Parsing Bison语法生成中的语法错误

Parsing Bison语法生成中的语法错误,parsing,syntax-error,grammar,bison,Parsing,Syntax Error,Grammar,Bison,作为测试文件,我使用这段代码来查看解析器是否工作正常: /* A test program */ void main(void){ int x; int y; int z; x= 10; y = 20; z =x* (x+y); } 然而,在第一个void之后,我得到了一个语法错误,我不太明白为什么它甚至不能到达参数部分。如果有任何提示或看到一些我可能没有看到的东西,我将不胜感激。我知道我还没有解决悬而未决的else问题,但这不应该成为这次测试的问题 到目前为止,我的解析器如下:

作为测试文件,我使用这段代码来查看解析器是否工作正常:

/* A test program  */

void main(void){
int x;
int y;
    int z;

x= 10;
y = 20;
z =x* (x+y);
}
然而,在第一个void之后,我得到了一个语法错误,我不太明白为什么它甚至不能到达参数部分。如果有任何提示或看到一些我可能没有看到的东西,我将不胜感激。我知道我还没有解决悬而未决的else问题,但这不应该成为这次测试的问题

到目前为止,我的解析器如下:

%{

#include <stdio.h>
#include <string.h>
#include <stdlib.h>


/* external function prototypes */
extern int yylex();
extern int initLex(int ,  char **);



/* external global variables */

extern int      yydebug;
extern int      yylineno;


/* function prototypes */ 
void    yyerror(const char *);

/* global variables */

%}

/* YYSTYPE */

/* terminals */
/* Start adding token names here */
/* Your token names must match Project 1 */
/* The file cmparser.tab.h was gets generated here */

%token TOK_ERROR
%token TOK_ELSE 
%token TOK_IF
%token TOK_RETURN
%token TOK_VOID
%token TOK_INT
%token TOK_WHILE
%token TOK_PLUS
%token TOK_MINUS
%token TOK_MULT
%token TOK_DIV
%token TOK_LT
%token TOK_LE
%token TOK_GT
%token TOK_GE
%token TOK_EQ
%token TOK_NE
%token TOK_ASSIGN
%token TOK_SEMI
%token TOK_COMMA
%token TOK_LPAREN
%token TOK_RPAREN
%token TOK_LSQ
%token TOK_RSQ
%token TOK_LBRACE
%token TOK_RBRACE
%token TOK_NUM
%token TOK_ID

/* associativity and precedence */
/* specify operator precedence (taken care of by grammar) and associatity here -
-uncomment */

//%left

%left '*' '/'
%left '+' '-'
%nonassoc '<' '>' "<=" ">="
%left "==" "!=" 
%right  '=' 
%nonassoc error

/* Begin your grammar specification here */
%%


Start   : /* put your RHS for this rule here */
   Declarations
    { printf ("Declaration.\n"); }

; /* note that the rule ends with a semicolon */

Declarations    :
/* empty */
{}
| Vardeclaration Declarations
{ printf ("Var-declaration.\n");}
| Fundeclaration Declarations
{ printf ("Fun-declaration.\n");}
;

Vardeclaration  :   
Typespecifier TOK_ID ';'
{ printf ("Not an array.\n");}
| Typespecifier TOK_ID '[' TOK_NUM ']' ';'
{ printf ("An array.\n");}
;

Typespecifier   :
TOK_INT
{ printf ("Type int.\n");}
| TOK_VOID
{ printf("Type void.\n");}
;

Fundeclaration  :
Typespecifier TOK_ID '(' Params ')' Compoundstmt
{ printf ("Function Declaration.");}
;

Params  :
Paramlist
| TOK_VOID
{ printf ("Void param.\n");}
;

Paramlist   :
Paramlist ',' Param
| Param
;

Param   :
Typespecifier TOK_ID
| Typespecifier TOK_ID '[' ']'
;

Compoundstmt    :
'{' Localdeclaration Statement '}'
;

Localdeclaration    :
Vardeclaration Localdeclaration
| /* empty */
;

Statement   :
Expressionstmt Statement
| Compoundstmt Statement
| Selectionstmt Statement
| Iterationstmt Statement
| Returnstmt Statement
| /* empty */
;

Expressionstmt  :
Expression ';'
| ';'
;

Selectionstmt   :
TOK_IF '(' Expression ')' Statement
| TOK_IF '(' Expression ')' Statement TOK_ELSE Statement
;

Iterationstmt   :
TOK_WHILE '(' Expression ')' Statement
;

Returnstmt  :
TOK_RETURN ';'
| TOK_RETURN Expression ';'
;

Expression  :
Var '=' Expression
| SimpleExpression
;

Var :
TOK_ID
| TOK_ID '[' Expression ']'
;

SimpleExpression    :
AdditiveExpression Relop AdditiveExpression
| AdditiveExpression
;

Relop   :
"<="
| '<'
| '>'
| ">="
| "=="
| "!="
;

AdditiveExpression  :
AdditiveExpression Addop Term
| Term
;

Addop   :
'+'
| '-'
;

Term    :
Term Mulop Factor
| Factor
;

