summaryrefslogtreecommitdiffstats
path: root/parser.y
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2020-04-09 23:05:35 -0700
committerKaz Kylheku <kaz@kylheku.com>2020-04-09 23:13:48 -0700
commit1f92a0580ad9539f92ac788b92dd12bb7db171e1 (patch)
tree66030dad644acf83db0613b78ad44eed7fe3c963 /parser.y
parent62c2d365464a526e142de31c5895d3d9e53875ee (diff)
downloadtxr-1f92a0580ad9539f92ac788b92dd12bb7db171e1.tar.gz
txr-1f92a0580ad9539f92ac788b92dd12bb7db171e1.tar.bz2
txr-1f92a0580ad9539f92ac788b92dd12bb7db171e1.zip
parser: streamline core list building.
The r_expr grammar symbol is replaced with listacc which has a different type: a new Yacc node type that has three fields for building a list from left to right without nreverse, and the dotted pair item. * lib.h (struct list_accum): New struct type. Not a great place for it, but we don't have a parser-specific header that is included before y.tab.h: parser.h is included after y.tab.h. * parser.y (misplaced_consing_dot_check): The val argument is just the existing dotted item; if it is other than nao, the error is generated. (lacc, splacc): New static functions. (YYSTYPE): New union member, lacc of type struct list_accum. (r_exprs): Grammar symbol removed. (listacc): New grammar symbol of type listacc. The rules are those of r_exprs upgraded to construct the list in one pass.
Diffstat (limited to 'parser.y')
-rw-r--r--parser.y104
1 files changed, 57 insertions, 47 deletions
diff --git a/parser.y b/parser.y
index 1e800be0..8ac75469 100644
--- a/parser.y
+++ b/parser.y
@@ -67,11 +67,13 @@ static val rlcp_parser(parser_t *parser, val to, val from);
static wchar_t char_from_name(const wchar_t *name);
static val make_expr(parser_t *, val sym, val rest, val lineno);
static val check_parse_time_action(val spec_rev);
-static void misplaced_consing_dot_check(scanner_t *scanner, val term_atom_cons);
+static void misplaced_consing_dot_check(scanner_t *scanner, val dot);
static val uref_helper(parser_t *, val expr);
static val uoref_helper(parser_t *, val expr);
static val qref_helper(parser_t *, val lexpr, val rexpr);
static val fname_helper(parser_t *, val name);
+static struct list_accum lacc(val obj);
+static struct list_accum splacc(val list);
#if YYBISON
union YYSTYPE;
@@ -113,6 +115,7 @@ INLINE val expand_form_ver(val form, int ver)
union obj *val;
wchar_t chr;
cnum lineno;
+ struct list_accum lacc;
}
%token <lexeme> SPACE TEXT SYMTOK
@@ -144,7 +147,8 @@ INLINE val expand_form_ver(val form, int ver)
%type <val> line elems_opt elems clause_parts_h additional_parts_h
%type <val> text texts elem var var_op modifiers
%type <val> vector hash struct range tnode tree
-%type <val> exprs exprs_opt n_exprs r_exprs i_expr i_dot_expr
+%type <val> exprs exprs_opt n_exprs i_expr i_dot_expr
+%type <lacc> listacc
%type <val> n_expr n_exprs_opt n_dot_expr
%type <val> list dwim meta compound
%type <val> out_clauses out_clauses_opt out_clause
@@ -941,54 +945,43 @@ exprs_opt : exprs { $$ = $1; }
| /* empty */ { $$ = nil; }
;
-n_exprs : r_exprs { val term_atom = pop(&$1);
- val tail_cons = $1;
- $$ = us_nreverse($1);
- if (term_atom != unique_s)
- rplacd(tail_cons, term_atom); }
+n_exprs : listacc { if ($1.dot != nao)
+ rplacd($1.tail, $1.dot);
+ $$ = $1.head; }
;
-r_exprs : n_expr { val exprs = cons($1, nil);
- rlc(exprs, $1);
- $$ = rlc(cons(unique_s, exprs), exprs); }
+listacc : n_expr { $$ = lacc($1);
+ rlc($$.head, $1); }
| HASH_SEMI { parser->ignore = 1; }
n_expr { parser->ignore = 0;
- $$ = cons(unique_s, nil); }
- | r_exprs HASH_SEMI { parser->ignore = 1; }
+ $$ = lacc(nil); }
+ | listacc HASH_SEMI { parser->ignore = 1; }
n_expr { parser->ignore = 0;
$$ = $1; }
- | r_exprs n_expr { uses_or2;
- val term_atom_cons = $1;
- val exprs = cdr($1);
- misplaced_consing_dot_check(scnr, term_atom_cons);
- rplacd(term_atom_cons,
- rlc(cons($2, exprs), or2($2, exprs)));
- $$ = term_atom_cons; }
- | r_exprs CONSDOT n_expr
- { val term_atom_cons = $1;
- misplaced_consing_dot_check(scnr, term_atom_cons);
- rplaca(term_atom_cons, $3);
+ | listacc n_expr { uses_or2;
+ val cell = rlc(cons($2, nil), or2($2, $1.head));
+ misplaced_consing_dot_check(scnr, $1.dot);
+ rplacd($1.tail, cell);
+ $1.tail = cell;
+ $$ = $1; }
+ | listacc CONSDOT n_expr
+ { misplaced_consing_dot_check(scnr, $1.dot);
+ $1.dot = $3;
+ $$ = $1; }
+ | WSPLICE wordslit { $$ = splacc(rl($2, num($1))); }
+ | listacc WSPLICE
+ wordslit { val list = rl($3, num($2));
+ misplaced_consing_dot_check(scnr, $1.dot);
+ rplacd($1.tail, list);
+ $1.tail = lastcons(list);
+ $$ = $1; }
+ | QWSPLICE wordsqlit { $$ = splacc(rl($2, num($1))); }
+ | listacc QWSPLICE
+ wordsqlit { val list = rl($3, num($2));
+ misplaced_consing_dot_check(scnr, $1.dot);
+ rplacd($1.tail, list);
+ $1.tail = lastcons(list);
$$ = $1; }
- | WSPLICE wordslit { $$ = cons(unique_s, us_nreverse(rl($2, num($1))));
- rlc($$, cdr($$)); }
- | r_exprs WSPLICE
- wordslit { val term_atom_cons = $1;
- val exprs = cdr($1);
- misplaced_consing_dot_check(scnr, term_atom_cons);
- rplacd(term_atom_cons,
- nappend2(rl(us_nreverse($3), num($2)),
- exprs));
- $$ = term_atom_cons; }
- | QWSPLICE wordsqlit { $$ = cons(unique_s, rl($2, num($1)));
- rlc($$, cdr($$)); }
- | r_exprs QWSPLICE
- wordsqlit { val term_atom_cons = $1;
- val exprs = cdr($1);
- misplaced_consing_dot_check(scnr, term_atom_cons);
- rplacd(term_atom_cons,
- nappend2(rl(us_nreverse($3), num($2)),
- exprs));
- $$ = term_atom_cons; }
;
i_expr : SYMTOK { $$ = ifnign(symhlpr($1, t)); }
@@ -1781,12 +1774,10 @@ static val check_parse_time_action(val spec_rev)
return spec_rev;
}
-static void misplaced_consing_dot_check(scanner_t *scanner, val term_atom_cons)
+static void misplaced_consing_dot_check(scanner_t *scanner, val dot)
{
- if (car(term_atom_cons) != unique_s) {
+ if (dot != nao)
yyerrorf(scanner, lit("misplaced consing dot"), nao);
- rplaca(term_atom_cons, unique_s);
- }
}
static val uref_helper(parser_t *parser, val expr)
@@ -1840,6 +1831,25 @@ static val fname_helper(parser_t *parser, val name)
return nil;
}
+static struct list_accum lacc(val obj)
+{
+ struct list_accum la;
+ val cell = cons(obj, nil);
+ la.head = cell;
+ la.tail = cell;
+ la.dot = nao;
+ return la;
+}
+
+static struct list_accum splacc(val list)
+{
+ struct list_accum la;
+ la.head = list;
+ la.tail = lastcons(list);
+ la.dot = nao;
+ return la;
+}
+
#ifndef YYEOF
#define YYEOF 0
#endif