diff options
-rw-r--r-- | ChangeLog | 23 | ||||
-rw-r--r-- | parser.l | 15 | ||||
-rw-r--r-- | parser.y | 41 |
3 files changed, 54 insertions, 25 deletions
@@ -1,5 +1,28 @@ 2015-06-26 Kaz Kylheku <kaz@kylheku.com> + 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 <kaz@kylheku.com> + * genman.txr: New filter to add hyperlinks within code in more places such as examples and summary lists. @@ -269,7 +269,7 @@ UONLY {U2}{U}|{U3}{U}{U}|{U4}{U}{U}{U} return NUMBER; } -<SPECIAL,QSPECIAL,NESTED,BRACED>{FLO} { +<SPECIAL,NESTED,BRACED>{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; } -<SPECIAL,QSPECIAL>({FLO}|{FLODOT}){TOK} | +<SPECIAL>({FLO}|{FLODOT}){TOK} | <BRACED>({FLO}|{FLODOT}){BTOK} | <NESTED>({FLO}|{FLODOT}){NTOK} { val str = string_utf8(yytext); @@ -309,7 +309,7 @@ UONLY {U2}{U}|{U3}{U}{U}|{U4}{U}{U}{U} return NUMBER; } -<NESTED,QSILIT,QWLIT>@{NUM} { +<NESTED,QSILIT,QWLIT,QSPECIAL>@{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; } -<NESTED,QSILIT,QWLIT>@{XNUM} { +<NESTED,QSILIT,QWLIT,QSPECIAL>@{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; } -<NESTED,QSILIT,QWLIT>@{ONUM} { +<NESTED,QSILIT,QWLIT,QSPECIAL>@{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; } -<NESTED,QSILIT,QWLIT>@{BNUM} { +<NESTED,QSILIT,QWLIT,QSPECIAL>@{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]; } -<NESTED,BRACED>@ { +<NESTED,BRACED,QSPECIAL>@ { yylval->lineno = yyextra->lineno; return yytext[0]; } @@ -897,6 +897,7 @@ UONLY {U2}{U}|{U3}{U}{U}|{U4}{U}{U}{U} <QSILIT,QWLIT>@ { yy_push_state(QSPECIAL, yyscanner); + return yytext[0]; } <WLIT,QWLIT>{WS} { @@ -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 |