我有 lex 和 yacc 文件。
lex - tokens.l yacc - 表达式.y
我使用 flex 作为 lex,使用 bison 作为 yacc
表达式.y:
%{
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include "../lex/lex.yy.c"
int yylex();
void yyerror(const char *s);
int i=0;
%}
%union {
char *lexeme;
char *value;
char *code;
char *addr;
struct {
char *code;
char *addr;
} exp;
};
%left '+' '-'
%token <lexeme> id
%token <value> LITERAL
%type <code> S
%type <exp> E
%%
S : id '=' E {
char *code = (char *)malloc(sizeof(char) * 100); // Adjust size accordingly
sprintf(code, "%s=%s", $1.lexeme, $3.exp.addr);
$$.code = code;
}
E : E '+' E {
char *temp = (char *)malloc(sizeof(char) * 10); // Adjust size accordingly
sprintf(temp, "t%d", i++);
$$.exp.addr = temp;
char *code = (char *)malloc(sizeof(char) * 100); // Adjust size accordingly
sprintf(code, "%s=%s+%s", $$.exp.addr, $1.exp.addr, $3.exp.addr);
$$.exp.code = code;
}
| '-' E {
char *temp = (char *)malloc(sizeof(char) * 10); // Adjust size accordingly
sprintf(temp, "t%d", i++);
$$.exp.addr = temp;
char *code = (char *)malloc(sizeof(char) * 100); // Adjust size accordingly
sprintf(code, "%s=-%s", $$.exp.addr, $2.exp.addr);
$$.exp.code = code;
}
| '(' E ')' {
$$.exp.addr = $2.exp.addr;
$$.exp.code = $2.exp.code;
}
| id {
$$.exp.addr = $1.lexeme;
$$.exp.code = "";
};
%%
void yyerror(const char *s) {
fprintf(stderr, "Parser error: %s\n", s);
}
int main() {
yyparse(); // Start parsing
return 0;
}
代币.l
%{
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include "../yacc/grammer.tab.h";
typedef struct SymbolTable{
char token[10];
char attr[100];
char type[10];
} SymbolTable;
SymbolTable ST[1000];
int STn=0;
void printST(){
int i;
printf("\nPrinting Symbol Table ");
for(i=0;i<STn;i++){
printf("\n%s : %s",ST[i].token, ST[i].attr);
}
}
int installID(char *a, char *t){
int i;
for(i=0;i<STn;i++){
if((strcmp(ST[i].token, "ID")==0)&&(strcmp(ST[i].attr, a)==0)){
return i;
}
}
strcpy(ST[STn].token,"ID");
strcpy(ST[STn].attr,a);
strcpy(ST[STn].type,t);
STn++;
return STn-1;
}
int installLit(char *b, char *t){
int i;
for(i=0;i<STn;i++){
if((strcmp(ST[i].token, "NUM")==0)&&(strcmp(ST[i].attr, b)==0)){
return i;
}
}
strcpy(ST[STn].token,"LITERAL");
strcpy(ST[STn].attr,b);
strcpy(ST[STn].type,t);
STn++;
return STn-1;
}
%}
id [a-zA-Z_][a-zA-Z_0-9]*
int [-]?[0-9]+
float [-]?[0-9]+([.][0-9]+)?([Ee][+-]?[0-9]+)?
bool "True" | "False"
str (\"([^\"\\\\]|\\\\.)*\")|('([^'\\\\]|\\\\.)*')
%%
%union {
char *lexeme;
char *value;
}
%token <lexeme> ID
{id} {
printf("\nIdentifier : %s ", yytext);
int a = installID(yytext, NULL);
yylval.lexeme = strdup(yytext);
return ID;
}
{int} {printf("\nInteger : %s ",yytext);
int a = installLit(yytext,"INT");
yylval.value = strdup(yytext);
return LITERAL;}
{str} {printf("String ");
int a = installLit(yytext,"STR");
yylval.value = strdup(yytext);
return LITERAL;}
{float} {printf("Float ");
int a = installLit(yytext,"FLOAT");
yylval.value = strdup(yytext);
return LITERAL;}
%%
int yywrap(){
return 1;
}
当我跑步时
flex tokens.l
bison expressions.y
>gcc expressions.tab.c ../lex/lex.yy.c -o myprg && myprg
In file included from expressions.y:5:0:
tokens.l:5:33: warning: extra tokens at end of #include directive
In file included from expressions.y:5:0:
tokens.l: In function 'yylex':
tokens.l:69:1: error: expected expression before '<' token
In file included from expressions.y:5:0:
tokens.l:74:11: error: request for member 'lexeme' in something not a structure or union
In file included from expressions.y:5:0:
tokens.l:80:13: error: request for member 'value' in something not a structure or union
tokens.l:81:14: error: 'LITERAL' undeclared (first use in this function)
tokens.l:81:14: note: each undeclared identifier is reported only once for each function it appears in
In file included from expressions.y:5:0:
tokens.l:85:13: error: request for member 'value' in something not a structure or union
In file included from expressions.y:5:0:
tokens.l:90:13: error: request for member 'value' in something not a structure or union
expressions.y: In function 'yyparse':
expressions.y:32:45: error: request for member 'lexeme' in something not a structure or union
sprintf(code, "%s=%s", $1.lexeme, $3.exp.addr);
^
expressions.y:32:79: error: request for member 'exp' in something not a structure or union
sprintf(code, "%s=%s", $1.lexeme, $3.exp.addr);
^
expressions.y:33:11: error: request for member 'code' in something not a structure or union
$$.code = code;
^
expressions.y:40:11: error: request for member 'exp' in something not a structure or union
$$.exp.addr = temp;
^
expressions.y:43:37: error: request for member 'exp' in something not a structure or union
sprintf(code, "%s=%s+%s", $$.exp.addr, $1.exp.addr, $3.exp.addr);
^
expressions.y:43:70: error: request for member 'exp' in something not a structure or union
sprintf(code, "%s=%s+%s", $$.exp.addr, $1.exp.addr, $3.exp.addr);
^
expressions.y:43:103: error: request for member 'exp' in something not a structure or union
sprintf(code, "%s=%s+%s", $$.exp.addr, $1.exp.addr, $3.exp.addr);
^
expressions.y:44:11: error: request for member 'exp' in something not a structure or union
$$.exp.code = code;
^
expressions.y:49:11: error: request for member 'exp' in something not a structure or union
$$.exp.addr = temp;
^
expressions.y:52:35: error: request for member 'exp' in something not a structure or union
sprintf(code, "%s=-%s", $$.exp.addr, $2.exp.addr);
^
expressions.y:52:68: error: request for member 'exp' in something not a structure or union
sprintf(code, "%s=-%s", $$.exp.addr, $2.exp.addr);
^
expressions.y:53:11: error: request for member 'exp' in something not a structure or union
$$.exp.code = code;
^
expressions.y:56:11: error: request for member 'exp' in something not a structure or union
$$.exp.addr = $2.exp.addr;
^
expressions.y:56:45: error: request for member 'exp' in something not a structure or union
$$.exp.addr = $2.exp.addr;
^
expressions.y:57:11: error: request for member 'exp' in something not a structure or union
$$.exp.code = $2.exp.code;
^
expressions.y:57:45: error: request for member 'exp' in something not a structure or union
$$.exp.code = $2.exp.code;
^
expressions.y:60:11: error: request for member 'exp' in something not a structure or union
$$.exp.addr = $1.lexeme;
^
expressions.y:60:45: error: request for member 'lexeme' in something not a structure or union
$$.exp.addr = $1.lexeme;
^
expressions.y:61:11: error: request for member 'exp' in something not a structure or union
$$.exp.code = "";
^
tokens.l:5:33: warning: extra tokens at end of #include directive
tokens.l: In function 'yylex':
tokens.l:69:1: error: expected expression before '<' token
tokens.l:74:11: error: request for member 'lexeme' in something not a structure or union
tokens.l:80:13: error: request for member 'value' in something not a structure or union
tokens.l:81:14: error: 'LITERAL' undeclared (first use in this function)
tokens.l:81:14: note: each undeclared identifier is reported only once for each function it appears in
tokens.l:85:13: error: request for member 'value' in something not a structure or union
tokens.l:90:13: error: request for member 'value' in something not a structure or union
错误消息中提到的所有成员都在联合体中。但错误仍然存在。我在SO中提到了很多问题,但找不到解决方案
请帮忙
改变
#include "../yacc/grammer.tab.h";
到
#include "../yacc/expressions.tab.h";
有效