summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2014-10-18 20:59:49 -0700
committerKaz Kylheku <kaz@kylheku.com>2014-10-18 20:59:49 -0700
commitf835bd19d1d65b1679f90aea56015704f11f8f4f (patch)
tree2b412d26b2c3fccfede6bc2d5323f88adb952ae3
parent88e7e54b5b415c7ab4e6fedd3e3e519d8bf3a68b (diff)
downloadtxr-f835bd19d1d65b1679f90aea56015704f11f8f4f.tar.gz
txr-f835bd19d1d65b1679f90aea56015704f11f8f4f.tar.bz2
txr-f835bd19d1d65b1679f90aea56015704f11f8f4f.zip
* parser.y: Allow TXR to support large programs, and efficiently so.
(clauses_rev): New grammar symbol. Uses a left-recursive rule that does not consume an amount of parser stack proportional to the number of clauses, and sticks to efficient consing, which means that the list is built up in reverse. (clauses): Now just a wrapper rule for clauses_rev which nreverses its output. (clauses_opt): Retargetted to use clauses_rev instead of clauses, and reverse its output.
-rw-r--r--ChangeLog12
-rw-r--r--parser.y12
2 files changed, 19 insertions, 5 deletions
diff --git a/ChangeLog b/ChangeLog
index 2f1e3b68..b26b89f0 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,17 @@
2014-10-18 Kaz Kylheku <kaz@kylheku.com>
+ * parser.y: Allow TXR to support large programs, and efficiently so.
+ (clauses_rev): New grammar symbol. Uses a left-recursive rule that
+ does not consume an amount of parser stack proportional to the number
+ of clauses, and sticks to efficient consing, which means that
+ the list is built up in reverse.
+ (clauses): Now just a wrapper rule for clauses_rev which nreverses
+ its output.
+ (clauses_opt): Retargetted to use clauses_rev instead of clauses,
+ and reverse its output.
+
+2014-10-18 Kaz Kylheku <kaz@kylheku.com>
+
Deal with situation when GC is disabled and the freshobj array runs out
of room. This could happen when parsing a really large TXR program,
since gc is disabled during parsing. Currently it asserts, which
diff --git a/parser.y b/parser.y
index 2379602f..6dd79c30 100644
--- a/parser.y
+++ b/parser.y
@@ -97,7 +97,7 @@ int yylex(union YYSTYPE *, yyscan_t scanner);
%token <chr> REGCHAR REGTOKEN LITCHAR SPLICE
-%type <val> spec clauses clauses_opt clause
+%type <val> spec clauses_rev clauses clauses_opt clause
%type <val> all_clause some_clause none_clause maybe_clause block_clause
%type <val> cases_clause choose_clause gather_clause collect_clause until_last
%type <val> collect_repeat
@@ -144,11 +144,13 @@ spec : clauses { parser->syntax_tree = $1; }
;
-clauses : clause { $$ = cons($1, nil); }
- | clause clauses { $$ = cons($1, $2); }
- ;
+clauses : clauses_rev { $$ = nreverse($1); }
+
+clauses_rev : clause { $$ = cons($1, nil); }
+ | clauses_rev clause { $$ = cons($2, $1); }
+ ;
-clauses_opt : clauses { $$ = $1; }
+clauses_opt : clauses_rev { $$ = nreverse($1); }
| /* empty */ { $$ = nil; }
;