作为一个测试文件,我正在使用这段代码来查看解析器是否运行良好:
/* 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
}