ISO c++禁止没有类型的' Expresion '声明

时间:2021-09-25 15:46:37

I'am writing a small compiler for a college compilers subject practice and i when i try to compile my program it says :

我为大学的编译器编写了一个小的编译器课程实践当我试着编译我的程序时它说:

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

Here i give you line 2 from lexer.l file :

这里我给你列克星的第2行。l文件:

#include "parser.tab.h++"

and line 21 from parser.y++.

第21行来自parser.y+。

Expresion *exp;

note: "parser.tab.h++" is generated from "parser.y++" using bison.

注:“parser.tab。h++"是由“解析器”生成的。使用野牛y + +”。

I'am using Flex and Bison GNU tools to generate lexical and grammar analyzers. Here i give you the entire lexer.l file

我使用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();}
}   

%%

The parser.y++ file

解析器。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);
}

The Expresion class is declared in file "codigo.h" :

Expresion类被声明在文件“go”中。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();            
};

and my makefile :

和我的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

I do not see the problem as i used to code in JAVA.

我不像以前那样在JAVA中编写代码。

2 个解决方案

#1


1  

It seems, you need a ; after the definition of the union.

看起来,你需要一个;在联盟的定义之后。

#2


1  

I found that the problem happens if i use a class that i created, MyClass for example in %union definition in the bison's grammar definition file and after that i include the grammar.tab.h generated with bison in another source file (lexer.l in my case) where Myclass isn't a defined type.

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

There ara two solutions :

有两种解决方案:

  • Include MyClass.h in the file where needed, for example if i include grammar.tab.h in lexer.l, i have to include MyClass.h too in lexer.l
  • 包括MyClass。h在需要的文件中,例如如果我包含grammar.tab。h在词法分析程序。l,我得包括我的课。在lexer.l h太
  • Use the %code directive with requires option :

    使用%代码指令与需求选项:

    %code requires{ class MyClass; }

    %的代码需要{ MyClass类;}

#1


1  

It seems, you need a ; after the definition of the union.

看起来,你需要一个;在联盟的定义之后。

#2


1  

I found that the problem happens if i use a class that i created, MyClass for example in %union definition in the bison's grammar definition file and after that i include the grammar.tab.h generated with bison in another source file (lexer.l in my case) where Myclass isn't a defined type.

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

There ara two solutions :

有两种解决方案:

  • Include MyClass.h in the file where needed, for example if i include grammar.tab.h in lexer.l, i have to include MyClass.h too in lexer.l
  • 包括MyClass。h在需要的文件中,例如如果我包含grammar.tab。h在词法分析程序。l,我得包括我的课。在lexer.l h太
  • Use the %code directive with requires option :

    使用%代码指令与需求选项:

    %code requires{ class MyClass; }

    %的代码需要{ MyClass类;}