语法在Bison的语法生成中出错

时间:2013-03-03 23:04:09

标签: 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);
}

但是,我在第一个空格后发现语法错误,我不太明白为什么它甚至不会到达参数部分。如果有任何提示或看到我可能没有看到的东西,我会很感激。我知道我还没有解决悬空的其他问题,但这不应该成为这个测试的问题。

到目前为止,这是我的解析器:

%{

#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

} 

1 个答案:

答案 0 :(得分:1)

你的语法看起来没问题,所以我最好的猜测是你的词法分析器不会将字符串void识别为TOK_VOID,而是返回其他内容。

尝试使用-DYYDEBUG编译解析器并在调用yyparse之前设置yydebug = 1以查看它从词法分析器获取的内容。