我正在为大学编译器学科实践编写一个小型编译器,当我尝试编译我的程序时它说:
In file included from lexer.l:2:
parser.y++:21: error: ISO C++ forbids declaration of ‘Expresion’ with no type
parser.y++:21: error: expected ‘;’ before ‘*’ token
make: *** [principal] Error 1
在这里,我给你来自 lexer.l 文件的第 2 行:
#include "parser.tab.h++"
和 parser.y++ 的第 21 行。
Expresion *exp;
注意:“parser.tab.h++”是使用野牛从“parser.y++”生成的。
我正在使用 Flex 和 Bison GNU 工具来生成词汇和语法分析器。这里我给你整个 lexer.l 文件
%{
#include "parser.tab.h++"
int lineaComentario;
extern bool errorFlag;
#define POSICION \
yylloc.last_line = 1; \
%}
digito [0-9]
letra [a-zA-Z]
entero {digito}+
%x COMENTARIO_TIPO1 COMENTARIO_TIPO2
%%
[ \t]+ ;
\n { yylloc.last_line++; }
"//"(.*)[\n] yylloc.last_line++; /* Comentarios de una sola linea */
program return PROGRAM;
var return VAR;
integer return INTEGER;
begin return BEGINN;
end return END;
if return IF;
then return THEN;
else return ELSE;
while return WHILE;
do return DO;
print return PRINT;
({letra}|_)({letra}|{digito}|_)* {if (yyleng > 16){printf("***ERROR,\n el identificador : %s en linea : %d excede 16 caracteres\n",yytext,yylloc.last_line);errorFlag=true;yytext[16]='\0';};yylval.cadena=strdup(yytext);return ID;}
{entero} {yylval.numero=atoi(yytext);if ((yyleng!=1)&&((atoi(yytext)>32767)||(yytext[0]=='0'))){printf("***ERROR,\n el entero : %s en linea : %d esta fuera de rango u empieza con cero \n",yytext,yylloc.last_line);};errorFlag=true; return INTLITERAL;}
"(" return LPAREN;
")" return RPAREN;
";" return SEMICOLON;
"," return COMMA;
":=" return ASSIGNOP;
"+" return PLUSOP;
"*" return MULTOP;
"-" return MINUSOP;
"/" return DIVOP;
"." return POINT;
":" return TWO_POINTS;
\"[^"\n]*\" {yylval.cadena=strdup(yytext);return STR;}
\"[^"\n]*$ {printf("***ERROR,\n cadena sin cerrar en linea : %d\n",yylloc.last_line);yylloc.last_line++;errorFlag=true;}
"(*" {BEGIN(COMENTARIO_TIPO1);lineaComentario=yylloc.last_line;}
"{" {BEGIN(COMENTARIO_TIPO2);lineaComentario=yylloc.last_line;}
[^[:alnum:]();,:+*/.{}"_\n-]+ {printf("***ERROR,\n la siguiente secuencia de simbolos : %s en la linea : %d no ha sido reconocida :\n",yytext,yylloc.last_line);errorFlag=true;} /* Modo panico */
<COMENTARIO_TIPO1>{
[^*]* ; /* Cualquier cosa que no es '*' */
"*"+[^)] ; /* '*' no seguida de ')' */
"*"+")" BEGIN(0); /* con "*)" se acaba modo comentario tipo 1 */
/* En caso de llegar al fin de fichero */
<<EOF>> {printf("***ERROR,\n comentario sin cerrar. linea : %d \n",yylloc.last_line);errorFlag=true;yyterminate();}
}
<COMENTARIO_TIPO2>{
[^}]* ; /* Cualquier cosa que no es '}' */
"}" BEGIN(0); /* con '}' se acaba modo comentario tipo 2 */
<<EOF>> {printf("***ERROR,\n comentario sin cerrar, linea : %d \n",lineaComentario);errorFlag=true;yyterminate();}
}
%%
parser.y++ 文件
%{
#include <stdio.h>
#include "codigo.h"
#include"tablaSimbolos.h++"
#include <sstream>
extern bool errorFlag;
extern int yylex(void);
string intToSTR(int num);
void yyerror(char *error);
TablaSimbolos tabla;
int dir = 1;
int despl = 0;
%}
%locations
%union{
char *cadena;
int numero;
Expresion *exp;
}
%type <exp> expression term factor
%token PROGRAM LPAREN RPAREN SEMICOLON POINT VAR TWO_POINTS COMMA INTEGER ASSIGNOP IF THEN ELSE WHILE DO PRINT PLUSOP MINUSOP MULTOP DIVOP BEGINN END
%token <numero> INTLITERAL
%token <cadena> STR
%token <cadena> ID
%%
program : PROGRAM ID LPAREN RPAREN SEMICOLON declarations compound_statement POINT
{}
;
declarations: declarations VAR identifier_list TWO_POINTS type SEMICOLON
{}
|
;
identifier_list: ID {
Simbolo *aux = tabla.buscaSimbolo($1);
if(aux!=NULL){
errorFlag = true;
printf("***ERROR, variable %s en linea : %d esta previamente declarada\n",$1,@1.last_line);
}else{
Simbolo *nuevo =new Simbolo($1,despl,true);
despl+=4;
tabla.nuevoSimbolo(nuevo);
}
free($1);
}
| identifier_list COMMA ID{
Simbolo *aux = tabla.buscaSimbolo($3);
if(aux!=NULL){
errorFlag = true;
printf("***ERROR, variable %s en linea : %d esta previamente declarada\n",$3,@1.last_line);
}else{
Simbolo *nuevo =new Simbolo($3,despl,true);
despl+=4;
tabla.nuevoSimbolo(nuevo);
}
free($3);
}
;
type : INTEGER
{}
;
compound_statement : BEGINN optional_statements END
{}
;
optional_statements : statement_list
{}
|
;
statement_list : statement
{}
| statement_list SEMICOLON statement
{}
;
statement : ID ASSIGNOP expression{
Simbolo *aux = tabla.buscaSimbolo($1);
if(aux==NULL){
errorFlag = true;
printf("***ERROR, la variable %s en linea : %d no ha sido declarada previamente \n",$1,@1.last_line);
}
free($1);
}
| compound_statement
{}
| IF expression THEN statement ELSE statement
{}
| IF expression THEN statement
{}
| WHILE expression DO statement
{}
| PRINT print_list
{}
;
print_list : print_item
{}
| print_list COMMA print_item
{}
;
print_item : expression
{}
| STR{
Simbolo *aux = tabla.buscaSimbolo($1);
if(aux==NULL){ // si existe y como es cadena dejar anterior
Simbolo *nuevo =new Simbolo($1,dir,false);
dir++;
tabla.nuevoSimbolo(nuevo);
}
}
;
expression : expression PLUSOP term
{}
| expression MINUSOP term
{}
| term
{}
;
term : term MULTOP factor
{}
| term DIVOP factor
{}
| factor
{$$ = $1}
;
factor : MINUSOP factor
{
$$ = new Expresion(""); // new Temp()
$$->concatenar($2);
Cuadrupla *c = new Cuadrupla("SUB","0",$2->getResult(),$$->getResult());
$$->concatenar(c)
}
| LPAREN expression RPAREN
{ $$ = $2; } // copia
| ID{
Simbolo *aux = tabla.buscaSimbolo($1);
if(aux==NULL) {
errorFlag = true;
printf("***ERROR, no se ha declarado la variable %s en linea : %d\n",$1,@1.last_line);
}else
$$ = new Expresion($1);
}
| INTLITERAL
{ $$ = new Expresion(intToSTR($1)); }
;
%%
string intToSTR(int num){
stringstream ss;
ss << num;
return ss.str();
}
void yyerror(char *error) {
printf("%s!\n",error);
}
表达式类在文件 "codigo.h" 中声明:
#include <string>
#include <list>
using namespace std;
class Cuadrupla{
private:
string op;
string arg1;
string arg2;
string res;
public:
Cuadrupla(string op, string arg1, string arg2, string res);
void toString();
string getResult();
};
class Expresion{
private:
list<Cuadrupla *> codigo;
string result;
public:
string getResult();
Expresion(string result);
void concatenar(Expresion *exp);
void concatenar(Cuadrupla *cuad);
void toString();
};
class Sentencia{
private:
list<Cuadrupla *> codigo;
public:
Sentencia();
void concatenar(Expresion *exp);
void concatenar(Cuadrupla *cuad);
void concatenar(Sentencia *sent);
void toString();
};
和我的makefile:
principal: principal.c++ tablaSimbolos.c++ parser.tab.c++ lex.yy.c
g++ -Wno-write-strings principal.c++ tablaSimbolos.c++ parser.tab.c++ lex.yy.c -lfl -o miniPascal
parser.tab.c++ parser.tab.h++: parser.y++
bison -d parser.y++
lex.yy.c: lexer.l
flex lexer.l
clear:
rm -f lex.yy.c parser.tab.c++ parser.tab.h++ miniPascal
我没有看到我以前在 JAVA 中编码的问题。