问题描述
尝试使用 flex/bison 创建一个简单的编译器,但对于我想要返回的每个标识符,我不断从scanner.l 收到“未声明的标识符”错误消息我在 parser.y 中运行 bison 时收到这些错误消息:
Parser.y:73.10-14: 使用了符号类,但未定义为令牌且无规则
Parser.y:74.34-36:使用了符号 Eof,但未定义为令牌且没有规则
Parser.y:74.23-26:使用了符号 Decl,但未定义为令牌且没有规则
Parser.y:83.33-36:使用了符号类型,但未定义为令牌且没有规则
Parser.y:88.32-39: 使用了符号变量,但未定义为令牌且没有规则
Parser.y:91.25-32: 使用了符号 Argument,但未定义为令牌且没有规则
scanner.l (flex/词法分析器)
%{
#include <iostream>
using std::cout;
using std::endl;
#include "parser.h"
extern "C" int isatty(int);
int col=1;
int lin=1;
%}
%x Comment
%%
[/][/].*\n {lin++; col = 1;}
"int" {col += yyleng; return INTEGER;}
"boolean" {col += yyleng; return BOOL;}
"double" {col += yyleng; return DOUBLE;}
"null" {col += yyleng; return NULLVAL;}
"if" {col += yyleng; return IF;}
"else" {col += yyleng; return ELSE;}
"while" {col += yyleng; return WHILE;}
"for" {col += yyleng; return FOR;}
"true" {col += yyleng; return TRUEFALSE;}
"false" {col += yyleng; return TRUEFALSE;}
"class" {col += yyleng; return CLASS;}
"return" {col += yyleng; return RETURN;}
"new" {col += yyleng; return NEW;}
"static" {col += yyleng; return STATIC;}
"private" {col += yyleng; return PRIVATE;}
"this" {col += yyleng; return THIS;}
"extends" {col += yyleng; return EXTENDS;}
"instanceof" {col += yyleng; return INSTANCEOF;}
"-" {col += yyleng; return SUB;}
"+" {col += yyleng; return ADD;}
"/" {col += yyleng; return DIV;}
"*" {col += yyleng; return MUL;}
"%" {col += yyleng; return MOD;}
"=" {col += yyleng; return *yytext;}
"++" {col += yyleng; return INC;}
"--" {col += yyleng; return DEC;}
"==" {col += yyleng; return EQ;}
"<" {col += yyleng; return SM;}
">" {col += yyleng; return GR;}
"<=" {col += yyleng; return SME;}
">=" {col += yyleng; return GRE;}
"!" {col += yyleng; return NEGATION;}
"&&" {col += yyleng; return AND;}
"||" {col += yyleng; return OR;}
[a-zA-Z_][a-zA-Z_0-9]* {col += yyleng; return ID;}
0|([1-9][0-9]*) {col += yyleng; return NUMBER;}
([0-9]+[\.][0-9]*([eE][-+]?[0-9]+)?) {col += yyleng; return REAL;}
[\t]* {col += 4*yyleng;}
[ ]* {col += yyleng;}
[\n] {col =1; lin++;}
[\(\)\,\{\};=] {
col += yyleng;
return *yytext;
}
"/*" {
BEGIN(Comment);
}
<Comment>"*/" {
BEGIN(INITIAL);
}
<Comment>\n { col = 1; lin++; }
<Comment>. { col += yyleng; }
. {
col += yyleng;
}
%%
int yywrap()
{
return 0;
}
int main()
{
yylex();
return 0;
}
parser.y(野牛语法分析器)
%{
#include<iostream>
using std::cout;
using std::endl;
#include "parser.h"
extern int lin;
extern int col;
int Errs = 0;
extern int yylex();
extern int yyerror(const char *);
extern int yydebug;
extern char* yytext;
extern int yyleng;
extern int errors;
extern int yywrap();
#define YYDEBUG 1
%}
%debug
%token INTEGER
%token BOOL
%token DOUBLE
%token NULLVAL
%token IF
%token ELSE
%token WHILE
%token FOR
%token TRUEFALSE
%token CLASS
%token RETURN
%token NEW
%token STATIC
%token PRIVATE
%token THIS
%token EXTENDS
%token INSTANCEOF
%token SUB
%token ADD
%token DIV
%token MUL
%token MOD
%token INC
%token DEC
%token EQ
%token SM
%token GR
%token SME
%token GRE
%token NEGATION
%token AND
%token OR
%token ID
%token NUMBER
%token REAL
%nonassoc IfStatmentPrec
%nonassoc ELSE
%nonassoc EQ NEQ SM GR GRE SME
%right '='
%left ADD SUB MUL DIV MODULE AND OR NEGATION POS NEG
%start File
%%
File :Class
|File Decl Class Eof
;
CONSTRUCTOR:
| PRIVATE
| STATIC
;
VARIABLES: Type '(' Arguments ')' '{' Insts '}'
;
Insts : Insts Inst
|
;
Variables : Variables ',' Variable
| Variable
;
Arguments : Argument
| Arguments ',' Argument
;
EmptyExpression :
| Expression
;
Inst : Expression ';'
|'{' Insts '}'
|WHILE '(' Expression ')' Inst
|Type Variables ';'
|IF '(' Expression ')' Inst %prec IfStatmentPrec
|IF '(' Expression ')' Inst ELSE Inst
|FOR '(' Type ID '=' Expression ';' EmptyExpression ';' EmptyExpression ')' Inst
|
|RETURN'(' Expression ')' Inst
|Type Variables ';'
|INSTANCEOF'(' Expression ')' Inst
|Type Variables ';'
';'
Expression :
| TRUEFALSE
| BOOL
| REAL
| NULLVAL
| INTEGER
| REAL
| THIS
| SUB Expression %prec NEG
| Expression ADD Expression
| Expression SUB Expression
| Expression DIV Expression
| Expression MUL Expression
| Expression MODULE Expression
| NEGATION Expression
| ID INC
| ID DEC
| ID '=' Expression
| Expression EQ Expression
| Expression NEQ Expression
| Expression SM Expression
| Expression SME Expression
| Expression GR Expression
| Expression GRE Expression
| Expression AND Expression
| Expression OR Expression
| '(' Expression ')'
;
%%
int yyerror(const char* er)
{
cout<<"error in line: " <<lin << " at column "<<col<<" \n";
Errs += 1;
return 1;
}
解决方法
标记“CLASS”被定义为大写,所以你需要这样写。其他标识符甚至都没有声明。