2017-01-07 18 views
1

flex 및 bison을 사용하는 단순화 된 Python 3에 대한 파서를 작성해야하며이 두 가지 오류가 발생합니다. 터미널에 78 번째 줄의 79 번째 줄이 있다고합니다. 쓰여졌습니다. 내가 포맷의 종류와 클래스에서 다른 '.L'의 예를 가지고 있고 잘 작동FLEX에서 '인식 할 수없는 규칙'및 '치명적인 구문 분석 오류'

이 내가

%option noyywrap 

%{ 
#define YYSTYPE double 
#include "scanner.tab.h" 
#include <stdlib.h> 
#include <string> 

extern int flag; 
extern int line; 
%} 

DELIMITER [ ]+|[/t]+ 

KEYWORD  False|class|finally|is|return|None|continue|for|lambda|try|True|def|from|nonlocal|while|and|del|global|not|with|as|elif|if|or|yield|assert|else|import|pass|break|except|in|raise 

OPERATOR  ([+\[email protected]&|^~])|(\*{1,2})|(\/{1,2})|(<[=<]?)|(>[=>]?)|(==)|! 

COMMENT  #.+ 

IDENTIFIER [a-zA-Z_][a-zA-Z0-9_]* 
ID_ERR  [0-9]{IDENTIFIER} 

