我是flex和bison的新手,我正在尝试使用flex和bison制作计算器。我的flex正在编译,但我的野牛文件中出现错误。
下面是我的flex文件:
%{
#include <stdio.h>
#include <stdlib.h>
#include "calc.tab.h"
%}
digit ([0-9])
characters ([a-z])
smallcasedigit ([a-z0-9])
identifier ([a-z])(a-z0-9])*
%option yylineno
%%
"main()" { return(TOK_MAIN);}
"{" { return(TOK_OPEN_CURLY);}
"}" { return(TOK_CLOSE_CURLY);}
"printvar" { return(TOK_PRINTVAR);}
"println" { return(TOK_PRINTLN);}
"int" { return(TOK_INT_KEYWORD);}
"float" { return(TOK_FLOAT_KEYWORD);}
{digit}+ { yylval.int_val=atoi(yytext);
printf(" TOK_NUM_INT \n");
return TOK_NUM_INT;}
{digit}+[.]{digit}+ { yylval.float_val=atof(yytext);
printf(" TOK_NUM_FLOAT \n");
return TOK_NUM_FLOAT;}
{identifier} { yylval.string=strdup(yytext);
printf(" TOK_IDENTIFIER %s\n",yytext);
return(TOK_IDENTIFIER); }
";" { return(TOK_SEMICOLON);}
"+" { return(TOK_ADD);}
"-" { return(TOK_SUB);}
"*" { return(TOK_MUL);}
"/" { return(TOK_DIV);}
"=" { reurn(TOK_EQUAL);}
[ \n] { }
. { printf("Invalid character '%c', ignored\n", yytext[0]); }
%%
/*int main(){ yylex();
printf(" lexical Analysisfinished ");return 0;}*/
这是我的野牛文件:
%{
#include <stdio.h>
extern int yylineno;
typedef struct sym_node * smt;
typedef struct sym_node
{
smt *smt;
int type;
char *id_name;
/* data */
}sm_node;
%}
%token TOK_MAIN_BRACKET TOK_OPEN_CURLY TOK_CLOSE_CURLY TOK_PRINTVAR TOK_PRINTLN TOK_INT_KEYWORD TOK_FLOAT_KEYWORD TOK_NUM_INT TOK_NUM_FLOAT TOK_IDENTIFIER TOK_SEMICOLON TOK_ADD
TOK_SUB TOK_MUL TOK_DIV TOK_NUM TOK_EQUAL
%union{
int int_val;
float float_val;
char *string;
struct s_expr
{
int type;
int ival;
float fval;
}struct_expr;
}
%type <int_val> TOK_NUM_INT
%type <float_val> TOK_NUM_FLOAT
%type <string> TOK_IDENTIFIER
%type <struct_expr> expr
%left TOK_ADD TOK_SUB
%left TOK_MUL TOK_DIV
%%
prog: TOK_MAIN TOK_OPEN_CURLY stmts TOK_CLOSE_CURLY
;
stmts:
| stmt TOK_SEMICOLON stmts
;
stmt:
TOK_INT_KEYWORD TOK_IDENTIFIER
| TOK_FLOAT_KEYWORD TOK_IDENTIFIER
| TOK_IDENTIFIER TOK_EQUAL expr
| TOK_PRINTVAR TOK_IDENTIFIER
;
expr:
expr TOK_ADD expr
{
// $$ = $1 + $3;
}
| expr TOK_MUL expr
{
// $$ = $1 * $3;
}
| TOK_NUM_INT
{
// $$ = $1;
}
| TOK_NUM_FLOAT
{
// $$ = $1;
}
;
%%
int yyerror(char *s)
{
printf("\nsyntax error on line no %d\n",yylineno);
return 0;
}
int main()
{
yyparse();
return 0;
}
现在我遇到错误:
已使用符号TOK_MAIN,但未定义为令牌,并且没有 规则编:TOK_MAIN TOK_OPEN_CURLY stmts TOK_CLOSE_CURLY
答案 0 :(得分:0)
The error message is telling you're using a token named TOK_MAIN
, but you never defined a token with that name. And sure enough, if you look at your %token
line, it includes a token named TOK_MAIN_BRACKET
, but not TOK_MAIN
.
So you should either rename it to TOK_MAIN
in your %token
definition or replace the use of TOK_MAIN
with TOK_MAIN_BRACKET
(in which case you should change your lexer accordingly as well).
PS: It is somewhat unusual to lex main()
as a single token. It'd be more common to have main
, (
and )
each be their own token.