2013-03-25 1 views
0

flex와 bison을 사용하여 파서를 작성하려고합니다. 그러나 파일을 수정하는 방법과 상관없이 "1 행의 구문 오류"오류가 항상 나타납니다."줄 : 1 : 오류 : 구문 오류!"를 수정하는 방법

%{ 
#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#include "bool.h" 
#include "parser.h" 
#include "context.h" 
#include "vtl4.tab.h" 

extern FILE * yyin; 
extern FILE * yyout; 
extern int yylex(); 
extern int yywrap(); 
%} 

%union { 
struct simpleNode *ast; 
double d; 
int i; 
bool b; 
char* string; 
struct symbol *sym; 
} 

%type <ast> root stmts stmt 

%token <string> CONTENT 

%token FINAL 

%% 

root:stmts FINAL {printf("root\n");$$ = process($1);traverse($$);} 
; 

stmts: {printf("stmts:stmt\n");$$ = 0;} 
|stmts stmt {printf("stmts:stmts stmt\n");$$ = add_ybrother($1,$2);} 
; 

stmt:CONTENT {printf("stmt\n");$$ = text($1);} 
; 

%% 
int main(){ 
FILE *src; 
src = fopen("test.vm","r"); 
yyin = src; 
yyparse(); 
fclose(src); 
return 1; 
} 

int yywrap(){ 
return 1; 
} 

메이크 :

%{ 
#include<stdio.h> 
#include<string.h> 
#include "context.h" 
#include "bool.h" 
#include "vtl4.tab.h" 
%} 
%% 
(.|\n)* {yylval.string = yytext;return CONTENT;} 
<<EOF>> {return FINAL;} 
%% 

이는 vtl4.y 파일입니다

$asfdfsdf 
sdfsdfs 
sdfsdfsd 
sdfsdfsd 
sfsdfd 

이이 vtl4.l 파일입니다 이 yyinput의 test.vm 파일입니다 :

CC=cc 

FLEX=vtl4.l 

BISON=vtl4.y 

parse:vtl4.tab.c lex.yy.c 
     $(CC) -o out *.c -ll 


vtl4.tab.c:$(BISON) 
     bison -d $(BISON) --report=all 

lex.yy.c:$(FLEX) 
     flex $(FLEX) 
유엔 ./out, 그것은 올바른 결과를 인쇄 할 것이지만, 항상 "라인 : 1 : 오류 : 구문 오류"라고 마침내! 나는 왜 그런지 몰라?

그것은 내가 Yacc에 규칙을

root:stmts FINAL {printf("root\n");$$ = process($1);traverse($$);} 

root:stmts {printf("root\n");$$ = process($1);traverse($$);} 

<<EOF>> {return FINAL;} 

<<EOF>> {yyterminate();} 

에 렉스 규칙을 편집하고 수정할 때 잘 작동

하지만 왜 그런지 모르겠습니다.

답변

2

<<EOF>> 규칙에서 return FINAL을 사용하면 토크 나이저는 파일 끝에서 FINAL을 계속 반환합니다. flexbison과 함께 사용되면 명시 적 파일 끝 토큰을 사용할 필요가 없습니다. 파일 끝에 yylex이 반환하는 0에 의존하십시오. yywrap은 1을 반환합니다. 이는 정확히 yyterminate이 무엇인지 잘 나타내며 그 점이 정상적으로 작동합니다.

이 경우 문법은 처리 할 수없는 토큰 인 FINAL의 무한 스트림과 마주하고 있습니다. 물론 문법은 '정확'하지만 결코 끝나지 않으므로 문법에이 끝없는 흐름을 수용해서는 안됩니다.

tokenizer가 CONTENT 토큰의 전체 파일과 일치한다고 알고 있다고 가정합니다. 따라서 문법이 CONTENT 토큰 목록을 지원하더라도 항상 하나만 표시됩니다.

P.S : 에 -t 옵션을 사용하여 문제를 발견하여 디버거 추적을 파서에 추가하고 두 번째로 FINAL 발생시 숨 막히게하는 것으로 나타났습니다.

P.S2 : Makefile에서 parse에 대한 컴파일러 호출에서 *.c을 사용했습니다. 일부 임의의 .c 파일이 디렉토리에 저장 될 수 있으므로 매우 위험합니다. 규칙이 달려있는 모든 파일을 참조하려면 $^을 사용하는 것이 좋습니다.

P.S3 : yywrapmain을 정의 했으므로 -ll을 잃을 수 있습니다.

관련 문제