flex 및 bison을 사용하여 간단한 스크립트 파일을 구문 분석하기 위해 스캐너 및 구문 분석기를 작성하려고합니다. 스크립트 파일의 첫 번째 행만 구문 분석 할 수 있습니다. 그런 다음 프로그램은 'yyerror : syntax error'오류로 종료됩니다. 내 프로그램이 스크립트의 다음 줄로 진행하도록하려면 어떻게해야합니까?Flex 및 Bison : 전체 스크립트 파일을 구문 분석 할 수 없습니다.
아래의 컴파일 옵션으로 Window7을 사용하고 있습니다.
편집 :
flex lex.l
bison -d yacc.y
g++ lex.yy.c yacc.tab.c -lfl -o scanner.exe
여기
나는 .Y 파일 내 Script.txt를 파일을 .L 부착하고있다.
파일 : lex.l
%{
#include <iostream>
#include <stdio.h>
#include "yacc.tab.h"
#define YY_DECL extern "C" int yylex()
using namespace std;
%}
DOT "."
COLON ":"
SEMICOLON ";"
COMMA ","
ANGLE_LEFT "<"
ANGLE_RIGHT ">"
AT "@"
EQUAL "="
SQUARE_OPEN "["
SQUARE_CLOSE [^\\]"]"
OPENBRACE "\("
CLOSEBRACE "\)"
QUOTE "\""
QUOTE_OPEN "\""
QUOTE_CLOSE [^\\]"\""
SPACE " "
TAB "\t"
CRLF "\r\n"
QUOTED_PAIR "\\"[^\r\n]
DIGIT [0-9]
ALPHA [a-zA-Z]
QTEXT [0-9a-zA-Z!#$%&'()*+,\-.\/:;<=>[email protected]\[\]^_`{|}~]
%%
{SPACE}*{OPENBRACE}{SPACE}* { return TOK_OPENBRACE; }
{SPACE}*{CLOSEBRACE}{SPACE}* { return TOK_CLOSEBRACE; }
{SPACE}*{SEMICOLON}{SPACE}* { return TOK_SEMICOLON; }
{SPACE}*{COMMA}{SPACE}* { return TOK_COMMA; }
{QUOTE_OPEN}({SPACE}*{QTEXT}*{QUOTED_PAIR}*)*{QUOTE_CLOSE} {
yylval.sval = &yytext[1];
yylval.sval[strlen(yylval.sval) - 1] = '\0';
return TOK_QUOTED_STRING;
}
{DIGIT}+ {
yylval.lval = atoi(yytext);
return TOK_LONG;
}
"true"|"false" {
yylval.ival = ((0 == strcmp(yytext, "true")) ? 1 : 0);
return TOK_BOOL;
}
^"function1" { return TOK_FUNC1; }
^"function2" { return TOK_FUNC2; }
^"function3" { return TOK_FUNC3; }
^{CRLF} { return TOK_EMPTY_LINE; }
{CRLF} {}
. {}/* ignore unknown chars */
파일 : yacc.y
%{
#include <iostream>
#include <stdio.h>
using namespace std;
extern "C" int yylex();
extern "C" FILE *yyin;
int yyerror(const char *s);
%}
// Symbols.
%union
{
char *sval;
long lval;
int ival;
};
%token TOK_FUNC1
%token TOK_FUNC2
%token TOK_FUNC3
%token <sval> TOK_QUOTED_STRING
%token <lval> TOK_LONG
%token <ival> TOK_BOOL
%token TOK_SEMICOLON
%token TOK_OPENBRACE
%token TOK_CLOSEBRACE
%token TOK_COMMA
%token TOK_EMPTY_LINE
%start program
%%
program : func1
| func2
| func3
| empty_line
;
func1 : TOK_FUNC1 TOK_OPENBRACE TOK_QUOTED_STRING TOK_COMMA TOK_LONG TOK_COMMA TOK_BOOL TOK_CLOSEBRACE TOK_SEMICOLON
{
cout << "function1:" << $3 << " " << $5 << " " << $7;
}
func2 : TOK_FUNC2 TOK_OPENBRACE TOK_QUOTED_STRING TOK_COMMA TOK_LONG TOK_COMMA TOK_BOOL TOK_CLOSEBRACE TOK_SEMICOLON
{
cout << "function2:" << $3 << " " << $5 << " " << $7;
}
func3 : TOK_FUNC3 TOK_OPENBRACE TOK_QUOTED_STRING TOK_COMMA TOK_LONG TOK_COMMA TOK_BOOL TOK_CLOSEBRACE TOK_SEMICOLON
{
cout << "function3:" << $3 << " " << $5 << " " << $7;
}
empty_line : TOK_EMPTY_LINE
{
}
%%
int yyerror(const char *s) {
cout << "yyerror : " << s << endl;
}
int main(void) {
FILE * pt = fopen("script.txt", "r");
yyin = pt;
yyparse();
}
파일 : Script.txt를
function1("scanner1", 1234, true);
function2("scanner2", 4321, false);
function3("scanner3", 0123, true);
출력 :
function1:scanner1 1234 1
yyerror : syntax error
예상 출력 :
function1:scanner1 1234 1
function2:scanner2 4321 0
function3:scanner3
만 덕분에 (이 bison FAQ entry 참조). 나는 그것을 고쳤다. 당신이 말했듯이 '\ r \ n'은 '\ n'과 'yytext'로 대체되어야 'sval'에 덤프됩니다. – Sandy