2012-07-17 87 views
1

型我'写一个小的编译器为大专编译器主题实践,我当我尝试编译我的程序,它说:ISO C++禁止“Expresion”的声明没有

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 

这里我给大家line 2 from lexer.l file:

#include "parser.tab.h++" 

and line 21 from parser.y ++。

Expresion *exp; 

注意:“parser.tab.h ++”是使用bison从“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); 
} 

的Expresion类文件 “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();    
}; 

和我的生成文件:

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编码。

+0

我删除了Adobe Flex标签并用gnu-flex替换了它。 – JeffryHouser 2012-07-17 19:57:02

+0

注意:已经回滚了一个打破现有代码的编辑(由于没有明显的原因,标记“Expresion”的拼写被改变了) – 2015-06-05 09:08:52

回答

1

我发现如果我使用我创建的类MyClass,例如在Bison的语法定义文件中的%union定义中发生问题,然后我将包含在另一个源文件中使用bison生成的grammar.tab.h (在我的情况下lexer.l)其中Myclass不是一个定义的类型。

ARA有两种解决方案:

  • 包括MyClass.h在需要的文件中,例如,如果我包括lexer.l grammar.tab.h,我在词法分析器包括MyClass.h太.L
  • 使用%的代码指令有需要的选项:

    %的代码需要{ MyClass类; }

1

看来,你需要一个;后定义的联合。

+0

它没有解决问题 – 2012-07-17 20:03:19

+0

不像在C中创建联合声明,您不需要编写在野牛的%union声明中的右括号之后的分号,所以它是别的。 – 2012-07-17 20:48:26

+0

对不起......只是在黑暗中拍摄这里;-)还有一个:BEGINN是lexer.l中的拼写错误吗? – steffen 2012-07-17 21:55:15

相关问题