YACC和LEX,在行尾获取语法错误,无法弄清楚原因
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了YACC和LEX,在行尾获取语法错误,无法弄清楚原因相关的知识,希望对你有一定的参考价值。
这是我的YACC
%{
#include <stdio.h>
#include <ctype.h>
#include "lex.yy.c"
void yyerror (s) /* Called by yyparse on error */
char *s;
{
printf ("%s
", s);
}
%}
%start program
%union{
int value;
char * string;
}
%token <value> NUM INT VOID WHILE IF THEN ELSE READ WRITE RETURN LE GE EQ NE
%token <string> ID
%token <value> INTEGER
%left '|'
%left '&'
%left '+' '-'
%left '*' '/' '%'
%left UMINUS
%%
program : decllist
{fprintf(stderr, "program");}
;
decllist : dec
{fprintf(stderr, "
dec");}
| dec decllist
;
dec : vardec
{fprintf(stderr, "vardec");}
| fundec
{fprintf(stderr, "YEAH");}
;
typespec : INT
| VOID
;
vardec : typespec ID ';'
{fprintf(stderr, "yep");}
| typespec ID '[' NUM ']' ';'
{fprintf(stderr, "again");}
;
fundec : typespec ID '(' params ')' compoundstmt
;
params : VOID
| paramlist
;
paramlist : param
| param ',' paramlist
;
param : typespec ID
| typespec ID '['']'
;
compoundstmt : '{' localdeclerations statementlist '}'
;
localdeclerations :/* empty */
|vardec localdeclerations
;
statementlist : /* empty */
| statement statementlist
;
statement : expressionstmt
| compoundstmt
| selectionstmt
| iterationstmt
| assignmentstmt
| returnstmt
| readstmt
| writestmt
;
expressionstmt : expression ';'
| ';'
;
assignmentstmt : var '=' expressionstmt
;
selectionstmt : IF '(' expression ')' statement
| IF '(' expression ')' statement ELSE statement
;
iterationstmt : WHILE '(' expression ')' statement
;
returnstmt : RETURN ';'
| RETURN expression ';'
;
writestmt : WRITE expression ';'
;
readstmt : READ var ';'
;
expression : simpleexpression
;
var : ID
| ID '[' expression ']'
;
simpleexpression : additiveexpression
| additiveexpression relop simpleexpression
;
relop : LE
| '<'
| '>'
| GE
| EQ
| NE
;
additiveexpression : term
| term addop term
;
addop : '+'
| '-'
;
term : factor
| term multop factor
;
multop : '*'
| '/'
;
factor : '(' expression ')'
| NUM
| var
| call
;
call : ID '(' args ')'
;
args : arglist
| /* empty */
;
arglist : expression
| expression ',' arglist
;
%%
main(){
yyparse();
}
这里是我的LEX
%{
int mydebug=1;
int lineno=0;
#include "y.tab.h"
%}
%%
int {if (mydebug) fprintf(stderr, "int found
");
return(INT);
}
num {if (mydebug) fprintf(stderr, "num found
");
return(NUM);
}
void {if (mydebug) fprintf(stderr, "void found
");
return(VOID);
}
while {if (mydebug) fprintf(stderr, "while found
");
return(WHILE);
}
if {if (mydebug) fprintf(stderr, "if found
");
return(IF);
}
then {if (mydebug) fprintf(stderr, "then found
");
return(THEN);
}
else {if (mydebug) fprintf(stderr, "else found
");
return(ELSE);
}
read {if (mydebug) fprintf(stderr, "read found
");
return(READ);
}
write {if (mydebug) fprintf(stderr, "void found
");
return(WRITE);
}
return {if (mydebug) fprintf(stderr, "void found
");
return(RETURN);
}
'<=' {if (mydebug) fprintf(stderr, "void found
");
return(LE);
}
'>=' {if (mydebug) fprintf(stderr, "void found
");
return(GE);
}
'==' {if (mydebug) fprintf(stderr, "void found
");
return(EQ);
}
'!=' {if (mydebug) fprintf(stderr, "void found
");
return(NE);
}
[a-zA-Z][a-zA-Z0-9]* {if (mydebug) fprintf(stderr,"Letter found
");
yylval.string=strdup(yytext); return(ID);}
[0-9][0-9]* {if (mydebug) fprintf(stderr,"Digit found
");
yylval.value=atoi((const char *)yytext); return(NUM);}
[ ] {if (mydebug) fprintf(stderr,"Whitespace found
");}
[=-+*/%&|()[]<>;] { if (mydebug) fprintf(stderr,"return a token %c
",*yytext);
return (*yytext);}
{ if (mydebug) fprintf(stderr,"cariage return %c
",*yytext);
lineno++;
return (*yytext);}
%%
int yywrap(void)
{ return 1;}
如果我输入'int a;'之类的东西它一直到新行并打印'回车'但后来停止并在最后吐出语法错误。谁能明白为什么?
我已经过了很多,似乎无法找到阻止它的东西。我有一个以前的程序,我要回去试图看看我是否能解决它,但我很难过。有人可以帮忙吗?
答案
你的词法分析器在行的末尾返回'
'
(换行符)标记,但你的解析器从不接受它们,所以当解析器命中第一个换行符时你会得到一个语法错误。
以上是关于YACC和LEX,在行尾获取语法错误,无法弄清楚原因的主要内容,如果未能解决你的问题,请参考以下文章