regex 语法分析器如何忽略输入中白色

lrl1mhuk  于 2023-04-22  发布在  其他
关注(0)|答案(1)|浏览(99)

在下面的代码中,虽然我添加了\t作为令牌,优先级高于数字,但当我测试它时,它接受-2- 2(在-后面有一个空格)和-2 - 2-周围有2个空格),但它不接受-2-2(没有空格)。对于这种特殊情况有解决方案吗?
我的目标是,当我给予它一个输入,如-2-2-22*3/6-1,它工作正常,不输出'语法错误'。
lexical.l

/* recognize tokens for the calculator and print them out */
/*"--"[0-9]+ { yytext++; yylval = atoi(yytext); return NUMBER; }*/
%{
#include"syntax.tab.h"

%}

%%
"+"    { return ADD; }
"-"    { return SUB; }
"*"    { return MUL; }
"/"    { return DIV; }
"|"    { return ABS; }
[ \t]  { /* ignore whitespace */ }
(-|"")[0-9]+  { yylval = atoi(yytext); return NUMBER; }
\n     { return EOL; }

.      { printf("Mystery character %c\n", *yytext); }
%%

syntax.y

/* simplest version of calculator */
%{
#include <stdio.h>
%}

/* declare tokens */
%token NUMBER
%token ADD SUB MUL DIV ABS
%token EOL

%%

calclist: /* nothing */                       
 | calclist exp EOL { printf("= %d\n", $2); }
 ;

exp: factor       
 | exp ADD factor { $$ = $1 + $3; }
 | exp SUB factor { $$ = $1 - $3; }
 ;

factor: term        
 | factor MUL term { $$ = $1 * $3; }
 | factor DIV term { $$ = $1 / $3; }
 ;

term: NUMBER   
 | ABS term   { if ($2 < 0) $$ = -$2; else $$ = $2; }
;
%%
main(int argc, char **argv)
{
  yyparse();
}

yyerror(char *s)
{
  fprintf(stderr, "error: %s\n", s);
}`
ocebsuys

ocebsuys1#

-2-2被lexer解释为-2-2,而不是-2-2。Lexer总是查找最长的匹配,因此它总是倾向于将减号和数字视为单个标记。
你的解析器没有接受两个连续数字的规则,所以它显示一个错误。(你应该学会在词法分析器和解析器中打开调试输出。在这种情况下,这是非常有帮助的。)
为了解决这个问题,你需要在lexer中删除-作为数字的一部分。将它烘焙到数字中是非常常见的错误,这会导致你遇到的问题。相反,你可以在解析器中定义一元-运算符。
(Btw.,(-|"")可以写成-?。)

相关问题