gpt4 book ai didi

c++ - Bison 解析器计算器

转载 作者:行者123 更新时间:2023-11-28 07:16:35 25 4
gpt4 key购买 nike

这是我的 Bison 代码:

%}

%union {
int int_val;
}


%left '+' '-'
%nonassoc '(' ')'

%token INTEGER PRINT
%type <int_val> expr_int INTEGER

%%
program: command '\n' { return 0; }
;
command: print_expr
;
print_expr: PRINT expr_int { cout<<$2<<endl; }
expr_int: expr_int '+' expr_int { $$ = $1 + $3; }
| expr_int '-' expr_int { $$ = $1 - $3; }
| '(' expr_int ')' { $$ = $2; }
| INTEGER
;

这是弹性代码:

%}

INTEGER [1-9][0-9]*|0
BINARY [-+]
WS [ \t]+
BRACKET [\(\)]

%%
print{WS} { return PRINT; }
{INTEGER} { yylval.int_val=atoi(yytext); return INTEGER; }
{BINARY}|\n { return *yytext; }
{BRACKET} { return *yytext; }
{WS} {}
. { return *yytext; }

%%

//////////////////////////////////////////////////
int yywrap(void) { return 1; } // Callback at end of file

程序的无效输入是:

print 5

输出:

5

输入:

print (1+1)

输出:

2

但出于某种原因,对于以下输入,我没有立即收到错误:

print (1+1))

输出:

2
some error

输入:

print 5!

输出:

5
some error

我希望立即打印错误,而不是提交打印命令然后抛出错误。

我应该如何更改程序以便它不会打印错误的输入?

最佳答案

从 John Levine 下载“flex & bison”一书或从 gnu 下载“bison”手册。两者都包含一个您可以引用的中缀计算器。

在检测到“(1 + 1))”中语法错误的“)”之前,您编写的语法“'('expr_int')'”缩减为 expr_int。解析器会执行以下操作:

(1 + 1)) => ( expr_int )) => expr_int) 

然后看到错误。为了捕获错误,您必须更改解析器以在减少之前查看错误,并且必须对所有要处理的错误执行此操作。因此你会写(在这种情况下):

expr_int '(' expr_int ')' ')' { 这是错误信息 }

在长答案之后,简短的答案是生成一个包含所有可能错误实例的解析器是不切实际的。你所拥有的对你正在做的事情来说很好。您应该探索的是如何(优雅地)从错误中恢复,而不是放弃解析。

您的“程序”和“命令”非终端可以组合为:

program: print-expr '\n' { return 0; }

在一个单独的注释中,您的正则表达式可以重写为:

%%
INTEGER [0-9]+
WS [ \t]+

%%
print/{WS} { return PRINT; }
{INTEGER} { yylval.int_val=atoi(yytext); return INTEGER; }
'(' { return '('; }
')' { return ')'; }
'+' { return '+'; }
'-' { return '-'; }
{WS}* {}
\n { return '\n'; }
. { return *yytext; } // do you really want to do this?

%%

关于c++ - Bison 解析器计算器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20142335/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com