BISON / FLEX C-Basic无声明类型错误

时间:2014-06-15 22:42:42

标签: types compiler-errors bison

我在这个flex bison项目上遇到麻烦,无法理解为什么我一直收到这个错误"没有声明类型" ..

我的flex文件

%token T_COM



%type <codigo> ficheiro
%type <codigo> idents
%type <codigo> comentario
%type <codigo> def_consts def_const def_vars def_var
%type <codigo> def_function tipo main bloco blocoSemMAin
%type <codigo> statements statement statementsSemMain
%type <codigo> valores_const valor_const expr

%type <i> const_integer_expr
%type <d> const_real_expr
%type <i> const_boolean_expr
%type <s> const_string_expr


%%

ficheiro
:   def_vars def_function                       { printf( "%s %s\n",$1, $2); }
|   def_vars                                    { printf( "%s\n",$1); }
|   def_function                                { printf( "%s\n", $1 );}
|   comentario                                  { printf( "%s\n", $1 );}
;

comentario
:   T_COM                                                   { sprintf( $$,"REM %s ",$1);}
;

这就是我在野牛中宣称的方式

%option noyywrap nounput case-insensitive yylineno
  #include <assert.h>
  #include <stdlib.h>
  #include <string.h>
  #include "consts.h"

  /* Estamos a usar %union, pelo que NAO repetimos a definicao nem da %union,
     nem de YYSTYPE, aqui. */

  /* Incluir as definicoes criadas automaticamente pelo
     bison, e exportadas por este para um ficheiro ".h"
  */
  #include "pascal.tab.h"


%x COMENTARIO


%%




Uses        return T_USES;
In      return T_IN;
Label       return T_LABEL;
Var     return T_VAR;
Const       return T_CONST;
int     return T_INTEGER;
double      return T_REAL;
Boolean     return T_BOOLEAN;
char        return T_CHAR;
String      return T_STRING;
Procedure   return T_PROCEDURE;
Function    return T_FUNCTION;
"{"         return T_BEGIN;
"END"         return T_END; // não dava para alterar estava sempre a dar erro
if          return T_IF;
Then        return T_THEN;
else        return T_ELSE;
Case        return T_CASE;
Of      return T_OF;
while       return T_WHILE;
do      return T_DO;
Repeat      return T_REPEAT;
Until       return T_UNTIL;
For     return T_FOR;
To      return T_TO;
DownTo      return T_DOWNTO;
Goto        return T_GOTO;
main        return T_MAIN;
void        return T_VOID;
True        return T_TRUE;
False       return T_FALSE;

"(" T_ABRE;
")" T_FECHA;

":="        return T_ASSIGN;
"<="        return T_LESS_EQ;
">="        return T_GREAT_EQ;
"!="        return T_NOT_EQ;
"=="        return T_EQ;
"&&"        return T_AND;
"||"        return T_OR;
"*"         return T_STAR;
"++"        return T_INCRE;
"--"        return T_DECR;
"!"     return T_NOT;
Div     return T_DIV;
Mod     return T_MOD;
Ord     return T_ORD;
Chr     return T_CHR;

"strcpy" return T_STRCOPY;
"strcat" return T_STRCAT;
"strcmp" return T_STRCMP;

"/*"([^*]|[*]+[^/])*[*]+[/]   {

    return T_COM; }

[0-9]+      {
        /* repara como nao tem sinal ao inicio: ve^ "expr" no Bison */
        yylval.i = atoi( yytext );
        return V_INTEGER;
        }

([0-9]+([.][0-9]*)?|[.][0-9]+)([Ee][+-]?[0-9]+)?  {
        /* repara como nao tem sinal ao inicio: ve^ "expr" no Bison */
        yylval.d = atof( yytext );
        return V_REAL;
        }

'[^']{0,255}'   {
        #if MAX_STR_LEN != 255
        #error "Por favor atualize a expressao regular acima para refletir o novo valor de MAX_STR_LEN"
        #endif
        strncpy( yylval.s, yytext+1, MAX_STR_LEN );
        yylval.s[ strlen(yylval.s)-1 ] = '\0';
        return V_STRING;
        }

[a-zA-Z_][a-zA-Z0-9_]{0,31}  {
        #if MAX_IDENT_LEN != 32
        #error "Por favor atualize a expressao regular acima para refletir o novo valor de MAX_IDENT_LEN"
        #endif
        yylval.pci = encontrar_integer_const( yytext );
        if( yylval.pci != NULL )
            return V_INTEGER_CONST;
        yylval.pcr = encontrar_real_const( yytext );
        if( yylval.pcr != NULL )
            return V_REAL_CONST;
        yylval.pcb = encontrar_boolean_const( yytext );
        if( yylval.pcb != NULL )
            return V_BOOLEAN_CONST;
        yylval.pcs = encontrar_string_const( yytext );
        if( yylval.pcs != NULL )
            return V_STRING_CONST;
        #if MAX_STR_LEN < MAX_IDENT_LEN
        #error "Nao consigo (sempre) guardar um identificador dentro de uma string: por favor verifique o codigo e corrija"
        #endif
        strcpy( yylval.s, yytext );
        return V_IDENT;
        }

[-+*/()<>=,;:.] return (int) yytext[0];  /* tokens de um so' caracter */

[ \t\r\n]+                         /* ignorar */
[{][^}]*[}]                        /* ignorar */


.       fprintf( stderr, "Caracter invalido na linha %d: '%c'\n", yylineno, yytext[0] );


%%


void inicia_flex( const char *filename )
{
    FILE *fp;

    if( filename != NULL )
        {
        fp = fopen( filename, "r" );
        if( fp == NULL )
            fprintf( stderr, "Ficheiro \"%s\" nao encontrado: a ler do teclado.\n", filename );
        else
            yyrestart( fp );
        }
}

void termina_flex( void )
{
    fclose( yyin );
}

所以我的错误是,如果我尝试制作这个项目,我会在

上出错
:   T_COM                                                   { sprintf( $$,"REM %s ",$1);}

它说:pascal.y:172.85-86:$ comentario&#39;没有声明的类型

PS-我刚刚复制了与错误相关的代码部分,其余的似乎工作正常

谢谢:)

1 个答案:

答案 0 :(得分:1)

终端T_COM(该生产中的$1)当然没有声明的类型。此外,虽然它对野牛是不可见的,但是当它返回yylval时,扫描器从不设置T_COM的任何成员,所以似乎可以公平地说终端确实没有语义值。

使用$1作为与printf格式对应的%s的参数表明您希望它具有字符串类型。如果是,则需要将类型标记添加到%token声明,,确保在扫描程序中设置yylval的相应成员。

%token声明看起来像这样:

%token <s> T_COM

假设在%union声明中,标记s引用了类似字符串的对象。 (虽然查看代码,但它似乎也可以是codigo标记。)