types - BISON/FLEX C-Basic没有声明类型错误

标签 types compiler-errors bison

我在这个 flex 野牛项目上遇到麻烦,无法理解为什么我不断收到此错误“未声明类型”。

我的 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:$ 1的`comentario'没有声明的类型

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

谢谢 :)

最佳答案

终端T_COM(该生产中的$1)当然没有声明的类型。此外,尽管野牛看不见它,但扫描程序在返回yylval时从不设置T_COM的任何成员,因此可以说终端确实没有语义值。

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

%token <s> T_COM

假设在%union声明中,标记s指向类似字符串的对象。 (尽管查看您的代码,但看起来也可能是codigo标记。)

关于types - BISON/FLEX C-Basic没有声明类型错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24234761/

相关文章:

python /MyPy : How to annotate a method that can return one of several different types of objects?

types - 在 Clojure 中表示 sum 类型(a b)的惯用方式

c# - 编译和执行单行代码

token - Bison:如果 token 不符合规则,如何忽略它

c++ - 将 float 与参数内的字符串连接起来

c - 如何为错误创建语法规则?

scala - 从返回类型推断泛型隐式参数的类型

types - 系统 F 中的类型示例在 Hindley Milner 类型推断中不可用

python - Python错误中的简单类

java - 为什么我使用@Override 得到 "must override a superclass method"?