【发布时间】:2012-03-24 22:27:39
【问题描述】:
我正在尝试在 Pascal 语言上制作一个非常简单的 YACC 解析器,它只包括整数声明、一些基本表达式和 if-else 语句。但是,我几个小时都找不到错误,我很快就会发疯。终端说Error at line:0,但这是不可能的!我将 flex 和 byacc 用于解析器。如果您能帮助我,我将非常高兴。如您所见,这是我的 lex 文件;
%{
#include <stdio.h>
#include <string.h>
#include "y.tab.h"
extern int yylval;
int linenum=0;
%}
digit [0-9]
letter [A-Za-z]
%%
if return IF;
then return THEN;
else return ELSE;
for return FOR;
while return WHILE;
PROGRAM return PROGRAM_SYM;
BEGIN return BEGIN_SYM;
VAR return VAR_SYM;
END return END_SYM;
INTEGER return INTEGER_SYM;
{letter}({letter}|{digit})* return identifier;
[0-9]+ return NUMBER;
[\<][\=] return CON_LE;
[\>][\=] return CON_GE;
[\=] return CON_EQ;
[\:][\=] return ASSIGNOP;
; return semiColon;
, return comma;
\n {linenum++;}
. return (int) yytext[0];
%%
这是我的 Yacc 文件
%{
#include <stdio.h>
#include <string.h>
#include "y.tab.h"
extern FILE *yyin;
extern int linenum;
%}
%token PROGRAM_SYM VAR_SYM BEGIN_SYM END_SYM INTEGER_SYM NUMBER
%token identifier INTEGER ASSIGNOP semiColon comma THEN
%token IF ELSE FOR WHILE
%token CON_EQ CON_LE CON_GE GE LE
%left '*' '/'
%left '+' '-'
%start program
%%
program: PROGRAM_SYM identifier semiColon VAR_SYM dec_block BEGIN_SYM statement_list END_SYM '.'
;
dec_block:
dec_list semiColon;
dec_list:
dec_list dec
|
dec
;
dec:
int_dec_list
;
int_dec_list:
int_dec_list int_dec ':' type
|
int_dec ':' type
;
int_dec:
int_dec comma identifier
|
identifier
;
type:
INTEGER_SYM
;
statement_list:
statement_list statement
|
statement
;
statement:
assignment_list
|
expression_list
|
selection_list
;
assignment_list:
assignment_list assignment
|
assignment
;
assignment:
identifier ASSIGNOP expression_list
;
expression_list:
expression_list expression semiColon
|
expression semiColon
;
expression:
'(' expression ')'
|
expression '*' expression
|
expression '/' expression
|
expression '+' expression
|
expression '-' expression
|
factor
;
factor:
identifier
|
NUMBER
;
selection_list:
selection_list selection
|
selection
;
selection:
IF '(' logical_expression ')' THEN statement_list ELSE statement_list
;
logical_expression:
logical_expression '=' expression
|
logical_expression '>' expression
|
logical_expression '<' expression
;
%%
void yyerror(char *s){
fprintf(stderr,"Error at line: %d\n",linenum);
}
int yywrap(){
return 1;
}
int main(int argc, char *argv[])
{
/* Call the lexer, then quit. */
yyin=fopen(argv[1],"r");
yyparse();
fclose(yyin);
return 0;
}
最后我在输入时在第一行出现错误;
PROGRAM myprogram;
VAR
i:INTEGER;
i3:INTEGER;
j:INTEGER;
BEGIN
i := 3;
j := 5;
i3 := i+j*2;
i := j*20;
if(i>j)
then i3 := i+50+(45*i+(40*j));
else i3 := i+50+(45*i+(40*j))+i+50+(45*i+(30*j));
END.
【问题讨论】:
-
您使用的是哪个版本的 Yacc?当我使用
bison编译您的代码时,我会收到有关grammar.y: warning: 3 useless nonterminals and 7 useless rules和grammar.y: conflicts: 8 shift/reduce的警告(以及介于两者之间的特定错误消息)。您是否打算在运行程序之前修复其中的任何一个? (FWIW:当我不顾警告运行程序时,我会收到与您相同的错误消息。) -
它应该是
byacc,即使我遇到了 13 个移位/减少冲突,它们也不应该成为问题,因为我说它由非常简单的语法组成,顺便说一下Error at line 0。我什至尝试写树形但无法意识到问题 -
它太愚蠢了,它在第 0 行给出了错误!!我试图解决这个问题几个小时,但没有任何改善......
-
请注意,发布的示例不是有效的 Pascal。在这种情况下,一个“;”在 else 之前是不允许的,所以如果它被解析为正确,则解析器是错误的。这是 Pascal 对悬空 else 问题的解决方案/破解的一部分
标签: parsing pascal yacc lex parser-generator