我在这个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-我刚刚复制了与错误相关的代码部分,其余的似乎工作正常
谢谢:)
答案 0 :(得分:1)
终端T_COM
(该生产中的$1
)当然没有声明的类型。此外,虽然它对野牛是不可见的,但是当它返回yylval
时,扫描器从不设置T_COM
的任何成员,所以似乎可以公平地说终端确实没有语义值。
使用$1
作为与printf
格式对应的%s
的参数表明您希望它具有字符串类型。如果是,则需要将类型标记添加到%token
声明,和,确保在扫描程序中设置yylval
的相应成员。
%token
声明看起来像这样:
%token <s> T_COM
假设在%union
声明中,标记s
引用了类似字符串的对象。 (虽然查看代码,但它似乎也可以是codigo
标记。)