문제
이 파일에서 Bison을 실행합니다:
%{
#include <iostream>
int yylex();
void yyerror(const char*);
%}
%union
{
char name[100];
int val;
}
%token NUM ID
%right '='
%left '+' '-'
%left '*'
%%
exp : NUM {$$.val = $1.val;}
| ID {$$.val = vars[$1.name];}
| exp '+' exp {$$.val = $1.val + $3.val;}
| ID '=' exp {$$.val = vars[$1.name] = $3.val;}
;
%%
다음과 같은 경고가 발생합니다.
경고:$$의 'exp'에는 선언된 유형이 없습니다.
이는 무엇을 의미하며 어떻게 해결합니까?
해결책
정의 된 Union (%Union)은 직접 사용하기위한 것이 아닙니다. 오히려, 당신은 어떤 표현에 의해 어떤 노조의 구성원이 사용되는지 Bison에게 말해야합니다.
이것은 이루어집니다 %유형 지침.
코드의 고정 된 버전은 다음과 같습니다.
%{
#include <iostream>
int yylex();
void yyerror(const char*);
%}
%union
{
char name[100];
int val;
}
%token NUM ID
%right '='
%left '+' '-'
%left '*'
%type<val> exp NUM
%type<name> ID
%%
exp : NUM {$$ = $1;}
| ID {$$ = vars[$1];}
| exp '+' exp {$$ = $1 + $3;}
| ID '=' exp {$$ = vars[$1] = $3;}
;
%%
다른 팁
추가로 생각해보면, 감소를 보다 명확하게 하고 싶다면(AST 주석을 수행하는 경우 이것이 편리할 수 있음) 스택 값 포인터를 만든 다음 유형 값을 직접 처리할 수 있습니다.다음과 같은 스칼라 유형과 매우 유사합니다.
struct myScalar {
union {
int num;
char *id;
char *float_lexeme;
}payload;
enum {
TYPE_NUM,
TYPE_IDENTIFIER,
TYPE_FLOAT_CHAR
} type;
char *orig_lexeme;
};
그리고 typedef가 있고 scalar_val *val
스택을 위해.
더 복잡한 컴파일러 프런트엔드로 이동할 때 이와 같이 AST를 구축하면 트리를 탐색할 때 더 나은 메타데이터를 얻을 수 있고 사전 의미 유형에 대한 번역을 통해 번역을 늘릴 수도 있습니다.그런 다음 어휘소를 올바른 스칼라 페이로드로 섞기 위해 ID와 같은 리프 생성으로 귀결됩니다.
완전한 설명은 아니지만 아이디어를 얻을 수 있습니다.
이것이 귀하의 향후 Bison/Lex 프런트엔드 및 ...에 도움이 되기를 바랍니다.
행운을 빌어요
제휴하지 않습니다 StackOverflow