summaryrefslogtreecommitdiffstats
path: root/parser.y
diff options
context:
space:
mode:
authorDavid Tolnay <dtolnay@gmail.com>2015-08-23 20:36:11 -0700
committerDavid Tolnay <dtolnay@gmail.com>2015-08-23 20:36:11 -0700
commit0c93eb3379241dc4775718a9d39f54a6c4de20d6 (patch)
tree67bb5510adb707d54c6f72b51b0718578a2caf5c /parser.y
parent891f28ef5e406a8d2156ad88d0244ab03fe490eb (diff)
Move source files to src/
Diffstat (limited to 'parser.y')
-rw-r--r--parser.y935
1 files changed, 0 insertions, 935 deletions
diff --git a/parser.y b/parser.y
deleted file mode 100644
index d57e5c8a..00000000
--- a/parser.y
+++ /dev/null
@@ -1,935 +0,0 @@
-%{
-#include <assert.h>
-#include <math.h>
-#include <stdio.h>
-#include <string.h>
-#include "compile.h"
-#include "jv_alloc.h"
-#define YYMALLOC jv_mem_alloc
-#define YYFREE jv_mem_free
-%}
-%code requires {
-#include "locfile.h"
-struct lexer_param;
-
-#define YYLTYPE location
-#define YYLLOC_DEFAULT(Loc, Rhs, N) \
- do { \
- if (N) { \
- (Loc).start = YYRHSLOC(Rhs, 1).start; \
- (Loc).end = YYRHSLOC(Rhs, N).end; \
- } else { \
- (Loc).start = YYRHSLOC(Rhs, 0).end; \
- (Loc).end = YYRHSLOC(Rhs, 0).end; \
- } \
- } while (0)
-}
-
-%locations
-%error-verbose
-%define api.pure
-%union {
- jv literal;
- block blk;
-}
-
-%destructor { jv_free($$); } <literal>
-%destructor { block_free($$); } <blk>
-
-%parse-param {block* answer}
-%parse-param {int* errors}
-%parse-param {struct locfile* locations}
-%parse-param {struct lexer_param* lexer_param_ptr}
-%lex-param {block* answer}
-%lex-param {int* errors}
-%lex-param {struct locfile* locations}
-%lex-param {struct lexer_param* lexer_param_ptr}
-
-
-%token INVALID_CHARACTER
-%token <literal> IDENT
-%token <literal> FIELD
-%token <literal> LITERAL
-%token <literal> FORMAT
-%token REC ".."
-%token SETMOD "%="
-%token EQ "=="
-%token NEQ "!="
-%token DEFINEDOR "//"
-%token AS "as"
-%token DEF "def"
-%token MODULE "module"
-%token IMPORT "import"
-%token INCLUDE "include"
-%token IF "if"
-%token THEN "then"
-%token ELSE "else"
-%token ELSE_IF "elif"
-%token REDUCE "reduce"
-%token FOREACH "foreach"
-%token END "end"
-%token AND "and"
-%token OR "or"
-%token TRY "try"
-%token CATCH "catch"
-%token LABEL "label"
-%token BREAK "break"
-%token LOC "__loc__"
-%token SETPIPE "|="
-%token SETPLUS "+="
-%token SETMINUS "-="
-%token SETMULT "*="
-%token SETDIV "/="
-%token SETDEFINEDOR "//="
-%token LESSEQ "<="
-%token GREATEREQ ">="
-
-%token QQSTRING_START
-%token <literal> QQSTRING_TEXT
-%token QQSTRING_INTERP_START
-%token QQSTRING_INTERP_END
-%token QQSTRING_END
-
-/* Instead of raising this, find a way to use precedence to resolve
- * shift-reduce conflicts. */
-%expect 0
-
-%precedence FUNCDEF
-%right '|'
-%left ','
-%right "//"
-%nonassoc '=' SETPIPE SETPLUS SETMINUS SETMULT SETDIV SETMOD SETDEFINEDOR
-%left OR
-%left AND
-%nonassoc NEQ EQ '<' '>' LESSEQ GREATEREQ
-%left '+' '-'
-%left '*' '/' '%'
-%precedence NONOPT /* non-optional; rules for which a specialized
- '?' rule should be preferred over Exp '?' */
-%precedence '?'
-%precedence "try"
-%precedence "catch"
-
-
-%type <blk> Exp Term
-%type <blk> MkDict MkDictPair ExpD
-%type <blk> ElseBody
-%type <blk> String QQString
-%type <blk> FuncDef FuncDefs
-%type <blk> Module Import Imports ImportWhat ImportFrom
-%type <blk> Param Params Arg Args
-%type <blk> Pattern ArrayPats ObjPats ObjPat
-%type <literal> Keyword
-%{
-#include "lexer.h"
-struct lexer_param {
- yyscan_t lexer;
-};
-#define FAIL(loc, msg) \
- do { \
- location l = loc; \
- yyerror(&l, answer, errors, locations, lexer_param_ptr, msg); \
- /*YYERROR*/; \
- } while (0)
-
-void yyerror(YYLTYPE* loc, block* answer, int* errors,
- struct locfile* locations, struct lexer_param* lexer_param_ptr, const char *s){
- (*errors)++;
- if (strstr(s, "unexpected")) {
-#ifdef WIN32
- locfile_locate(locations, *loc, "jq: error: %s (Windows cmd shell quoting issues?)", s);
-#else
- locfile_locate(locations, *loc, "jq: error: %s (Unix shell quoting issues?)", s);
-#endif
- } else {
- locfile_locate(locations, *loc, "jq: error: %s", s);
- }
-}
-
-int yylex(YYSTYPE* yylval, YYLTYPE* yylloc, block* answer, int* errors,
- struct locfile* locations, struct lexer_param* lexer_param_ptr) {
- yyscan_t lexer = lexer_param_ptr->lexer;
- int tok = jq_yylex(yylval, yylloc, lexer);
- if ((tok == LITERAL || tok == QQSTRING_TEXT) && !jv_is_valid(yylval->literal)) {
- jv msg = jv_invalid_get_msg(jv_copy(yylval->literal));
- if (jv_get_kind(msg) == JV_KIND_STRING) {
- FAIL(*yylloc, jv_string_value(msg));
- } else {
- FAIL(*yylloc, "Invalid literal");
- }
- jv_free(msg);
- jv_free(yylval->literal);
- yylval->literal = jv_null();
- }
- return tok;
-}
-
-static block gen_dictpair(block k, block v) {
- return BLOCK(gen_subexp(k), gen_subexp(v), gen_op_simple(INSERT));
-}
-
-static block gen_index(block obj, block key) {
- return BLOCK(gen_subexp(key), obj, gen_op_simple(INDEX));
-}
-
-static block gen_index_opt(block obj, block key) {
- return BLOCK(gen_subexp(key), obj, gen_op_simple(INDEX_OPT));
-}
-
-static block gen_slice_index(block obj, block start, block end, opcode idx_op) {
- block key = BLOCK(gen_subexp(gen_const(jv_object())),
- gen_subexp(gen_const(jv_string("start"))),
- gen_subexp(start),
- gen_op_simple(INSERT),
- gen_subexp(gen_const(jv_string("end"))),
- gen_subexp(end),
- gen_op_simple(INSERT));
- return BLOCK(key, obj, gen_op_simple(idx_op));
-}
-
-static block constant_fold(block a, block b, int op) {
- if (!block_is_single(a) || !block_is_const(a) ||
- !block_is_single(b) || !block_is_const(b))
- return gen_noop();
- if (op == '+') {
- if (block_const_kind(a) == JV_KIND_NULL) {
- block_free(a);
- return b;
- }
- if (block_const_kind(b) == JV_KIND_NULL) {
- block_free(b);
- return a;
- }
- }
- if (block_const_kind(a) != block_const_kind(b))
- return gen_noop();
-
- jv res = jv_invalid();
-
- if (block_const_kind(a) == JV_KIND_NUMBER) {
- double na = jv_number_value(block_const(a));
- double nb = jv_number_value(block_const(b));
- switch (op) {
- case '+': res = jv_number(na + nb); break;
- case '-': res = jv_number(na - nb); break;
- case '*': res = jv_number(na * nb); break;
- case '/': res = jv_number(na / nb); break;
- case EQ: res = (na == nb ? jv_true() : jv_false()); break;
- case NEQ: res = (na != nb ? jv_true() : jv_false()); break;
- case '<': res = (na < nb ? jv_true() : jv_false()); break;
- case '>': res = (na > nb ? jv_true() : jv_false()); break;
- case LESSEQ: res = (na <= nb ? jv_true() : jv_false()); break;
- case GREATEREQ: res = (na >= nb ? jv_true() : jv_false()); break;
- default: break;
- }
- } else if (op == '+' && block_const_kind(a) == JV_KIND_STRING) {
- res = jv_string_concat(block_const(a), block_const(b));
- } else {
- return gen_noop();
- }
-
- if (jv_get_kind(res) == JV_KIND_INVALID)
- return gen_noop();
-
- block_free(a);
- block_free(b);
- return gen_const(res);
-}
-
-static block gen_binop(block a, block b, int op) {
- block folded = constant_fold(a, b, op);
- if (!block_is_noop(folded))
- return folded;
-
- const char* funcname = 0;
- switch (op) {
- case '+': funcname = "_plus"; break;
- case '-': funcname = "_minus"; break;
- case '*': funcname = "_multiply"; break;
- case '/': funcname = "_divide"; break;
- case '%': funcname = "_mod"; break;
- case EQ: funcname = "_equal"; break;
- case NEQ: funcname = "_notequal"; break;
- case '<': funcname = "_less"; break;
- case '>': funcname = "_greater"; break;
- case LESSEQ: funcname = "_lesseq"; break;
- case GREATEREQ: funcname = "_greatereq"; break;
- }
- assert(funcname);
-
- return gen_call(funcname, BLOCK(gen_lambda(a), gen_lambda(b)));
-}
-
-static block gen_format(block a, jv fmt) {
- return BLOCK(a, gen_call("format", gen_lambda(gen_const(fmt))));
-}
-
-static block gen_definedor_assign(block object, block val) {
- block tmp = gen_op_var_fresh(STOREV, "tmp");
- return BLOCK(gen_op_simple(DUP),
- val, tmp,
- gen_call("_modify", BLOCK(gen_lambda(object),
- gen_lambda(gen_definedor(gen_noop(),
- gen_op_bound(LOADV, tmp))))));
-}
-
-static block gen_update(block object, block val, int optype) {
- block tmp = gen_op_var_fresh(STOREV, "tmp");
- return BLOCK(gen_op_simple(DUP),
- val,
- tmp,
- gen_call("_modify", BLOCK(gen_lambda(object),
- gen_lambda(gen_binop(gen_noop(),
- gen_op_bound(LOADV, tmp),
- optype)))));
-}
-
-%}
-
-%%
-TopLevel:
-Module Imports Exp {
- *answer = BLOCK($1, $2, gen_op_simple(TOP), $3);
-} |
-Module Imports FuncDefs {
- *answer = BLOCK($1, $2, $3);
-}
-
-Module:
-%empty {
- $$ = gen_noop();
-} |
-"module" Exp ';' {
- if (!block_is_const($2)) {
- FAIL(@$, "Module metadata must be constant");
- $$ = gen_noop();
- block_free($2);
- } else {
- $$ = gen_module($2);
- }
-}
-
-Imports:
-%empty {
- $$ = gen_noop();
-} |
-Import Imports {
- $$ = BLOCK($1, $2);
-}
-
-FuncDefs:
-%empty {
- $$ = gen_noop();
-} |
-FuncDef FuncDefs {
- $$ = block_bind($1, $2, OP_IS_CALL_PSEUDO);
-}
-
-Exp:
-FuncDef Exp %prec FUNCDEF {
- $$ = block_bind_referenced($1, $2, OP_IS_CALL_PSEUDO);
-} |
-
-Term "as" Pattern '|' Exp {
- $$ = gen_destructure($1, $3, $5);
-} |
-
-"reduce" Term "as" Pattern '(' Exp ';' Exp ')' {
- $$ = gen_reduce($2, $4, $6, $8);
-} |
-
-"foreach" Term "as" Pattern '(' Exp ';' Exp ';' Exp ')' {
- $$ = gen_foreach($2, $4, $6, $8, $10);
-} |
-
-"foreach" Term "as" Pattern '(' Exp ';' Exp ')' {
- $$ = gen_foreach($2, $4, $6, $8, gen_noop());
-} |
-
-"if" Exp "then" Exp ElseBody {
- $$ = gen_cond($2, $4, $5);
-} |
-"if" Exp "then" error {
- FAIL(@$, "Possibly unterminated 'if' statement");
- $$ = $2;
-} |
-
-"try" Exp "catch" Exp {
- //$$ = BLOCK(gen_op_target(FORK_OPT, $2), $2, $4);
- $$ = gen_try($2, gen_try_handler($4));
-} |
-"try" Exp {
- //$$ = BLOCK(gen_op_target(FORK_OPT, $2), $2, gen_op_simple(BACKTRACK));
- $$ = gen_try($2, gen_op_simple(BACKTRACK));
-} |
-"try" Exp "catch" error {
- FAIL(@$, "Possibly unterminated 'try' statement");
- $$ = $2;
-} |
-
-"label" '$' IDENT '|' Exp {
- jv v = jv_string_fmt("*label-%s", jv_string_value($3));
- $$ = gen_location(@$, locations, gen_label(jv_string_value(v), $5));
- jv_free($3);
- jv_free(v);
-} |
-
-Exp '?' {
- $$ = gen_try($1, gen_op_simple(BACKTRACK));
-} |
-
-Exp '=' Exp {
- $$ = gen_call("_assign", BLOCK(gen_lambda($1), gen_lambda($3)));
-} |
-
-Exp "or" Exp {
- $$ = gen_or($1, $3);
-} |
-
-Exp "and" Exp {
- $$ = gen_and($1, $3);
-} |
-
-Exp "//" Exp {
- $$ = gen_definedor($1, $3);
-} |
-
-Exp "//=" Exp {
- $$ = gen_definedor_assign($1, $3);
-} |
-
-Exp "|=" Exp {
- $$ = gen_call("_modify", BLOCK(gen_lambda($1), gen_lambda($3)));
-} |
-
-Exp '|' Exp {
- $$ = block_join($1, $3);
-} |
-
-Exp ',' Exp {
- $$ = gen_both($1, $3);
-} |
-
-Exp '+' Exp {
- $$ = gen_binop($1, $3, '+');
-} |
-
-Exp "+=" Exp {
- $$ = gen_update($1, $3, '+');
-} |
-
-'-' Exp {
- $$ = BLOCK($2, gen_call("_negate", gen_noop()));
-} |
-
-Exp '-' Exp {
- $$ = gen_binop($1, $3, '-');
-} |
-
-Exp "-=" Exp {
- $$ = gen_update($1, $3, '-');
-} |
-
-Exp '*' Exp {
- $$ = gen_binop($1, $3, '*');
-} |
-
-Exp "*=" Exp {
- $$ = gen_update($1, $3, '*');
-} |
-
-Exp '/' Exp {
- $$ = gen_binop($1, $3, '/');
- if (block_is_const_inf($$))
- FAIL(@$, "Division by zero?");
-} |
-
-Exp '%' Exp {
- $$ = gen_binop($1, $3, '%');
- if (block_is_const_inf($$))
- FAIL(@$, "Remainder by zero?");
-} |
-
-Exp "/=" Exp {
- $$ = gen_update($1, $3, '/');
-} |
-
-Exp SETMOD Exp {
- $$ = gen_update($1, $3, '%');
-} |
-
-Exp "==" Exp {
- $$ = gen_binop($1, $3, EQ);
-} |
-
-Exp "!=" Exp {
- $$ = gen_binop($1, $3, NEQ);
-} |
-
-Exp '<' Exp {
- $$ = gen_binop($1, $3, '<');
-} |
-
-Exp '>' Exp {
- $$ = gen_binop($1, $3, '>');
-} |
-
-Exp "<=" Exp {
- $$ = gen_binop($1, $3, LESSEQ);
-} |
-
-Exp ">=" Exp {
- $$ = gen_binop($1, $3, GREATEREQ);
-} |
-
-Term {
- $$ = $1;
-}
-
-Import:
-ImportWhat ';' {
- $$ = $1;
-} |
-ImportWhat Exp ';' {
- if (!block_is_const($2)) {
- FAIL(@$, "Module metadata must be constant");
- $$ = gen_noop();
- block_free($1);
- block_free($2);
- } else if (block_const_kind($2) != JV_KIND_OBJECT) {
- FAIL(@$, "Module metadata must be an object");
- $$ = gen_noop();
- block_free($1);
- block_free($2);
- } else {
- $$ = gen_import_meta($1, $2);
- }
-}
-
-ImportWhat:
-"import" ImportFrom "as" '$' IDENT {
- jv v = block_const($2);
- // XXX Make gen_import take only blocks and the int is_data so we
- // don't have to free so much stuff here
- $$ = gen_import(jv_string_value(v), jv_string_value($5), 1);
- block_free($2);
- jv_free($5);
- jv_free(v);
-} |
-"import" ImportFrom "as" IDENT {
- jv v = block_const($2);
- $$ = gen_import(jv_string_value(v), jv_string_value($4), 0);
- block_free($2);
- jv_free($4);
- jv_free(v);
-} |
-"include" ImportFrom {
- jv v = block_const($2);
- $$ = gen_import(jv_string_value(v), NULL, 0);
- block_free($2);
- jv_free(v);
-}
-
-ImportFrom:
-String {
- if (!block_is_const($1)) {
- FAIL(@$, "Import path must be constant");
- $$ = gen_const(jv_string(""));
- block_free($1);
- } else {
- $$ = $1;
- }
-}
-
-FuncDef:
-"def" IDENT ':' Exp ';' {
- $$ = gen_function(jv_string_value($2), gen_noop(), $4);
- jv_free($2);
-} |
-
-"def" IDENT '(' Params ')' ':' Exp ';' {
- $$ = gen_function(jv_string_value($2), $4, $7);
- jv_free($2);
-}
-
-Params:
-Param {
- $$ = $1;
-} |
-Params ';' Param {
- $$ = BLOCK($1, $3);
-}
-
-Param:
-'$' IDENT {
- $$ = gen_param_regular(jv_string_value($2));
- jv_free($2);
-} |
-
-IDENT {
- $$ = gen_param(jv_string_value($1));
- jv_free($1);
-}
-
-
-String:
-QQSTRING_START { $<literal>$ = jv_string("text"); } QQString QQSTRING_END {
- $$ = $3;
- jv_free($<literal>2);
-} |
-FORMAT QQSTRING_START { $<literal>$ = $1; } QQString QQSTRING_END {
- $$ = $4;
- jv_free($<literal>3);
-}
-
-
-QQString:
-%empty {
- $$ = gen_const(jv_string(""));
-} |
-QQString QQSTRING_TEXT {
- $$ = gen_binop($1, gen_const($2), '+');
-} |
-QQString QQSTRING_INTERP_START Exp QQSTRING_INTERP_END {
- $$ = gen_binop($1, gen_format($3, jv_copy($<literal>0)), '+');
-}
-
-
-ElseBody:
-"elif" Exp "then" Exp ElseBody {
- $$ = gen_cond($2, $4, $5);
-} |
-"else" Exp "end" {
- $$ = $2;
-}
-
-ExpD:
-ExpD '|' ExpD {
- $$ = block_join($1, $3);
-} |
-'-' ExpD {
- $$ = BLOCK($2, gen_call("_negate", gen_noop()));
-} |
-Term {
- $$ = $1;
-}
-
-
-Term:
-'.' {
- $$ = gen_noop();
-} |
-REC {
- $$ = gen_call("recurse", gen_noop());
-} |
-BREAK '$' IDENT {
- jv v = jv_string_fmt("*label-%s", jv_string_value($3)); // impossible symbol
- $$ = gen_location(@$, locations,
- BLOCK(gen_op_unbound(LOADV, jv_string_value(v)),
- gen_call("error", gen_noop())));
- jv_free(v);
- jv_free($3);
-} |
-BREAK error {
- FAIL(@$, "break requires a label to break to");
- $$ = gen_noop();
-} |
-Term FIELD '?' {
- $$ = gen_index_opt($1, gen_const($2));
-} |
-FIELD '?' {
- $$ = gen_index_opt(gen_noop(), gen_const($1));
-} |
-Term '.' String '?' {
- $$ = gen_index_opt($1, $3);
-} |
-'.' String '?' {
- $$ = gen_index_opt(gen_noop(), $2);
-} |
-Term FIELD %prec NONOPT {
- $$ = gen_index($1, gen_const($2));
-} |
-FIELD %prec NONOPT {
- $$ = gen_index(gen_noop(), gen_const($1));
-} |
-Term '.' String %prec NONOPT {
- $$ = gen_index($1, $3);
-} |
-'.' String %prec NONOPT {
- $$ = gen_index(gen_noop(), $2);
-} |
-'.' error {
- FAIL(@$, "try .[\"field\"] instead of .field for unusually named fields");
- $$ = gen_noop();
-} |
-'.' IDENT error {
- jv_free($2);
- FAIL(@$, "try .[\"field\"] instead of .field for unusually named fields");
- $$ = gen_noop();
-} |
-/* FIXME: string literals */
-Term '[' Exp ']' '?' {
- $$ = gen_index_opt($1, $3);
-} |
-Term '[' Exp ']' %prec NONOPT {
- $$ = gen_index($1, $3);
-} |
-Term '[' ']' '?' {
- $$ = block_join($1, gen_op_simple(EACH_OPT));
-} |
-Term '[' ']' %prec NONOPT {
- $$ = block_join($1, gen_op_simple(EACH));
-} |
-Term '[' Exp ':' Exp ']' '?' {
- $$ = gen_slice_index($1, $3, $5, INDEX_OPT);
-} |
-Term '[' Exp ':' ']' '?' {
- $$ = gen_slice_index($1, $3, gen_const(jv_null()), INDEX_OPT);
-} |
-Term '[' ':' Exp ']' '?' {
- $$ = gen_slice_index($1, gen_const(jv_null()), $4, INDEX_OPT);
-} |
-Term '[' Exp ':' Exp ']' %prec NONOPT {
- $$ = gen_slice_index($1, $3, $5, INDEX);
-} |
-Term '[' Exp ':' ']' %prec NONOPT {
- $$ = gen_slice_index($1, $3, gen_const(jv_null()), INDEX);
-} |
-Term '[' ':' Exp ']' %prec NONOPT {
- $$ = gen_slice_index($1, gen_const(jv_null()), $4, INDEX);
-} |
-LITERAL {
- $$ = gen_const($1);
-} |
-String {
- $$ = $1;
-} |
-FORMAT {
- $$ = gen_format(gen_noop(), $1);
-} |
-'(' Exp ')' {
- $$ = $2;
-} |
-'[' Exp ']' {
- $$ = gen_collect($2);
-} |
-'[' ']' {
- $$ = gen_const(jv_array());
-} |
-'{' MkDict '}' {
- block o = gen_const_object($2);
- if (o.first != NULL)
- $$ = o;
- else
- $$ = BLOCK(gen_subexp(gen_const(jv_object())), $2, gen_op_simple(POP));
-} |
-'$' LOC {
- $$ = gen_const(JV_OBJECT(jv_string("file"), jv_copy(locations->fname),
- jv_string("line"), jv_number(locfile_get_line(locations, @$.start) + 1)));
-} |
-'$' IDENT {
- $$ = gen_location(@$, locations, gen_op_unbound(LOADV, jv_string_value($2)));
- jv_free($2);
-} |
-IDENT {
- const char *s = jv_string_value($1);
- if (strcmp(s, "false") == 0)
- $$ = gen_const(jv_false());
- else if (strcmp(s, "true") == 0)
- $$ = gen_const(jv_true());
- else if (strcmp(s, "null") == 0)
- $$ = gen_const(jv_null());
- else
- $$ = gen_location(@$, locations, gen_call(s, gen_noop()));
- jv_free($1);
-} |
-IDENT '(' Args ')' {
- $$ = gen_call(jv_string_value($1), $3);
- $$ = gen_location(@1, locations, $$);
- jv_free($1);
-} |
-'(' error ')' { $$ = gen_noop(); } |
-'[' error ']' { $$ = gen_noop(); } |
-Term '[' error ']' { $$ = $1; } |
-'{' error '}' { $$ = gen_noop(); }
-
-Args:
-Arg {
- $$ = $1;
-} |
-Args ';' Arg {
- $$ = BLOCK($1, $3);
-}
-
-Arg:
-Exp {
- $$ = gen_lambda($1);
-}
-
-Pattern:
-'$' IDENT {
- $$ = gen_op_unbound(STOREV, jv_string_value($2));
- jv_free($2);
-} |
-'[' ArrayPats ']' {
- $$ = BLOCK($2, gen_op_simple(POP));
-} |
-'{' ObjPats '}' {
- $$ = BLOCK($2, gen_op_simple(POP));
-}
-
-ArrayPats:
-Pattern {
- $$ = gen_array_matcher(gen_noop(), $1);
-} |
-ArrayPats ',' Pattern {
- $$ = gen_array_matcher($1, $3);
-}
-
-ObjPats:
-ObjPat {
- $$ = $1;
-} |
-ObjPats ',' ObjPat {
- $$ = BLOCK($1, $3);
-}
-
-ObjPat:
-'$' IDENT {
- $$ = gen_object_matcher(gen_const($2), gen_op_unbound(STOREV, jv_string_value($2)));
-} |
-IDENT ':' Pattern {
- $$ = gen_object_matcher(gen_const($1), $3);
-} |
-Keyword ':' Pattern {
- $$ = gen_object_matcher(gen_const($1), $3);
-} |
-String ':' Pattern {
- $$ = gen_object_matcher($1, $3);
-} |
-'(' Exp ')' ':' Pattern {
- $$ = gen_object_matcher($2, $5);
-}
-
-Keyword:
-"as" {
- $$ = jv_string("as");
-} |
-"def" {
- $$ = jv_string("def");
-} |
-"module" {
- $$ = jv_string("module");
-} |
-"import" {
- $$ = jv_string("import");
-} |
-"include" {
- $$ = jv_string("include");
-} |
-"if" {
- $$ = jv_string("if");
-} |
-"then" {
- $$ = jv_string("then");
-} |
-"else" {
- $$ = jv_string("else");
-} |
-"elif" {
- $$ = jv_string("elif");
-} |
-"reduce" {
- $$ = jv_string("reduce");
-} |
-"foreach" {
- $$ = jv_string("foreach");
-} |
-"end" {
- $$ = jv_string("end");
-} |
-"and" {
- $$ = jv_string("and");
-} |
-"or" {
- $$ = jv_string("or");
-} |
-"try" {
- $$ = jv_string("try");
-} |
-"catch" {
- $$ = jv_string("catch");
-} |
-"label" {
- $$ = jv_string("label");
-} |
-"break" {
- $$ = jv_string("break");
-} |
-"__loc__" {
- $$ = jv_string("__loc__");
-}
-
-MkDict:
-%empty {
- $$=gen_noop();
-} |
- MkDictPair { $$ = $1; }
-| MkDictPair ',' MkDict { $$=block_join($1, $3); }
-| error ',' MkDict { $$ = $3; }
-
-MkDictPair:
-IDENT ':' ExpD {
- $$ = gen_dictpair(gen_const($1), $3);
- }
-| Keyword ':' ExpD {
- $$ = gen_dictpair(gen_const($1), $3);
- }
-| String ':' ExpD {
- $$ = gen_dictpair($1, $3);
- }
-| String {
- $$ = gen_dictpair($1, BLOCK(gen_op_simple(POP), gen_op_simple(DUP2),
- gen_op_simple(DUP2), gen_op_simple(INDEX)));
- }
-| '$' IDENT {
- $$ = gen_dictpair(gen_const($2),
- gen_location(@$, locations, gen_op_unbound(LOADV, jv_string_value($2))));
- }
-| IDENT {
- $$ = gen_dictpair(gen_const(jv_copy($1)),
- gen_index(gen_noop(), gen_const($1)));
- }
-| '(' Exp ')' ':' ExpD {
- $$ = gen_dictpair($2, $5);
- }
-| '(' error ')' ':' ExpD { $$ = $5; }
-%%
-
-int jq_parse(struct locfile* locations, block* answer) {
- struct lexer_param scanner;
- YY_BUFFER_STATE buf;
- jq_yylex_init_extra(0, &scanner.lexer);
- buf = jq_yy_scan_bytes(locations->data, locations->length, scanner.lexer);
- int errors = 0;
- *answer = gen_noop();
- yyparse(answer, &errors, locations, &scanner);
- jq_yy_delete_buffer(buf, scanner.lexer);
- jq_yylex_destroy(scanner.lexer);
- if (errors > 0) {
- block_free(*answer);
- *answer = gen_noop();
- }
- return errors;
-}
-
-int jq_parse_library(struct locfile* locations, block* answer) {
- int errs = jq_parse(locations, answer);
- if (errs) return errs;
- if (block_has_main(*answer)) {
- locfile_locate(locations, UNKNOWN_LOCATION, "jq: error: library should only have function definitions, not a main expression");
- return 1;
- }
- assert(block_has_only_binders_and_imports(*answer, OP_IS_CALL_PSEUDO));
- return 0;
-}