From 9bf17146994d7586c62f7f52be525ee6f6b08329 Mon Sep 17 00:00:00 2001 From: Kaz Kylheku Date: Fri, 26 Jun 2015 18:55:22 -0700 Subject: First round of quasiliteral-related fixes. * parser.l: Do not try to recognize floating-point literals in QSPECIAL state; that is not possible because @134.3 in a quasiliteral parses as a METANUM followed by ".3". On the other hand, recognize METANUM literals in QSPECIAL state, so that @@123 scans. Recognize @ as a token in QSPECIAL state, so @@abc will scan. When transitioning from QSILIT and QWLIT states to QSPECIAL upon scanning @, return a @ token, which is now parsed in the grammar. * parser.y (quasi_meta_helper): New static function. (q_var): Do not handle SYMTOK any more, only the braced variable syntax. SYMTOK is handled as a n_expr. Braced vars are handled with explicit '@' token, which is now produced by the scanner when it shifts from QSILIT to QSPECIAL. (quasi_item): No longer necessary to recognize various forms here such as quotes and splices. Just recognize a n_expr, preceded by '@'. --- ChangeLog | 23 +++++++++++++++++++++++ parser.l | 15 ++++++++------- parser.y | 41 +++++++++++++++++++++++------------------ 3 files changed, 54 insertions(+), 25 deletions(-) diff --git a/ChangeLog b/ChangeLog index 20792a0d..09b4be30 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,26 @@ +2015-06-26 Kaz Kylheku + + First round of quasiliteral-related fixes. + + * parser.l: Do not try to recognize floating-point literals + in QSPECIAL state; that is not possible because @134.3 + in a quasiliteral parses as a METANUM followed by ".3". + On the other hand, recognize METANUM literals in QSPECIAL state, + so that @@123 scans. Recognize @ as a token in QSPECIAL state, + so @@abc will scan. When transitioning from QSILIT and QWLIT + states to QSPECIAL upon scanning @, return a @ token, which + is now parsed in the grammar. + + * parser.y (quasi_meta_helper): New static function. + (q_var): Do not handle SYMTOK any more, only the braced + variable syntax. SYMTOK is handled as a n_expr. + Braced vars are handled with explicit '@' token, which + is now produced by the scanner when it shifts from QSILIT + to QSPECIAL. + (quasi_item): No longer necessary to recognize various + forms here such as quotes and splices. Just recognize a n_expr, + preceded by '@'. + 2015-06-26 Kaz Kylheku * genman.txr: New filter to add hyperlinks within code in diff --git a/parser.l b/parser.l index 9036278f..4a133836 100644 --- a/parser.l +++ b/parser.l @@ -269,7 +269,7 @@ UONLY {U2}{U}|{U3}{U}{U}|{U4}{U}{U}{U} return NUMBER; } -{FLO} { +{FLO} { val str = string_own(utf8_dup_from(yytext)); if (yy_top_state(yyscanner) == INITIAL @@ -293,7 +293,7 @@ UONLY {U2}{U}|{U3}{U}{U}|{U4}{U}{U}{U} return NUMBER; } -({FLO}|{FLODOT}){TOK} | +({FLO}|{FLODOT}){TOK} | ({FLO}|{FLODOT}){BTOK} | ({FLO}|{FLODOT}){NTOK} { val str = string_utf8(yytext); @@ -309,7 +309,7 @@ UONLY {U2}{U}|{U3}{U}{U}|{U4}{U}{U}{U} return NUMBER; } -@{NUM} { +@{NUM} { val str = string_own(utf8_dup_from(yytext + 1)); if (yy_top_state(yyscanner) == INITIAL @@ -320,7 +320,7 @@ UONLY {U2}{U}|{U3}{U}{U}|{U4}{U}{U}{U} return METANUM; } -@{XNUM} { +@{XNUM} { val str = string_own(utf8_dup_from(yytext + 3)); if (yy_top_state(yyscanner) == INITIAL @@ -331,7 +331,7 @@ UONLY {U2}{U}|{U3}{U}{U}|{U4}{U}{U}{U} return METANUM; } -@{ONUM} { +@{ONUM} { val str = string_own(utf8_dup_from(yytext + 3)); if (yy_top_state(yyscanner) == INITIAL @@ -342,7 +342,7 @@ UONLY {U2}{U}|{U3}{U}{U}|{U4}{U}{U}{U} return METANUM; } -@{BNUM} { +@{BNUM} { val str = string_own(utf8_dup_from(yytext + 3)); if (yy_top_state(yyscanner) == INITIAL @@ -558,7 +558,7 @@ UONLY {U2}{U}|{U3}{U}{U}|{U4}{U}{U}{U} return yytext[0]; } -@ { +@ { yylval->lineno = yyextra->lineno; return yytext[0]; } @@ -897,6 +897,7 @@ UONLY {U2}{U}|{U3}{U}{U}|{U4}{U}{U}{U} @ { yy_push_state(QSPECIAL, yyscanner); + return yytext[0]; } {WS} { diff --git a/parser.y b/parser.y index 01e7295e..12324f51 100644 --- a/parser.y +++ b/parser.y @@ -58,6 +58,7 @@ static val rlrec(parser_t *, val form, val line); 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_for_include(val spec_rev); +static val quasi_meta_helper(val obj); #if YYBISON union YYSTYPE; @@ -685,12 +686,10 @@ o_var : SYMTOK { $$ = list(var_s, symhlpr($1, nil), nao); yybadtok(yychar, lit("variable spec")); } ; -q_var : SYMTOK { $$ = list(var_s, symhlpr($1, nil), nao); +q_var : '@' '{' n_expr n_exprs_opt '}' + { $$ = list(var_s, $3, $4, nao); rl($$, num(parser->lineno)); } - | '{' n_expr n_exprs_opt '}' - { $$ = list(var_s, $2, $3, nao); - rl($$, num(parser->lineno)); } - | SYMTOK error { $$ = nil; + | '@' '{' error { $$ = nil; yybadtok(yychar, lit("variable spec")); } ; @@ -959,19 +958,7 @@ quasi_item : litchars { $$ = lit_char_helper($1); } | q_var { $$ = $1; } | METANUM { $$ = cons(var_s, cons($1, nil)); rl($$, num(parser->lineno)); } - | list { $$ = rlcp(cons(expr_s, $1), $1); } - | '\'' n_expr { $$ = rl(rlcp(cons(expr_s, list(quote_s, $2, nao)), $2), - num(parser->lineno)); - rlcp_tree($$, $$); } - | '^' n_expr { $$ = rl(rlcp(cons(expr_s, list(sys_qquote_s, $2, nao)), $2), - num(parser->lineno)); - rlcp_tree($$, $$); } - | ',' n_expr { $$ = rl(rlcp(cons(expr_s, list(sys_unquote_s, $2, nao)), $2), - num(parser->lineno)); - rlcp_tree($$, $$); } - | SPLICE n_expr { $$ = rl(rlcp(cons(expr_s, list(sys_splice_s, $2, nao)), $2), - num(parser->lineno)); - rlcp_tree($$, $$); } + | '@' n_expr { $$ = quasi_meta_helper($2); } ; litchars : LITCHAR { $$ = rl(cons(chr($1), nil), num(parser->lineno)); } @@ -1357,6 +1344,24 @@ static val check_for_include(val spec_rev) return spec_rev; } +static val quasi_meta_helper(val obj) +{ + if (integerp(obj) || symbolp(obj)) + goto var; + + if (atom(obj) || length(obj) != two) + goto expr; + + if (first(obj) == var_s && integerp(second(obj))) + goto var; + +var: + return rlcp_tree(cons(var_s, cons(obj, nil)), obj); + +expr: + return rlcp(cons(expr_s, obj), obj); +} + #ifndef YYEOF #define YYEOF 0 #endif -- cgit v1.2.3