2017-11-25 12 views
0

私はflexとbisonを使用して架空のプログラミング言語用のパーサを作成しています。有効で無効な変数名が存在します。Flex/Bison - 正規表現が2つ以上のXの例(XXY-1またはXXY-1)と一致しない

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

最初のxは、変数のサイズを指定するだけです。変数5Aetは数字で始まるので、は無効です。私は、変数名が二つ以上のx文字で始めることはできませんので、この

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

変数XXAB-Yの正規表現は、無効で一致するために管理しています。

これに対して正規表現に一致させようとしましたが、失敗しました。私は以下の式のいろいろな組み合わせを試しましたが、うまくいきませんでした。変数は有効なものとして一致し続けます。

[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; 

はうまく動作し、うまく動作します。任意の更なるX文字が[A-Z0-9-]文字クラスと一致しますので、

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

:しかし、それはのように簡略化することができます。 (文字クラス内\-を書き込む必要がないことに注意してください。-は行います、それは文字クラスで最初または最後のものであることを条件とする。)

(あなたのような)パターンもちょうどXXと一致していることを、 [X]+パターンは、フレックス入力ファイルの初期に来るので勝ちます。 0がX{2,}書き、「2以上のX」を指定するには2未満であるため、

{2,0}は、有効な間隔式ではありません(ご希望の場合、または[X]{2,}を。"X"{2,}も動作します。)からのエラーメッセージを生成する必要があることflexを使用すると、字句スキャナが生成されません。 (ただし、古い人がまだ横たわっている可能性があり、混乱を招く可能性があります)

+0

私は 'XX [A-Z0-9 - ] * yylvalを試しました。string = strdup(yytext); return TERM_INVALID_VARIABLE_NAME; 'それでも動作しませんでしたが、なぜそれが取得されていないのかわかりません。質問を更新しました。デバッグ出力とサンプル入力が含まれています。必要に応じて完全なコードを与えることもできます。 – cod3min3

+1

@ cod3min3:私はあなたが実際にスキャナを再生していないと思う。 Flexは間違いなく 'X {2,0}'のエラーを生成します。さらに、あなたの最新の編集( '[X] +'をファイルの最後に移動した)は決して 'TERM_SIZE'トークンを返しません。 – rici

関連する問題