Mulop   :
'*'
| '/'
;

Factor  :
'(' Expression ')'
| Var
| Call
| TOK_NUM
;

Call    :
TOK_ID '(' Args ')'
;

Args    :
Arglist
| /* empty */
;

 Arglist    :
Arglist ',' Expression
| Expression
;
%%
void yyerror (char const *s) {
   fprintf (stderr, "Line %d: %s\n", yylineno, s);
}

int main(int argc, char **argv){

initLex(argc,argv);

#ifdef YYLLEXER
while (gettok() !=0) ; //gettok returns 0 on EOF
return;
#else
yyparse();

#endif

} 
%{
#包括
#包括
#包括
/*外部功能原型*/
extern int yylex();
extern int initLex(int,char**);
/*外部全局变量*/
外部调试;
外部内部yylineno;
/*功能原型*/
无效错误(常量字符*);
/*全局变量*/
%}
/*YYSTYPE*/
/*终端*/
/*开始在此处添加令牌名称*/
/*您的令牌名称必须与项目1匹配*/
/*在这里生成文件cmparser.tab.h*/
%令牌托库错误
%token TOK_ELSE
%TOK_IF代币
%token TOK_返回
%token TOK_VOID
%token TOK_INT
%token TOK_WHILE
%token TOK_PLUS
%TOK_负号
%token TOK_MULT
%代币托克分区
%token TOK_LT
%托克勒代币
%token TOK_GT
%token TOK_GE
%token TOK_EQ
%token Tokne
%令牌TOK_分配
%token TOK_SEMI
%token TOK_逗号
%token TOK_LPAREN
%token TOK_RPAREN
%token TOK_LSQ
%token TOK_RSQ
%token Toklbrace
%token TOK_RBRACE
%token TOK_NUM
%令牌托库ID
/*结合性与优先性*/
/*在此处指定运算符优先级(由语法负责)和关联性-
-取消注释*/
//%左
%左'*''/'
%左'+''-'
%非ASSOC“”“=”
%左“==”!=”
%对“=”
%非对称误差
/*从这里开始语法说明*/
%%
开始:/*将此规则的RHS放在此处*/
声明
{printf(“声明。\n”);}
; /* 请注意,该规则以分号结尾*/
声明:
/*空的*/
{}
|Vardeclaration声明
{printf(“Var声明。\n”);}
|基金会声明
{printf(“有趣的声明。\n”);}
;
声明:
类型说明符TOK_ID';'
{printf(“不是数组。\n”);}
|类型说明符TOK_ID'['TOK_NUM']''
{printf(“数组。\n”);}
;
类型说明符:
托库内
{printf(“类型int.\n”);}
|托库空
{printf(“键入void.\n”);}
;
基金会:
类型说明符TOK_ID'('Params')'Compoundstmt
{printf(“函数声明”);}
;
参数:
参数列表
|托库空
{printf(“Void参数。\n”);}
;
参数列表:
参数列表“,”参数
|Param
;
参数:
类型说明符TOK_ID
|类型说明符TOK_ID'['']
;
复合stmt:
“{”Localdeclaration语句“}”
;
本地声明:
Vardeclaration本地声明
|/*空*/
;
声明:
Expressionstmt语句
|复合stmt语句
|Selectionstmt语句
|迭代TMT语句
|Returnstmt语句
|/*空*/
;
表达TMT:
表达式“;”
| ';'
;
选择TMT:
TOK_IF'('Expression')语句
|TOK_IF'(“表达式”)语句TOK_ELSE语句
;
迭代TMT:
TOK_WHILE“(“表达式”)”语句
;
Returnstmt:
TOK_RETURN';'
|TOK_返回表达式“;”
;
表达方式:
变量“=”表达式
|简单表达式
;
变量:
托库ID
|TOK_ID'['表达式']
;
SimpleExpression:
AdditiveExpression重新加载AdditiveExpression
|加法表达式
;
重播:
"="
| "=="
| "!="
;
加法表达式:
加法表达式加法项
|术语
;
地址:
'+'
| '-'
;
术语:
术语多重因子
|因素
;
Mulop:
'*'
| '/'
;
因素:
“(“表达式”)”
|变量
|召唤
|托克努姆
;
电话:
TOK_ID'('Args')'
;
Args:
Arglist
|/*空*/
;
Arglist:
参数列表','表达式
|表情
;
%%
无效错误(字符常量*s){
fprintf(标准,“第%d行:%s\n”,yylineno,s);
}
int main(int argc,字符**argv){
initLex(argc,argv);
#ifdef-yylexer
while(gettok()!=0);//gettok在EOF上返回0
返回;
#否则
yyparse();
#恩迪夫
} 

您的语法看起来不错,因此我最好的猜测是您的lexer不会将字符串
void
识别为
TOK_void
,而是返回其他内容


在调用yyparse之前,请尝试使用
-DYYDEBUG
编译解析器,并设置
yydebug=1
,查看它从lexer中得到了什么。

好的,它似乎不接受我规则中的字符。必须将它们全部更改为其标记名。谢谢你的帮助。