flex 및 bison을 사용하여 mini C 언어 용 컴파일러를 작성하고 싶습니다. 여기 Flex/Bison 미니 C 컴파일러 어휘 및 의미 분석 이동/축소 충돌
/* This is an example uC program. */
int fac(int n)
{
if (n < 2)
return n;
return n * fac(n - 1);
}
int sum(int n, int a[])
{
int i;
int s;
i = 0;
s = 0;
while (i < n) {
s = s + a[i];
i = i + 1;
}
return s;
}
int main(void)
{
int a[2];
a[0] = fac(5);
a[1] = 27;
return 0;
}
언어의 이런 종류의 구문 분석하는 내 문법입니다 : 내 언어의 예는 다음과 같을 것이다
program ::= topdec_list
topdec_list ::= /empty/ | topdec topdec_list
topdec ::= vardec ";"
| funtype ident "(" formals ")" funbody
vardec ::= scalardec | arraydec
scalardec ::= typename ident
arraydec ::= typename ident "[" intconst "]"
typename ::= "int" | "char"
funtype ::= typename | "void"
funbody ::= "{" locals stmts "}" | ";"
formals ::= "void" | formal_list
formal_list ::= formaldec | formaldec "," formal_list
formaldec ::= scalardec | typename ident "[" "]"
locals ::= /empty/ | vardec ";" locals
stmts ::= /empty/ | stmt stmts
stmt ::= expr ";"
| "return" expr ";" | "return" ";"
| "while" condition stmt
| "if" condition stmt else_part
| "{" stmts "}"
| ";"
else_part ::= /empty/ | "else" stmt
condition ::= "(" expr ")"
expr ::= intconst
| ident | ident "[" expr "]"
| unop expr
| expr binop expr
| ident "(" actuals ")"
| "(" expr ")"
unop ::= "-" | "!"
binop ::= "+" | "-" | "*" | "/"
| "<" | ">" | "<=" | ">=" | "!=" | "=="
| "&&"
| "="
actuals ::= /empty/ | expr_list
expr_list ::= expr | expr "," expr_list
플렉스 모듈이 잘 작동을하고 원하는대로 값을 반환하지만 들소는 유지 문법 오류가 잘못되었음을 나타내는 이상한 오류를줍니다 (그렇지 않습니다). 여기 내 들소 파일입니다
%{
#include <stdio.h>
#include <stdlib.h>
extern int yylex();
extern int yyparse();
FILE* yyin;
extern int lineNumber;
void yyerror(const char* s);
%}
%union {
int intvalue;
}
%token<intvalue> INTCONST
%token IDENT
%token CHARK
%token ELSEK
%token IFK
%token INTK
%token RETURNK
%token VOIDK
%token WHILEK
%token NOTK
%token ANDK
%token COMMAK
%token DIVIDEK
%token MULTIPLYK
%token MINUSK
%token PLUSK
%token SEMICOLONK
%token NEQUALK
%token EQUALK
%token ASSIGNMENTK
%token RECOMPARATORK
%token LECOMPARATORK
%token RCOMPARATORK
%token LCOMPARATORK
%token RPARANTESESK
%token LPARANTESESK
%token RBRACKETK
%token LBRACKETK
%token RCURLY
%token LCURLY
%right ASSIGNMENTK
%left ANDK
%left EQUALK NEQUALK
%left LCOMPARATORK RCOMPARATORK LECOMPARATORK RECOMPARATORK
%left PLUSK
%left MULTIPLYK DIVIDEK
%left MINUSK NOTK
%start program
%%
program: topdec_list
;
topdec_list: /*empty*/
| topdec topdec_list
;
topdec: vardec SEMICOLONK
| funtype IDENT LPARANTESESK formals RPARANTESESK funbody
;
vardec: scalardec
| arraydec
;
scalardec: typename IDENT
;
arraydec: typename IDENT LBRACKETK INTCONST RBRACKETK
;
typename: INTK
| CHARK
;
funtype: typename
| VOIDK
;
funbody: LCURLY locals stmts RCURLY
| SEMICOLONK
;
formals: VOIDK
| formal_list
;
formal_list: formaldec
| formaldec COMMAK formal_list
;
formaldec: scalardec
| typename IDENT LBRACKETK RBRACKETK
;
locals: /*empty*/
| vardec SEMICOLONK locals
;
stmts: /*empty*/
| stmt stmts
;
stmt: expr SEMICOLONK
| RETURNK expr SEMICOLONK
| RETURNK SEMICOLONK
| WHILEK condition stmt
| IFK condition stmt else_part
| LCURLY stmts RCURLY
| SEMICOLONK
;
else_part: /*empty*/ | ELSEK stmt
;
condition: LPARANTESESK expr RPARANTESESK
;
expr: INTCONST
| IDENT
| IDENT LBRACKETK expr RBRACKETK
| unop expr
| expr binop expr
| IDENT LPARANTESESK actuals RPARANTESESK
| LPARANTESESK expr RPARANTESESK
;
unop: MINUSK | NOTK
;
binop: PLUSK
| MINUSK
| MULTIPLYK
| DIVIDEK
| LCOMPARATORK
| RCOMPARATORK
| LECOMPARATORK
| RECOMPARATORK
| NEQUALK
| EQUALK
| ANDK
| ASSIGNMENTK
;
actuals: /*empty*/
| expr_list
;
expr_list: expr
| expr COMMAK expr_list
;
%%
int main(int argc, char **argv)
{
yyin = fopen("input.c", "r");
do
{
yyparse();
} while (!feof(yyin));
fclose(yyin);
return 0;
}
void yyerror(const char* error)
{
fprintf(stderr, "Parse error in line %d: %s\n", lineNumber, error);
}
이 입력에 대한 예 :
int i;
i = 0;
내가 구문 오류가 두 번째 i
가 (난 내 플렉스에서 토큰을 인쇄 구별 직후에 일어난 오류가 파일 그래서 할당 문자에 도달 할 때까지 아무런 문제가 없다는 것을 압니다.)
또는 다른 예로서
이 광고 통과했을 때int fac(int n);
난이 구문 오류와 제
int
을 보는 것을 의미 오른쪽 제 paranteses 후 (정확하게
Parse error in line 1: syntax error
임) 동일한 구문 오류를 그것은 내 문법이 잘 보이기 때문에해서는 안됩니다. 다음
는 또한 들소 의해 생성 된 경고는 (플렉스 GCC 괜찮지)
semantic_analyzer.y: warning: 26 shift/reduce conflicts [-Wconflicts-sr]
semantic_analyzer.y:78.10-17: warning: rule useless in parser due to conflicts [-Wother]
funtype: typename
^^^^^^^^
제안이나 수정은 미리 감사 :) 이해된다.
파서를 생성 할 때 yacc/bison에 의해 생성 된 경고는 언급하지 않았습니다. – rici
감사합니다. @rici 방금 추가했습니다. – Mazhar