2017-11-25 8 views
0

저는 flex와 bison을 사용하여 가상 프로그래밍 언어 용 구문 분석기를 만들고 있습니다. 유효하고 유효하지 않은 변수 이름이있을 것입니다.Flex/Bison - 정규 표현식이 두 개 이상의 X (예 : XXY-1 또는 XXY-1)와 일치하지 않습니다.

XXXX XY-1 // valid 
XXXXX Z // valid 
XXX Y // valid 
XXX 5Aet // invalid 
XXXX XXAB-Y // invalid 

시작 부분의 x는 변수의 크기를 지정하는 것입니다. 변수 5Aet은 숫자로 시작하므로 인 이 잘못되었습니다. 나는이

[\_\-0-9][a-zA-Z][a-zA-Z0-9\-\_]* yylval.string = strdup(yytext);return TERM_INVALID_VARIABLE_NAME; 

변수 XXAB-Y에 대한 정규 표현식을 일치하도록 관리하는 변수 이름이 두 개 이상의 x 문자로 시작할 수 없기 때문에 무효입니다했다.

정규 표현식과 일치 시키려고 시도했지만 성공하지 못했습니다. 나는 아래 표현의 다양한 조합을 시도했지만 아무도 시도하지 않았다. 변수는 유효한 것으로 계속 일치합니다.

[X]{2,}[A-Z0-9\-]* yylval.string = strdup(yytext);return TERM_INVALID_VARIABLE_NAME; 

[X]{2,0}[\_\-0-9][a-zA-Z][a-zA-Z0-9\-\_]* yylval.string = strdup(yytext);return TERM_INVALID_VARIABLE_NAME; 

lexer.l는

[\t ]+ // ignore whitespaces 

\n // Ignore new line 

