From f1507e43b0c05178deca7af610d18de5dbc269d7 Mon Sep 17 00:00:00 2001 From: Kaz Kylheku Date: Sat, 12 Nov 2011 11:24:08 -0800 Subject: Infrastructure for storing line number information outside of the code, in hash tables. * filter.c (make_trie, trie_add): Update to three-argument make_hash. * hash.c (struct hash): New members, hash_fun, assoc_fun acons_new_l_fun. (ll_hash): Renamed to equal_hash. (eql_hash): New static function. (cobj_hash_op): Follows ll_hash rename. (hash_grow): Use new function indirection to call hashing function. (make_hash): New argument to specify type of hashing. Initialize new members of struct hash. (gethash_l, gethash, remhash): Use function indirection for hashing and chain search and update. (pushhash): New function. * hash.h (make_hash): Declaration updated with new parameter. (pushhash): Declared. * lib.c (eql_f): New global variable. (eql, assq, aconsq_new, aconsq_new_l): New functions. (make_package): Updated to new three-argument make_hash. (obj_init): gc-protect and initialize new variable eql_f. * lib.h (eql, assq, aconsq_new, aconsq_new_l): Declared. * match.c (dir_tables_init): Updated to there-argument make_hash. * parser.h (form_to_ln_hash, ln_to_forms_hash): Global variables declared. * parser.l (form_to_ln_hash, ln_to_forms_hash): New global variables. (grammar): Set yylval.lineno for tokens that are classified to that type in parser.y. (parse_init): Initialize and gc-protect new global variables. * parser.y (rl): New static helper function. (%union): New member, lineno. (ALL, SOME, NONE, MAYBE, CASES, CHOOSE, GATHER, AND, OR, END, COLLECT, UNTIL, COLL, OUTPUT, REPEAT, REP, SINGLE, FIRST, LAST, EMPTY, DEFINE, TRY, CATCH, FINALLY, ERRTOK, '('): Reclassified as lineno type. In the grammar, these keywords can thus provide a stable line number from the lexer. (grammar): Numerous rules updated to add constructs to the line number hash tables via the rl helper. * dep.mk: Updated. * Makefile (depend): Use the installed, stable txr in the system path to update dependencies rather than locally built ./txr, to prevent the problem that txr is broken because out out-of-date dependencies, and thus cannot regenerate dependencies. --- parser.y | 147 +++++++++++++++++++++++++++++++++++++++++---------------------- 1 file changed, 96 insertions(+), 51 deletions(-) (limited to 'parser.y') diff --git a/parser.y b/parser.y index e15b9f5d..fd4fae34 100644 --- a/parser.y +++ b/parser.y @@ -37,6 +37,7 @@ #include "regex.h" #include "utf8.h" #include "match.h" +#include "hash.h" #include "parser.h" int yylex(void); @@ -49,21 +50,29 @@ val lit_char_helper(val litchars); static val parsed_spec; +static val rl(val form, val lineno) +{ + sethash(form_to_ln_hash, form, lineno); + pushhash(ln_to_forms_hash, lineno, form); + return form; +} + + %} %union { wchar_t *lexeme; union obj *val; wchar_t chr; - cnum num; + cnum num, lineno; } %token SPACE TEXT IDENT KEYWORD METAVAR -%token ALL SOME NONE MAYBE CASES CHOOSE GATHER -%token AND OR END COLLECT -%token UNTIL COLL OUTPUT REPEAT REP SINGLE FIRST LAST EMPTY DEFINE -%token TRY CATCH FINALLY -%token ERRTOK /* deliberately not used in grammar */ +%token ALL SOME NONE MAYBE CASES CHOOSE GATHER +%token AND OR END COLLECT +%token UNTIL COLL OUTPUT REPEAT REP SINGLE FIRST LAST EMPTY DEFINE +%token TRY CATCH FINALLY +%token ERRTOK /* deliberately not used in grammar */ %token NUMBER @@ -84,6 +93,7 @@ static val parsed_spec; %type regterm regclass regclassterm regrange %type strlit chrlit quasilit quasi_items quasi_item litchars %type regchar +%type '(' %nonassoc LOW /* used for precedence assertion */ %nonassoc ALL SOME NONE MAYBE CASES CHOOSE AND OR END COLLECT UNTIL COLL @@ -133,7 +143,8 @@ clause : all_clause { $$ = list(num(lineno - 1), $1, nao); } yyerror("repeat outside of output"); } ; -all_clause : ALL newl clause_parts { $$ = list(all_s, $3, nao); } +all_clause : ALL newl clause_parts { $$ = list(all_s, $3, nao); + rl($$, num($1)); } | ALL newl error { $$ = nil; yybadtoken(yychar, lit("all clause")); } @@ -142,7 +153,8 @@ all_clause : ALL newl clause_parts { $$ = list(all_s, $3, nao); } ; -some_clause : SOME newl clause_parts { $$ = list(some_s, $3, nao); } +some_clause : SOME newl clause_parts { $$ = list(some_s, $3, nao); + rl($$, num($1)); } | SOME newl error { $$ = nil; yybadtoken(yychar, lit("some clause")); } @@ -150,7 +162,8 @@ some_clause : SOME newl clause_parts { $$ = list(some_s, $3, nao); } yyerror("empty some clause"); } ; -none_clause : NONE newl clause_parts { $$ = list(none_s, $3, nao); } +none_clause : NONE newl clause_parts { $$ = list(none_s, $3, nao); + rl($$, num($1)); } | NONE newl error { $$ = nil; yybadtoken(yychar, lit("none clause")); } @@ -158,7 +171,8 @@ none_clause : NONE newl clause_parts { $$ = list(none_s, $3, nao); } yyerror("empty none clause"); } ; -maybe_clause : MAYBE newl clause_parts { $$ = list(maybe_s, $3, nao); } +maybe_clause : MAYBE newl clause_parts { $$ = list(maybe_s, $3, nao); + rl($$, num($1)); } | MAYBE newl error { $$ = nil; yybadtoken(yychar, lit("maybe clause")); } @@ -166,7 +180,8 @@ maybe_clause : MAYBE newl clause_parts { $$ = list(maybe_s, $3, nao); } yyerror("empty maybe clause"); } ; -cases_clause : CASES newl clause_parts { $$ = list(cases_s, $3, nao); } +cases_clause : CASES newl clause_parts { $$ = list(cases_s, $3, nao); + rl($$, num($1)); } | CASES newl error { $$ = nil; yybadtoken(yychar, lit("cases clause")); } @@ -175,7 +190,8 @@ cases_clause : CASES newl clause_parts { $$ = list(cases_s, $3, nao); } ; choose_clause : CHOOSE exprs_opt ')' - newl clause_parts { $$ = list(choose_s, $5, $2, nao); } + newl clause_parts { $$ = list(choose_s, $5, $2, nao); + rl($$, num($1)); } | CHOOSE exprs_opt ')' newl error { $$ = nil; yybadtoken(yychar, @@ -189,7 +205,8 @@ gather_clause : GATHER exprs_opt ')' newl clause_parts { $$ = list(gather_s, append2(mapcar(curry_12_1(func_n2(cons), nil), first($5)), rest($5)), - $2, nao); } + $2, nao); + rl($$, num($1)); } | GATHER exprs_opt ')' newl error { $$ = nil; yybadtoken(yychar, @@ -203,11 +220,13 @@ gather_clause : GATHER exprs_opt ')' collect_clause : COLLECT exprs_opt ')' newl clauses END newl { $$ = list(collect_s, $5, nil, $2, - nao); } + nao); + rl($$, num($1)); } | COLLECT exprs_opt ')' newl clauses until_last newl clauses END newl { $$ = list(collect_s, $5, - cons($6, $8), $2, nao); } + cons($6, $8), $2, nao); + rl($$, num($1)); } | COLLECT exprs_opt ')' newl error { $$ = nil; if (yychar == UNTIL || @@ -228,7 +247,7 @@ clause_parts : clauses additional_parts { $$ = cons($1, $2); } additional_parts : END newl { $$ = nil; } | AND newl clauses additional_parts { $$ = cons($3, $4); } - | OR newl clauses additional_parts { $$ = cons($3, $4); } + | OR newl clauses additional_parts { $$ = cons($3, $4); } ; line : elems_opt '\n' { $$ = $1; } @@ -244,38 +263,44 @@ elems : elem { $$ = cons($1, nil); } yyerror("rep outside of output"); } ; -elem : TEXT { $$ = string_own($1); } +elem : TEXT { $$ = rl(string_own($1), num(lineno)); } | SPACE { if ($1[0] == ' ' && $1[1] == 0) { val spaces = list(oneplus_s, chr(' '), nao); $$ = cons(regex_compile(spaces), spaces); + rl($$, num(lineno)); free($1); } else - { $$ = string_own($1); }} - | var { $$ = $1; } + { $$ = rl(string_own($1), num(lineno)); }} + | var { $$ = rl($1, num(lineno)); } | list { $$ = $1; } | regex { $$ = cons(regex_compile(rest($1)), - rest($1)); } - | COLL exprs_opt ')' elems END { $$ = list(coll_s, $4, nil, $2, nao); } + rest($1)); + rl($1, num(lineno)); } + | COLL exprs_opt ')' elems END { $$ = list(coll_s, $4, nil, $2, nao); + rl($$, num($1)); } | COLL exprs_opt ')' elems until_last elems END { $$ = list(coll_s, $4, cons($5, $6), - $2, nao); } + $2, nao); + rl($$, num($1)); } | COLL error { $$ = nil; yybadtoken(yychar, lit("coll clause")); } - | ALL clause_parts_h { $$ = list(all_s, t, $2, nao); } + | ALL clause_parts_h { $$ = rl(list(all_s, t, $2, nao), num($1)); } | ALL END { yyerror("empty all clause"); } - | SOME clause_parts_h { $$ = list(some_s, t, $2, nao); } + | SOME clause_parts_h { $$ = rl(list(some_s, t, $2, nao), num($1)); } | SOME END { yyerror("empty some clause"); } - | NONE clause_parts_h { $$ = list(none_s, t, $2, nao); } + | NONE clause_parts_h { $$ = rl(list(none_s, t, $2, nao), num($1)); } | NONE END { yyerror("empty none clause"); } - | MAYBE clause_parts_h { $$ = list(maybe_s, t, $2, nao); } + | MAYBE clause_parts_h { $$ = rl(list(maybe_s, t, $2, nao), num($1)); } | MAYBE END { yyerror("empty maybe clause"); } - | CASES clause_parts_h { $$ = list(cases_s, t, $2, nao); } + | CASES clause_parts_h { $$ = rl(list(cases_s, t, $2, nao), num($1)); } | CASES END { yyerror("empty cases clause"); } | CHOOSE exprs_opt ')' - clause_parts_h { $$ = list(choose_s, t, $4, $2, nao); } + 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); } + | DEFINE exprs ')' elems END { $$ = list(define_s, t, $4, $2, nao); + rl($$, num($1)); } ; clause_parts_h : elems additional_parts_h { $$ = cons($1, $2); } @@ -288,10 +313,12 @@ additional_parts_h : END { $$ = nil; } define_clause : DEFINE exprs ')' newl clauses_opt - END newl { $$ = list(define_s, $2, $5, nao); } + END newl { $$ = list(define_s, $2, $5, nao); + rl($$, num($1)); } | DEFINE ')' newl clauses_opt - END newl { $$ = list(define_s, nil, $4, nao); } + END newl { $$ = list(define_s, nil, $4, nao); + rl($$, num($1)); } | DEFINE error { $$ = nil; yybadtoken(yychar, lit("list expression")); } | DEFINE exprs ')' newl @@ -307,7 +334,8 @@ try_clause : TRY newl END newl { $$ = list(try_s, flatten(mapcar(func_n1(second), $4)), - $3, $4, nao); } + $3, $4, nao); + rl($$, num($1)); } | TRY newl error { $$ = nil; if (yychar == END || yychar == CATCH || @@ -324,15 +352,18 @@ try_clause : TRY newl catch_clauses_opt : CATCH ')' newl clauses_opt catch_clauses_opt { $$ = cons(list(catch_s, cons(t, nil), - $4, nao), $5); } + $4, nao), $5); + rl($$, num($1)); } | CATCH exprs ')' newl clauses_opt catch_clauses_opt { $$ = cons(list(catch_s, $2, $5, nao), - $6); } + $6); + rl($$, num($1)); } | FINALLY newl clauses_opt { $$ = cons(list(finally_s, nil, $3, nao), - nil); } + nil); + rl($$, num($1)); } | { $$ = nil; } | CATCH ')' newl error { $$ = nil; @@ -354,13 +385,15 @@ output_clause : OUTPUT ')' o_elems '\n' END newl { $$ = nil; yyerror("obsolete output syntax: trailing material"); } | OUTPUT ')' newl - END newl { $$ = list(output_s, nao); } + END newl { $$ = rl(list(output_s, nao), num($1)); } | OUTPUT ')' newl out_clauses - END newl { $$ = list(output_s, $4, nao); } + END newl { $$ = rl(list(output_s, $4, nao), num($1)); } | OUTPUT exprs ')' newl out_clauses - END newl { $$ = list(output_s, $5, $2, nao); } + END newl { $$ = list(output_s, $5, $2, nao); + rl($$, num($1)); } + | OUTPUT exprs ')' o_elems '\n' out_clauses END newl { $$ = nil; @@ -414,7 +447,8 @@ out_clause : repeat_clause { $$ = list(num(lineno - 1), $1, nao); } repeat_clause : REPEAT newl out_clauses repeat_parts_opt - END newl { $$ = repeat_rep_helper(repeat_s, $3, $4); } + END newl { $$ = repeat_rep_helper(repeat_s, $3, $4); + rl($$, num($1)); } | REPEAT newl error { $$ = nil; yybadtoken(yychar, lit("repeat clause")); } @@ -422,16 +456,20 @@ repeat_clause : REPEAT newl repeat_parts_opt : SINGLE newl out_clauses_opt - repeat_parts_opt { $$ = cons(cons(single_s, $3), $4); } + repeat_parts_opt { $$ = cons(cons(single_s, $3), $4); + rl($$, num($1)); } | FIRST newl out_clauses_opt - repeat_parts_opt { $$ = cons(cons(first_s, $3), $4); } + repeat_parts_opt { $$ = cons(cons(first_s, $3), $4); + rl($$, num($1)); } | LAST newl out_clauses_opt - repeat_parts_opt { $$ = cons(cons(last_s, $3), $4); } + repeat_parts_opt { $$ = cons(cons(last_s, $3), $4); + rl($$, num($1)); } | EMPTY newl out_clauses_opt - repeat_parts_opt { $$ = cons(cons(empty_s, $3), $4); } + repeat_parts_opt { $$ = cons(cons(empty_s, $3), $4); + rl($$, num($1)); } | /* empty */ { $$ = nil; } ; @@ -464,19 +502,24 @@ o_elem : TEXT { $$ = string_own($1); } rep_elem : REP o_elems rep_parts_opt END { $$ = repeat_rep_helper(rep_s, o_elems_transform($2), - $3); } + $3); + rl($$, num($1)); } | REP error { $$ = nil; yybadtoken(yychar, lit("rep clause")); } ; rep_parts_opt : SINGLE o_elems_opt2 - rep_parts_opt { $$ = cons(cons(single_s, $2), $3); } + rep_parts_opt { $$ = cons(cons(single_s, $2), $3); + rl($$, num($1)); } | FIRST o_elems_opt2 - rep_parts_opt { $$ = cons(cons(first_s, $2), $3); } + rep_parts_opt { $$ = cons(cons(first_s, $2), $3); + rl($$, num($1)); } | LAST o_elems_opt2 - rep_parts_opt { $$ = cons(cons(last_s, $2), $3); } + rep_parts_opt { $$ = cons(cons(last_s, $2), $3); + rl($$, num($1)); } | EMPTY o_elems_opt2 - rep_parts_opt { $$ = cons(cons(empty_s, $2), $3); } + rep_parts_opt { $$ = cons(cons(empty_s, $2), $3); + rl($$, num($1)); } | /* empty */ { $$ = nil; } ; @@ -537,7 +580,7 @@ o_var : IDENT { $$ = list(var_s, intern(string_own($1), nil), var_op : '*' { $$ = list(t, nao); } ; -list : '(' exprs ')' { $$ = $2; } +list : '(' exprs ')' { $$ = rl($2, num($1)); } | '(' ')' { $$ = nil; } | '(' error { $$ = nil; yybadtoken(yychar, lit("list expression")); } @@ -572,7 +615,8 @@ expr : IDENT { $$ = intern(string_own($1), nil); } | quasilit { $$ = $1; } ; -regex : '/' regexpr '/' { $$ = cons(regex_s, $2); end_of_regex(); } +regex : '/' regexpr '/' { $$ = cons(regex_s, $2); end_of_regex(); + rl($$, num(lineno)); } | '/' error { $$ = nil; yybadtoken(yychar, lit("regex")); end_of_regex(); } @@ -664,7 +708,8 @@ chrlit : '\'' '\'' { $$ = nil; ; quasilit : '`' '`' { $$ = null_string; } - | '`' quasi_items '`' { $$ = cons(quasi_s, o_elems_transform($2)); } + | '`' quasi_items '`' { $$ = cons(quasi_s, o_elems_transform($2)); + rl($$, num(lineno)); } | '`' error { $$ = nil; yybadtoken(yychar, lit("string literal")); } ; -- cgit v1.2.3