大家好,我正在尝试为这个简单的 java 简单文件编写一个解析器,基本上我希望这个解析器能够识别和验证指令块。找到正确的指令块后,验证器将打印一条成功消息。
输入文件:
{
a = b;
}
{
counter = counter- 1;
i = i + 1;
}
{
variable1 = i / j;
variable2 = i * j;
i++;
j--;
}
但无论我尝试什么,我总是遇到语法错误
Bison parser.y 代码:
%{
#include <stdio.h>
%}
%union {
char * str;
}
%token IDENTIFIER
%token INT_LITERAL
%token STRING_LITERAL
%token PLUS PLUS_PLUS MINUS MINUS_MINUS EQUAL SEMICOLON
%%
program: block
| /* empty */
;
block: '{' statement_list '}'
;
statement_list: statement
| statement_list statement
;
statement: assignment_statement
| increment_statement
| decrement_statement
;
assignment_statement: IDENTIFIER EQUAL INT_LITERAL SEMICOLON
;
increment_statement: IDENTIFIER PLUS_PLUS SEMICOLON
;
decrement_statement: IDENTIFIER MINUS_MINUS SEMICOLON
;
%%
int yyerror (char *s) {
fprintf (stderr, "%s\n", s);
}
int main() {
yyparse();
return 0;
}
Flex parserlex.l 代码:
%{
#include "parser.tab.h"
%}
%%
"{" { return '{'; }
"}" { return '}'; }
"=" { return EQUAL; }
";" { return SEMICOLON; }
"++" { return PLUS_PLUS; }
"--" { return MINUS_MINUS; }
[ \t\n\r]+ ; // Ignore white spaces
[a-zA-Z_][a-zA-Z0-9_]* { yylval.str = strdup(yytext); return IDENTIFIER; }
[0-9]+ { yylval.str = strdup(yytext); return INT_LITERAL; }
. { fprintf(stderr, "Unrecognized token: %s\n", yytext); return 0; }
%%
int yywrap() {
return 1;
}
我不知道出了什么问题,因为我收到的唯一错误消息是“语法错误”,我什至不知道从哪里开始寻找潜在的解决方案。 我还尝试使用 bison -v 并读取 bison.output 文件,但它并没有给我带来太多帮助。任何帮助将不胜感激
你的语法的一些明显的局限性:
您的 assignment_statement 规则仅接受
IDENTIFIER EQUAL INT_LITERAL
,因此除 rhs 上的常量之外的任何内容(例如 a = b;
- 输入中的第二行)都会给出语法错误
您的顶级程序仅接受单个块,因此在看到第二个块时会出现语法错误(如果它达到了那么远)。
为了帮助跟踪您的程序,您可以启用跟踪代码(通过使用 bison 的
-t
参数),并通过在调用 yydebug = 1
之前设置 yyparse()
将其打开。我更喜欢放类似的东西
if (getennv('YYDEBUG')) yydebug = 1;
在 main 的开头并始终使用
-t
(或 .y 文件顶部附近的 %define parse.trace
- 效果相同)。这样,如果您在运行程序之前在环境中设置 YYDEBUG
,它将打印一条跟踪信息。