[\"][^"]*[\"] yylval.string = strdup(yytext); return TERM_STR; 

";" return TERM_SEPARATOR; 

"." return TERM_FULLSTOP; 

[0-9]+ yylval.integer = atoi(yytext); return TERM_INT; 

XX[A-Z0-9-]* yylval.string = strdup(yytext);return TERM_INVALID_VARIABLE_NAME; 

[\_\-0-9]+[a-zA-Z][a-zA-Z0-9\-\_]* yylval.string = strdup(yytext);return TERM_INVALID_VARIABLE_NAME; 

[A-Z][A-Z0-9\-]* yylval.string = strdup(yytext); return TERM_VARIABLE_NAME; 

[X]+ yylval.integer = yyleng; return TERM_SIZE; 

. return TERM_INVALID_TOKEN; 

parser.y 니펫 니펫

program: 
    /* empty */ | 
    begin middle_declarations body grammar_s end { 
     printf("\nParsing complete\n"); 
     exit(0); 
    }; 

begin: 
    TERM_BEGINING TERM_FULLSTOP; 

body: 
    TERM_BODY TERM_FULLSTOP; 

end: 
    TERM_END TERM_FULLSTOP; 

middle_declarations: 
    /* empty */ | 
    //Left recursive to allow for many declearations 
    middle_declarations declaration TERM_FULLSTOP; 

declaration: 
    TERM_SIZE TERM_VARIABLE_NAME { 
     createVar($1, $2); 
    } 
    | 
    TERM_SIZE TERM_INVALID_VARIABLE_NAME { 
     printInvalidVarName($2); 
    }; 

grammar_s: 
    /* empty */ | 
    grammar_s grammar TERM_FULLSTOP; 

grammar: 
    add | move | print | input; 

add: 
    TERM_ADD TERM_INT TERM_TO TERM_VARIABLE_NAME { 
     addIntToVar($2, $4); 
    } 
    | 
    TERM_ADD TERM_VARIABLE_NAME TERM_TO TERM_VARIABLE_NAME { 
     addVarToVar($2, $4); 
    } 

    ; 

move: 
    TERM_MOVE TERM_VARIABLE_NAME TERM_TO TERM_VARIABLE_NAME { 
     moveVarToVar($2, $4); 
    } 
    | 
    TERM_MOVE TERM_INT TERM_TO TERM_VARIABLE_NAME { 
     moveIntToVar($2, $4); 
    } 

    ; 

print: 
    /* empty */ | 
    TERM_PRINT rest_of_print { 
     printf("\n"); 
    }; 

rest_of_print: 
    /* empty */ | 
    rest_of_print other_print; 

other_print: 

    TERM_VARIABLE_NAME { 
     printVarValue($1); 
    } 
    | 
    TERM_SEPARATOR { 
     // do nothing 
    } 
    | 
    TERM_STR { 
     printf("%s", $1); 
    } 

    ; 

input: 
    // Fullstop declares grammar 
    TERM_INPUT other_input; 

other_input: 

    /* empty */ | 
    // Input var1 
    TERM_VARIABLE_NAME { 
     inputValues($1); 
    } 
    | 
    // Can be input var1; var2;...varN 
    other_input TERM_SEPARATOR TERM_VARIABLE_NAME { 
     inputValues($2); 
    } 
    ; 

디버그 출력 :

Starting parse 
Entering state 0 
Reading a token: Next token is token TERM_BEGINING (1.1:) 
Shifting token TERM_BEGINING (1.1:) 
Entering state 1 
Reading a token: Next token is token TERM_FULLSTOP (1.1:) 
Shifting token TERM_FULLSTOP (1.1:) 
Entering state 4 
Reducing stack by rule 3 (line 123): 
    $1 = token TERM_BEGINING (1.1:) 
    $2 = token TERM_FULLSTOP (1.1:) 
-> $$ = nterm begin (1.1:) 
Stack now 0 
Entering state 3 
Reducing stack by rule 6 (line 131): 
-> $$ = nterm middle_declarations (1.1:) 
Stack now 0 3 
Entering state 6 
Reading a token: Next token is token TERM_SIZE (1.1:) 
Shifting token TERM_SIZE (1.1:) 
Entering state 8 
Reading a token: Next token is token TERM_VARIABLE_NAME (1.1:) 
Shifting token TERM_VARIABLE_NAME (1.1:) 
Entering state 13 
Reducing stack by rule 8 (line 137): 
    $1 = token TERM_SIZE (1.1:) 
    $2 = token TERM_VARIABLE_NAME (1.1:) 
-> $$ = nterm declaration (1.1:) 
Stack now 0 3 6 
Entering state 10 
Reading a token: Next token is token TERM_FULLSTOP (1.1:) 
Shifting token TERM_FULLSTOP (1.1:) 
Entering state 15 
Reducing stack by rule 7 (line 134): 
    $1 = nterm middle_declarations (1.1:) 
    $2 = nterm declaration (1.1:) 
    $3 = token TERM_FULLSTOP (1.1:) 
-> $$ = nterm middle_declarations (1.1:) 
Stack now 0 3 
Entering state 6 
Reading a token: Next token is token TERM_SIZE (1.1:) 
Shifting token TERM_SIZE (1.1:) 
Entering state 8 
Reading a token: Next token is token TERM_VARIABLE_NAME (1.1:) 
Shifting token TERM_VARIABLE_NAME (1.1:) 
Entering state 13 
Reducing stack by rule 8 (line 137): 
    $1 = token TERM_SIZE (1.1:) 
    $2 = token TERM_VARIABLE_NAME (1.1:) 
-> $$ = nterm declaration (1.1:) 
Stack now 0 3 6 
Entering state 10 
Reading a token: Next token is token TERM_FULLSTOP (1.1:) 
Shifting token TERM_FULLSTOP (1.1:) 
Entering state 15 
Reducing stack by rule 7 (line 134): 
    $1 = nterm middle_declarations (1.1:) 
    $2 = nterm declaration (1.1:) 
    $3 = token TERM_FULLSTOP (1.1:) 
-> $$ = nterm middle_declarations (1.1:) 
Stack now 0 3 
Entering state 6 
Reading a token: Next token is token TERM_SIZE (1.1:) 
Shifting token TERM_SIZE (1.1:) 
Entering state 8 
Reading a token: Next token is token TERM_VARIABLE_NAME (1.1:) 
Shifting token TERM_VARIABLE_NAME (1.1:) 
Entering state 13 
Reducing stack by rule 8 (line 137): 
    $1 = token TERM_SIZE (1.1:) 
    $2 = token TERM_VARIABLE_NAME (1.1:) 
-> $$ = nterm declaration (1.1:) 
Stack now 0 3 6 
Entering state 10 
Reading a token: Next token is token TERM_FULLSTOP (1.1:) 
Shifting token TERM_FULLSTOP (1.1:) 
Entering state 15 
Reducing stack by rule 7 (line 134): 
    $1 = nterm middle_declarations (1.1:) 
    $2 = nterm declaration (1.1:) 
    $3 = token TERM_FULLSTOP (1.1:) 
-> $$ = nterm middle_declarations (1.1:) 
Stack now 0 3 
Entering state 6 
Reading a token: Next token is token TERM_BODY (1.1:) 
Shifting token TERM_BODY (1.1:) 
Entering state 7 
Reading a token: Next token is token TERM_FULLSTOP (1.1:) 
Shifting token TERM_FULLSTOP (1.1:) 
Entering state 11 
Reducing stack by rule 4 (line 126): 
    $1 = token TERM_BODY (1.1:) 
    $2 = token TERM_FULLSTOP (1.1:) 
-> $$ = nterm body (1.1:) 
Stack now 0 3 6 
Entering state 9 
Reducing stack by rule 10 (line 145): 
-> $$ = nterm grammar_s (1.1:) 
Stack now 0 3 6 9 
Entering state 14 
Reading a token: Next token is token TERM_PRINT (1.1:) 
Shifting token TERM_PRINT (1.1:) 
Entering state 20 
Reducing stack by rule 22 (line 180): 
-> $$ = nterm rest_of_print (1.1:) 
Stack now 0 3 6 9 14 20 
Entering state 34 
Reading a token: Next token is token TERM_STR (1.1:) 
Shifting token TERM_STR (1.1:) 
Entering state 41 
Reducing stack by rule 26 (line 194): 
    $1 = token TERM_STR (1.1:) 
-> $$ = nterm other_print (1.1:) 
Stack now 0 3 6 9 14 20 34 
Entering state 44 
Reducing stack by rule 23 (line 182): 
    $1 = nterm rest_of_print (1.1:) 
    $2 = nterm other_print (1.1:) 
-> $$ = nterm rest_of_print (1.1:) 
Stack now 0 3 6 9 14 20 
Entering state 34 
Reading a token: Next token is token TERM_FULLSTOP (1.1:) 
Reducing stack by rule 21 (line 176): 
    $1 = token TERM_PRINT (1.1:) 
    $2 = nterm rest_of_print (1.1:) 
"hEllo" 
-> $$ = nterm print (1.1:) 
Stack now 0 3 6 9 14 
Entering state 25 
Reducing stack by rule 14 (line 150): 
    $1 = nterm print (1.1:) 
-> $$ = nterm grammar (1.1:) 
Stack now 0 3 6 9 14 
Entering state 22 
Next token is token TERM_FULLSTOP (1.1:) 
Shifting token TERM_FULLSTOP (1.1:) 
Entering state 35 
Reducing stack by rule 11 (line 147): 
    $1 = nterm grammar_s (1.1:) 
    $2 = nterm grammar (1.1:) 
    $3 = token TERM_FULLSTOP (1.1:) 
-> $$ = nterm grammar_s (1.1:) 
Stack now 0 3 6 9 
Entering state 14 
Reading a token: Next token is token TERM_END (1.1:) 
Shifting token TERM_END (1.1:) 
Entering state 16 
Reading a token: Next token is token TERM_FULLSTOP (1.1:) 
Shifting token TERM_FULLSTOP (1.1:) 
Entering state 27 
Reducing stack by rule 5 (line 129): 
    $1 = token TERM_END (1.1:) 
    $2 = token TERM_FULLSTOP (1.1:) 
-> $$ = nterm end (1.1:) 
Stack now 0 3 6 9 14 
Entering state 21 
Reducing stack by rule 2 (line 113): 
    $1 = nterm begin (1.1:) 
    $2 = nterm middle_declarations (1.1:) 
    $3 = nterm body (1.1:) 
    $4 = nterm grammar_s (1.1:) 
    $5 = nterm end (1.1:) 

시료 입력 :

BeGiNInG. 

X XXAB-. 
XX XXX7. 
XX XXXY. 

BoDY. 

print "hEllo". 

EnD. 
+0

모든 규칙을 순서대로 표시하십시오. – rici

+0

@rici hello again :). 나는 질문을 변경했다. – cod3min3