STRINGESCAPESEQ [\\]. 
SHORTSTRINGCHAR1 [^\\'\n]* 
SHORTSTRINGCHAR2 [^\\"\n]* 
SHORTSTRINGITEM1 {SHORTSTRINGCHAR1}|{STRINGESCAPESEQ} 
SHORTSTRINGITEM2 {SHORTSTRINGCHAR2}|{STRINGESCAPESEQ} 
STRING  [']{SHORTSTRINGITEM1}*[']|(["]{SHORTSTRINGITEM2}*["]) 
STRING_ERR ['].[^'\n\t]*|["].[^"\n\t]* 

BINDIGIT  [01] 
BININTEGER 0[bB]{BINDIGIT}+ 
BIN_ERR1  0[Bb]+{BINDIGIT}+ 

DIGIT  [0-9] 
NONZERODIGIT  [1-9] 
INTEGER  {NONZERODIGIT}{DIGIT}*|[0]+ 
INT_ERR1  {INTEGER}[a-zA-Z]{DIGIT} 
INT_ERR2  [-+]{INTEGER} 
INT_ERR3  [0+]{INTEGER} 

INTPART  {DIGIT}+ 
EXPONENT  [eE][+-]*{INTPART} 
FRACTION  [\.]{INTPART} 
EXPONENTFLOAT ({INTPART}|{POINTFLOAT}){EXPONENT} 
POINTFLOAT {INTPART}*{FRACTION}|{INTPART}[\.] 
FLOATNUMBER {POINTFLOAT}|{EXPONENTFLOAT} 
FLOAT_ERR_POINT {INTPART}*[\.]+{DIGIT}+[\.]*{DIGIT}*|{INTPART}[\.]+ 
FLOAT_ERR_SIGN ([-+]{FLOATNUMBER}) 
FLOAT_ERR_LETTER {FLOATNUMBER}[A-Za-z]+ 

IMAGINARYNUMBER ({FLOATNUMBER}|{INTPART})[jJ] 

%% 

{DELIMITER}  { } 
{KEYWORD}  { return KEYWORD; } 
{OPERATOR}  { } 
{COMMENT}  { printf("Line %d: Found COMMENT\n", line); } 
{IDENTIFIER}  { printf("Line %d: Found IDENTIFIER %s\n", line, yytext);     return IDENTIFIER; } 
{ID_ERR}  { printf("Line %d: !!ERROR!!\tWrong IDENTIFIER statement %s\n", line, yytext);   return ID_ERR;} 
{STRING}  { printf("Line %d: Found STRING %s\n", line, yytext);      return STRING; } 
{STRING_ERR}  { printf("Line %d: !!ERROR!!\tWrong STRING statement %s\n", line, yytext);   return STRING_ERR;} 
{BININTEGER}  { printf("Line %d: Found BINARY INTEGER NUMBER %s\n", line, yytext);     return BININTEGER; } 
{BIN_ERR1}  { printf("Line %d: !!ERROR!!\tWrong BINARY NUMBER statement, too many 'Bb's%s\n", line, yytext); return BIN_ERR1;} 
{INTEGER}  { printf("Line %d: Found INTEGER NUMBER %s\n", line, yytext);     return INTEGER; } 
{INT_ERR1}  { printf("Line %d: !!ERROR!!\tWrong INT statement %s\n", line, yytext);    return INT_ERR1;} 
{INT_ERR2}  { printf("Line %d: !!ERROR!!\tWrong INT statement, '+/-' found %s\n", line, yytext);   return INT_ERR2;} 
{INT_ERR3}  { printf("Line %d: !!ERROR!!\tWrong INT statement, first digit(s) zeros %s\n", line, yytext); return INT_ERR3;} 
{FLOATNUMBER}  { printf("Line %d: Found FLOAT NUMBER %s\n", line, yytext);     return FLOATNUMBER; } 
{FLOAT_ERR_POINT} { printf("Line %d: !!ERROR!!\tWrong FLOAT statement, too many '.' %s\n", line, yytext);  return FLOAT_ERR_POINT;} 
{FLOAT_ERR_POINT} { printf("Line %d: !!ERROR!!\tWrong FLOAT statement, '+/-' FOUND %s\n", line, yytext);  return FLOAT_ERR_SIGN;} 
{FLOAT_ERR_LETTER { printf("Line %d: !!ERROR!!\tWrong FLOAT statement, letter FOUND %s\n", line, yytext);  return FLOAT_ERR_LETTER;} 
{IMAGINARYNUMBER} { printf("Line %d: Found IMAGINARY NUMBER %s\n", line, yytext);     return IMAGINARYNUMBER; } 
.   { printf("Line %d: UNKNOWN TOKEN:%s", line, yytext); BEGIN(error);} 
\n     { line++; } 
<<EOF>>   { printf("#END OF FILE\n"); exit(0); } 

을 작성한 것입니다 전체 오류 출력 :이

flex scanner.l 
scanner.l:79: unrecognized rule 
scanner.l:79: fatal parse error 
+0

전체 오류 출력을 질문에 붙여 넣을 수 있습니까? – snakecharmerb

+0

물론, 그냥 – spyros

답변

3

{FLOAT_ERR_LETTER { printf("Line %d: !!ERROR!!\tWrong FLOAT statement, letter FOUND %s\n", line, yytext);  return FLOAT_ERR_LETTER;} 
       ^<--- here 

: 라인 74의 단부에 누락 브레이스는

for n in {57..79}; do head -n$n g.l | flex -o /dev/null -w || { echo $n; break; } done 

대부분의 시간을 다음 줄에 치명적인 오류 : 문제가 여기에 단순 오타 때문에, 미래의 독자들에게이 답변을 유용하게하는 막연한 시도에서

내가 문제를 발견하는 방법입니다 플렉스 입력의 끝은 중괄호 또는 기타 유사한 문제가 누락 된 결과이지만 전체 파일을 교정하는 것은 고통스럽고 놀랍게도 IDE에서 구문 색상 플렉스 파일을 올바르게 인식하지 못합니다. 그래서 위의 트릭은 엄청난 시간을 절약 할 수 있습니다. (이것은 항상 그렇게 단순하지있어,이 경우, 어떤 조치를 한 줄 이상 스팬하지 않습니다.)


해당 오류를 수정 한 후에는 몇 가지 패턴이 일치 될 수 없음을 발견 할 것입니다. 패턴이 라인 72 ({FLOAT_ERR_POINT})와 동일하기 때문에 라인 73을 비교할 수 없습니다. 0B 다음에 숫자가 시작되고 문제의 패턴이 IDERR과 일치하기 때문에 (호기심에 따라) 하나의 숫자와 그 다음에 식별 기호가옵니다. 65 및 66 (BININTEGERBIN_ERR1)은 일치 할 수 없습니다. (아마도 [[:digit:]]+{IDENTIFIER}을 의미했을 것입니다.) 전반적으로 올바른 패턴의 패턴보다는 우선 순위를 갖지 않도록 끝에 오류 패턴을 넣어야합니다. 또한 오류 토큰을 작성하는 것이 훨씬 간단합니다. (BIN_ERR1IDERR 전에 와야 있도록 또한,보다 일반적인 일 전에 특정 오류 패턴을 넣어해야합니다.)

일부 다른 의견 :

당신은 플렉스 일치하는 패턴을보고 추가하려는 경우 --debug (또는 -d) 코드를 사용하여 코드 전체에 printf 명령을 뿌리지 말고 명령 줄에 추가하십시오. 어떤 일이 일어나고 있는지를 보여주는 더 좋은 일을하고, 전체 파일을 편집하지 않고 켜고 끌 수 있습니다.

< 의견 > 전반적으로 입력 파일 에서처럼 플렉스 매크로를 과도하게 사용하는 것은 그리 유용하지 않습니다. 실제로 매크로의 모든 용도를 찾아야하기 때문에 실제로 사양을 읽기가 어렵게 만듭니다. 개인적으로는 매크로를 여러 번 사용해야 할 때만 매크로를 사용하고 심지어는 [[:digit:]]과 같은 내장 된 문자 클래스를 숨기는 단순한 방법이 아닌 경우에도 매크로를 사용합니다. </의견 >

+0

많은 정보를 주셔서 감사하고 모든 시간을 쓸 수 있습니다. – spyros