summaryrefslogtreecommitdiffstats
path: root/parser.y
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2014-01-27 22:52:08 -0800
committerKaz Kylheku <kaz@kylheku.com>2014-01-27 22:52:08 -0800
commit681c02622c94ea17ebe417333e3dd078ee49ba5c (patch)
treeeacb631e69cc7b821b7d544319c86cd306a19d18 /parser.y
parent05c9d8a60d75f58655b75f2fda3f2696a56637e6 (diff)
downloadtxr-681c02622c94ea17ebe417333e3dd078ee49ba5c.tar.gz
txr-681c02622c94ea17ebe417333e3dd078ee49ba5c.tar.bz2
txr-681c02622c94ea17ebe417333e3dd078ee49ba5c.zip
Lexing and parsing improvements, leaving things less hacky than before,
albeit hacky. * parser.l (BSYM, NSYM): Regex definitions gone. (BT0, BT1, BT2, NT0, NT1, NT2): New regex definitions. (BTREG, BTKEY, NTREG, NTKEY): Rewritten, so that they cannot match a lone @ character as a symbol name. (grammar): Rules for returning METAPAR, METABKT and METAQUO are gone. Instead, we just recognize a @ in the NESTED and BRACED states and return it as a token. * parser.y (METAPAR, METABKT, METAQUO): Token types removed. (meta_expr): Nonterminal symbol removed. ('@'): New token type. (list): Quotes and splices handling removed from this rule. The new token '@' is handled here, on the other hand, because there are places that reference the list rule that need to support @ expressions. (n_expr): Reference to meta_expr removed. Quote, unquote and splice added here. (yybadtoken): Removed references to METAPAR, METABKT and METAQUO.
Diffstat (limited to 'parser.y')
-rw-r--r--parser.y64
1 files changed, 23 insertions, 41 deletions
diff --git a/parser.y b/parser.y
index 0271d38e..8089522a 100644
--- a/parser.y
+++ b/parser.y
@@ -81,8 +81,7 @@ static val parsed_spec;
%token <val> NUMBER METANUM
-%token <chr> REGCHAR REGTOKEN LITCHAR
-%token <chr> METAPAR METABKT METAQUO SPLICE
+%token <chr> REGCHAR REGTOKEN LITCHAR SPLICE
%type <val> spec clauses clauses_opt clause
%type <val> all_clause some_clause none_clause maybe_clause block_clause
@@ -91,7 +90,7 @@ static val parsed_spec;
%type <val> clause_parts additional_parts gather_parts additional_gather_parts
%type <val> output_clause define_clause try_clause catch_clauses_opt
%type <val> line elems_opt elems clause_parts_h additional_parts_h
-%type <val> text texts elem var var_op modifiers meta_expr vector hash
+%type <val> text texts elem var var_op modifiers vector hash
%type <val> list exprs exprs_opt expr n_exprs n_expr
%type <val> out_clauses out_clauses_opt out_clause
%type <val> repeat_clause repeat_parts_opt o_line
@@ -100,7 +99,7 @@ static val parsed_spec;
%type <val> regterm regtoken regclass regclassterm regrange
%type <val> strlit chrlit quasilit quasi_items quasi_item litchars
%type <chr> regchar
-%type <lineno> '(' '['
+%type <lineno> '(' '[' '@'
%nonassoc LOW /* used for precedence assertion */
%right SYMTOK '{' '}'
@@ -108,7 +107,7 @@ static val parsed_spec;
%right OUTPUT REPEAT REP FIRST LAST EMPTY DEFINE
%right SPACE TEXT NUMBER
%nonassoc '[' ']' '(' ')'
-%left '-' ',' '\'' SPLICE METAQUO
+%left '-' ',' '\'' SPLICE '@'
%left '|' '/'
%left '&'
%right '~' '*' '?' '+' '%'
@@ -344,7 +343,7 @@ elem : texts { $$ = rlcp(cons(text_s, $1), $1);
$$ = rlcp(optimize_text($$), $$); }
| var { $$ = rl($1, num(lineno)); }
| list { val sym = first($1);
- if (sym == do_s || sym == require_s)
+ if (sym == do_s || sym == require_s)
$$ = rlcp(cons(sym,
expand_forms(rest($1))),
$1);
@@ -376,8 +375,9 @@ elem : texts { $$ = rlcp(cons(text_s, $1), $1);
clause_parts_h { $$ = list(choose_s, t, $4, $2, nao);
rl($$, num($1)); }
| CHOOSE exprs_opt ')' END { yyerror("empty cases clause"); }
- | DEFINE exprs ')' elems END { $$ = list(define_s, t, $4, $2, nao);
- rl($$, num($1)); }
+ | DEFINE exprs ')' elems END
+ { $$ = list(define_s, t, $4, $2, nao);
+ rl($$, num($1)); }
;
clause_parts_h : elems additional_parts_h { $$ = cons($1, $2); }
@@ -699,44 +699,20 @@ list : '(' n_exprs ')' { $$ = rl($2, num($1)); }
| '(' ')' { $$ = nil; }
| '[' n_exprs ']' { $$ = rl(cons(dwim_s, $2), num($1)); }
| '[' ']' { $$ = rl(cons(dwim_s, nil), num($1)); }
- | ',' n_expr { val expr = $2;
- if (consp(expr) && first(expr) == qquote_s)
- expr = cons(quote_s, rest(expr));
- $$ = rlcp(list(unquote_s, expr, nao), $2); }
- | '\'' n_expr { $$ = rlcp(list(choose_quote($2),
- $2, nao), $2); }
- | SPLICE n_expr { val expr = $2;
- if (consp(expr) && first(expr) == qquote_s)
- expr = cons(quote_s, rest(expr));
- $$ = rlcp(list(splice_s, expr, nao), $2); }
+ | '@' list { $$ = rlcp(cons(expr_s, $2), $2); }
| '(' error { $$ = nil;
yybadtoken(yychar, lit("list expression")); }
| '[' error { $$ = nil;
yybadtoken(yychar, lit("DWIM expression")); }
- ;
-
-meta_expr : METAPAR n_exprs ')' { $$ = rlcp(cons(expr_s, $2), $2); }
- | METABKT n_exprs ']' { $$ = rlcp(cons(expr_s,
- rlcp(cons(dwim_s, $2), $2)),
- $2); }
- | METAPAR ')' { $$ = rl(cons(expr_s, nil), num(lineno)); }
- | METABKT ']' { $$ = rl(cons(expr_s, rl(cons(dwim_s, nil),
- num(lineno))),
- num(lineno)); }
- | METAQUO n_expr { val expnq = list(choose_quote($2), $2, nao);
- val quote = rlcp(expnq, $2);
- $$ = rlcp(cons(expr_s, quote), quote); }
- | METAQUO error { $$ = nil;
- yybadtoken(yychar, lit("meta expression")); }
- | METAPAR error { $$ = nil;
+ | '@' error { $$ = nil;
yybadtoken(yychar, lit("meta expression")); }
- | METABKT error { $$ = nil;
- yybadtoken(yychar, lit("meta expression")); }
- ;
+ ;
exprs : n_exprs { $$ = rlcp(expand_meta($1), $1); }
+ ;
expr : n_expr { $$ = rlcp(expand_meta($1), $1); }
+ ;
exprs_opt : exprs { $$ = $1; }
| /* empty */ { $$ = nil; }
@@ -757,13 +733,22 @@ n_expr : SYMTOK { $$ = rl(sym_helper($1, t), num(lineno)); }
| list { $$ = $1; }
| vector { $$ = $1; }
| hash { $$ = $1; }
- | meta_expr { $$ = $1; }
| lisp_regex { $$ = cons(regex_compile(rest($1), nil),
rest($1));
rlcp($$, $1); }
| chrlit { $$ = rl($1, num(lineno)); }
| strlit { $$ = $1; }
| quasilit { $$ = $1; }
+ | ',' n_expr { val expr = $2;
+ if (consp(expr) && first(expr) == qquote_s)
+ expr = cons(quote_s, rest(expr));
+ $$ = rlcp(list(unquote_s, expr, nao), $2); }
+ | '\'' n_expr { $$ = rlcp(list(choose_quote($2),
+ $2, nao), $2); }
+ | SPLICE n_expr { val expr = $2;
+ if (consp(expr) && first(expr) == qquote_s)
+ expr = cons(quote_s, rest(expr));
+ $$ = rlcp(list(splice_s, expr, nao), $2); }
;
regex : '/' regexpr '/' { $$ = cons(regex_s, $2); end_of_regex();
@@ -1229,9 +1214,6 @@ void yybadtoken(int tok, val context)
case REGCHAR: problem = lit("regular expression character"); break;
case REGTOKEN: problem = lit("regular expression token"); break;
case LITCHAR: problem = lit("string literal character"); break;
- case METAPAR: problem = lit("@("); break;
- case METABKT: problem = lit("@["); break;
- case METAQUO: problem = lit("@'"); break;
case DOTDOT: problem = lit(".."); break;
case HASH_BACKSLASH: problem = lit("#\\"); break;
case HASH_SLASH: problem = lit("#/"); break;