+0

'[X] {2,0}'은 유효하지 않지만'[X] {2,}'는 저에게 예상대로 작동합니다. 해당 파일에서 flex에서 "bad iteration values"오류가 표시되지 않습니까? – rici

답변

0
[X]{2,}[A-Z0-9\-]* yylval.string = strdup(yytext);return TERM_INVALID_VARIABLE_NAME; 

잘 작동해야하며 제대로 작동합니다. [A-Z0-9-] 문자 클래스를 일치 더 X 문자 이후

XX[A-Z0-9-]* yylval.string = strdup(yytext);return TERM_INVALID_VARIABLE_NAME; 

: 그러나, 단순화 할 수있다.

(당신처럼) 그 패턴을도 XX은 일치 (는 문자 클래스의 첫 번째 또는 마지막 일 중 하나입니다 제공 할 것입니다 -는 문자 클래스 내부 \- 쓰기 할 필요는 없습니다.) 플렉스 입력 파일의 앞 부분에 있기 때문에 [X]+ 패턴이 우세합니다. 0 2. 미만 X{2,} "2 개 이상의 X"를 지정 작성하는 것입니다 때문에

{2,0}

는, 유효한 간격 표현하지 않습니다 (당신이 선호하는 경우, 또는 [X]{2,}을. "X"{2,}도 작동합니다.) 즉에서 오류 메시지를 생성한다 flex를 사용하면 어휘 스캐너가 생성되지 않습니다. (그러나, 오래된 사람은 여전히 ​​주위에 혼란을 야기 할 수 있습니다.)

+0

나는 XX [A-Z0-9 -] * yylval을 시도했다.string = strdup (yytext); TERM_INVALID_VARIABLE_NAME;을 반환합니다. '하지만 여전히 작동하지 않습니다. 이유가 무엇인지 알 수 없습니다. 나는 디버깅 출력과 샘플 입력을 포함하여 질문을 업데이트했다. 필요한 경우 전체 코드를 제공 할 수도 있습니다. – cod3min3

+1

@ cod3min3 : 실제로 스캐너를 재생성하지 못하는 것 같습니다. Flex는 확실히'X {2,0}'에 대한 에러를 생성합니다; 게다가 최근 편집 ('[X] +'를 파일의 끝으로 옮긴다)은 절대로'TERM_SIZE' 토큰을 반환하지 않을 것입니다. – rici

관련 문제