[英]What's wrong with my grammar
我嘗試將以下內容輸入到我的yacc解析器中:
int main(void)
{
return;
}
根據yacc文件中定義的內容,它對我來說似乎有效,但是返回后我收到“語法錯誤”消息。 這是為什么?
yacc文件:
/* C-Minus BNF Grammar */
%{
#include "parser.h"
#include <string.h>
%}
%union
{
int intval;
struct symtab *symp;
}
%token ELSE
%token IF
%token INT
%token RETURN
%token VOID
%token WHILE
%token <symp> ID
%token <intval> NUM
%token LTE
%token GTE
%token EQUAL
%token NOTEQUAL
type <string> paramlist
%%
program : declaration_list ;
declaration_list : declaration_list declaration | declaration ;
declaration : var_declaration
| fun_declaration
| '$' { printTable();};
var_declaration : type_specifier ID ';' {$2->value = 0; $2->arraysize = 0;};
| type_specifier ID '[' NUM ']' ';' {$2->arraysize = $4;printf("Array size is %d", $2->arraysize);} ;
type_specifier : INT | VOID ;
fun_declaration : type_specifier ID '(' params ')' compound_stmt {printf("function declaration\n"); $2->args = 'a'; printf("Parameters: \n", $2->args); } ;
params : param_list | VOID ;
param_list : param_list ',' param
| param ;
param : type_specifier ID | type_specifier ID '[' ']' ;
compound_stmt : '{' local_declarations statement_list '}' {printf("exiting scope\n"); } ;
local_declarations : local_declarations var_declaration
| /* empty */ ;
statement_list : statement_list statement
| /* empty */ ;
statement : expression_stmt
| compound_stmt
| selection_stmt
| iteration_stmt
| return_stmt ;
expression_stmt : expression ';'
| ';' ;
selection_stmt : IF '(' expression ')' statement
| IF '(' expression ')' statement ELSE statement ;
iteration_stmt : WHILE '(' expression ')' statement ;
return_stmt : RETURN ';' | RETURN expression ';' ;
expression : var '=' expression | simple_expression ;
var : ID | ID '[' expression ']' ;
simple_expression : additive_expression relop additive_expression
| additive_expression ;
relop : LTE | '<' | '>' | GTE | EQUAL | NOTEQUAL ;
additive_expression : additive_expression addop term | term ;
addop : '+' | '-' ;
term : term mulop factor | factor ;
mulop : '*' | '/' ;
factor : '(' expression ')' | var | call | NUM ;
call : ID '(' args ')' ;
args : arg_list | /* empty */ ;
arg_list : arg_list ',' expression | expression ;
%%
/* look up a symbol table entry, add if not present */
struct symtab *symlook(char *s) {
printf("Putting %s into the symbol table\n", s);
//char *p;
struct symtab *sp;
for(sp = symtab; sp < &symtab[NSYMS]; sp++) {
/* is it already here? */
if(sp->name && !strcmp(sp->name, s))
{
yyerror("already in symbol table\n");
exit(1);
return sp;
}
if(!sp->name) { /* is it free */
sp->name = strdup(s);
return sp;
}
/* otherwise continue to next */
}
yyerror("Too many symbols");
exit(1); /* cannot continue */
} /* symlook */
yyerror(char *s)
{
printf( "yyerror: %s\n", s);
}
printTable()
{
printf("Print out the symbol table:\n\n");
struct symtab *sp;
for(sp = symtab; sp < &symtab[NSYMS]; sp++)
{
printf("name: %s\t"
"args: %s\t"
"value %d\t"
"arraysize %d\n",
sp->name,
sp->args,
sp->value,
sp->arraysize);
}
}
我看不到您的yacc語法文件有什么問題; 我最好的猜測是您的掃描儀沒有正確返回RETURN令牌。 如果我與您一起編譯您的yacc源
解析器
#define NSYMS 100
struct symtab {
char *name;
int value;
int arraysize;
char *args;
} symtab[NSYMS];
掃描儀
%{
#include "parser.tab.h"
extern struct symtab *symlook(char *);
extern void printTable();
%}
%option noyywrap
NUM [0-9][0-9]*
ID [_a-zA-Z][_a-zA-Z0-9]*
%%
else return ELSE;
if return IF;
int return INT;
return return RETURN;
void return VOID;
while return WHILE;
"==" return EQUAL;
"!=" return NOTEQUAL;
">=" return LTE;
"<=" return GTE;
[ \t\n] ;
{NUM} { yylval.intval = atoi(yytext); return NUM; }
{ID} { yylval.symp = symlook(yytext); return ID; }
. return *yytext;
%%
int main()
{
yyparse();
printTable();
return 0;
}
然后它接受您的示例程序,並且沒有錯誤,並且只打印出帶有主要符號的符號表
我的yacc發出有關減少班次沖突的警告。 我懷疑問題在於它無法盡快區分函數和變量定義。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.