저는 Lex와 Yacc을 처음 사용하고 있으며 간단한 산술 및 동등한 표현식을 허용하는 간단한 구문 분석기를 만들려고합니다. 일부는 작동하지만, 바이너리 연산과 관련된 표현식을 파싱 할 때 오류가 발생합니다. 여기 내 .y
파일입니다이진 연산자를 사용하는 표현식을 구문 분석 할 때 Yacc 및 Lex 오류가 발생했습니다.
%{
#include <stdlib.h>
#include <stdio.h>
%}
%token NUMBER
%token HOME
%token PU
%token PD
%token FD
%token BK
%token RT
%token LT
%left '+' '-'
%left '=' '<' '>'
%nonassoc UMINUS
%%
S : statement S { printf("S -> stmt S\n"); }
| { printf("S -> \n"); }
;
statement : HOME { printf("stmt -> HOME\n"); }
| PD { printf("stmt -> PD\n"); }
| PU { printf("stmt -> PU\n"); }
| FD expression { printf("stmt -> FD expr\n"); }
| BK expression { printf("stmt -> BK expr\n"); }
| RT expression { printf("stmt -> RT expr\n"); }
| LT expression { printf("stmt -> LT expr\n"); }
;
expression : expression '+' expression { printf("expr -> expr + expr\n"); }
| expression '-' expression { printf("expr -> expr - expr\n"); }
| expression '>' expression { printf("expr -> expr > expr\n"); }
| expression '<' expression { printf("expr -> expr < expr\n"); }
| expression '=' expression { printf("expr -> expr = expr\n"); }
| '(' expression ')' { printf("expr -> (expr)\n"); }
| '-' expression %prec UMINUS { printf("expr -> -expr\n"); }
| NUMBER { printf("expr -> number\n"); }
;
%%
int yyerror(char *s)
{
fprintf (stderr, "%s\n", s);
return 0;
}
int main()
{
yyparse();
}
그리고 여기 렉스에 대한 내 .l
파일입니다
%{
#include "testYacc.h"
%}
number [0-9]+
%%
[ ] { /* skip blanks */ }
{number} { sscanf(yytext, "%d", &yylval); return NUMBER; }
home { return HOME; }
pu { return PU; }
pd { return PD; }
fd { return FD; }
bk { return BK; }
rt { return RT; }
lt { return LT; }
%%
내가 평가에 대한 명령 줄에 연산 식을 입력하려고, 다음과 같은 결과 오류 :
home
stmt -> HOME
pu
stmt -> PU
fd 10
expr -> number
fd 10
stmt -> FD expr
expr -> number
fd (10 + 10)
stmt -> FD expr
(expr -> number
+stmt -> FD expr
S ->
S -> stmt S
S -> stmt S
S -> stmt S
S -> stmt S
S -> stmt S
syntax error
고맙습니다. 어떤 이유로,'+'등이 인용 되었기 때문에, 그들은 yacc에서 어떻게 든 특별한 '프리미티브'연산자였습니다. – dtg
그들은 yacc에 있습니다. 그래서 char 값을 반환하는 것이 효과적이므로 % TOKEN을 정의 할 필요가 없습니다. 그러나 그들은 lex/flex에서 특별하지 않습니다. – EJP
나는 그들이 올바르게 해석 할 수 있도록, 먼저 Lex에서 토큰으로 정의 될 필요가있다. – dtg