0

テスト ファイルとして、次のコードを使用して、パーサーが正常に機能しているかどうかを確認しています。

/* 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

} 
4

1 に答える 1

1

あなたの文法は問題ないように見えるので、レクサーは文字列voidを として認識せずTOK_VOID、代わりに別のものを返すと推測されます。

パーサーをコンパイルして-DYYDEBUG設定yydebug = 1してから yyparse を呼び出して、レクサーから何が得られるかを確認してください。

于 2013-03-04T00:02:47.620 に答える