diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2017-09-07 22:11:39 -0700 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2017-09-07 22:11:39 -0700 |
commit | fd47bc4ae6bb9f6a4dab2cf12e8c5cb7459675e2 (patch) | |
tree | 0ccda2dce4ebc58a0e71e3bdab296452467edd9f /parser.y | |
parent | 4c7c4e5fc3c53fca40d619e73b891269feffa010 (diff) | |
download | txr-fd47bc4ae6bb9f6a4dab2cf12e8c5cb7459675e2.tar.gz txr-fd47bc4ae6bb9f6a4dab2cf12e8c5cb7459675e2.tar.bz2 txr-fd47bc4ae6bb9f6a4dab2cf12e8c5cb7459675e2.zip |
parser: fix precedence of DOTDOT.
The problem is that a.b .. c.d parses as (qref a b..c d),
which is useless and counterintuitive.
Let's fix it, but with a backward compatibility switch to give
more leeway to any hapless people out there whose code happens
to depend on this unfortunate situation.
We basically use two token numbers for the .. token:
OLD_DOTDOT, and DOTDOT. Both are wired into the grammar. In
backward compatibility mode, the lexer pumps out OLD_DOTDOT.
Otherwise DOTDOT.
* parser.l (grammar): When .. is scanned, return OLD_DOTDOT
when in compatibility with 185 or earlier. Otherwise DOTDOT.
* parser.y (OLD_DOTDOT): New terminal symbol; introduced at
the same high precedence previously occupied by DOTDOT.
(DOTDOT): Changes precedence to lower than '.' and UREFDOT.
(n_expr): Two productions added involving OLD_DOTDOT.
These are copy and paste of the existing productions involving
DOTDOT; the only difference is that OLD_DOTDOT replaces
DOTDOT.
(yybadtoken): Handle OLD_DOTDOT.
* txr.1: Compat notes added.
Diffstat (limited to 'parser.y')
-rw-r--r-- | parser.y | 15 |
1 files changed, 14 insertions, 1 deletions
@@ -122,6 +122,7 @@ INLINE val expand_form_ver(val form, int ver) %token <lineno> HASH_B_QUOTE %token <lineno> WORDS WSPLICE QWORDS QWSPLICE %token <lineno> SECRET_ESCAPE_R SECRET_ESCAPE_E SECRET_ESCAPE_I +%token <lineno> OLD_DOTDOT %token <val> NUMBER METANUM %token <val> HASH_N_EQUALS HASH_N_HASH @@ -162,8 +163,9 @@ INLINE val expand_form_ver(val form, int ver) %left '|' '/' %left '&' %right '~' '*' '?' '+' '%' -%right '.' CONSDOT LAMBDOT UREFDOT REGCHAR REGTOKEN LITCHAR %right DOTDOT +%right '.' CONSDOT LAMBDOT UREFDOT REGCHAR REGTOKEN LITCHAR +%right OLD_DOTDOT %% @@ -1015,6 +1017,16 @@ n_expr : SYMTOK { $$ = symhlpr($1, t); } uref_helper(parser, $4), nao), or2($1, $4)); } + | n_expr OLD_DOTDOT n_expr + { uses_or2; + $$ = rlcp(list(rcons_s, $1, $3, nao), + or2($1, $3)); } + | n_expr OLD_DOTDOT '.' n_expr + { uses_or2; + $$ = rlcp(list(rcons_s, $1, + uref_helper(parser, $4), + nao), + or2($1, $4)); } | n_expr '.' n_expr { uses_or2; if (consp($3) && car($3) == qref_s) { rplacd($3, rlcp(cons($1, cdr($3)), $1)); @@ -1782,6 +1794,7 @@ void yybadtoken(parser_t *parser, int tok, val context) case CONSDOT: problem = lit("consing dot"); break; case LAMBDOT: problem = lit("consing dot"); break; case DOTDOT: problem = lit(".."); break; + case OLD_DOTDOT: problem = lit(".."); break; case HASH_BACKSLASH: problem = lit("#\\"); break; case HASH_SLASH: problem = lit("#/"); break; case HASH_H: problem = lit("#H"); break; |