2

C/C++ ソース コードのレクサー文法を開発しています。文法の目標は、大学の学生間の剽窃と戦うことです。

文法の有効性を向上させるために、生徒が変数をインクリメントできる 4 つ (?) の異なる方法に対して、ANTLR に同じトークンを作成してもらいたいと考えています。

i++
++i
i += 1
(i = i + 1) [I doubt that this can be solved with ANTLR]

これらの各式は、トークン INCREMENT になります。

私がこれまでに思いついたこと:(文法の必要な部分だけがここに再現されています)

options {
    language = CSharp3;
    filter = true;
    k = 2;
}

INCREMENT : IDENTIFIER (PLUSPLUS | ADDEQUAL '1') | PLUSPLUS IDENTIFIER ;
IDENTIFIER 
    :   LETTER (LETTER | DIGIT)*;

/*
 * covers both decimal and hex integer literals
 */
INTEGER_LITERAL : 
   DIGIT+ | '0x' HEX_DIGIT+;

ADDEQUAL            : '+=';
PLUSPLUS            : '++';

fragment
LETTER  :   'A'..'Z' | 'a'..'z';

fragment
HEX_DIGIT : DIGIT | 'a'..'f' | 'A'..'F';

fragment
DIGIT : '0'..'9';

この文法をテストすると、 の代わりにi += 1トークン シーケンスが返されます。IDENTIFIER ADDEQUAL INTEGER_LITERALINCREMENT

何故ですか?私の理解では、ルールの優先順位は上から下にINCREMENTあり、さらに「より大きな」ルールです。

望ましい結果を得るには、文法をどのように調整する必要がありますか?

4

1 に答える 1

2

この文法をテストすると、 の代わりにi += 1トークン シーケンスが返されます。IDENTIFIER ADDEQUAL INTEGER_LITERALINCREMENT

何故ですか?

ルール"i += 1"内で考慮しなかったスペースが含まれているためです。INCREMENT

望ましい結果を得るには、文法をどのように調整する必要がありますか?

スペース (および場合によっては改行) を考慮してください。

ただし、レクサーを単独で作成することは、ここでの方法ではないようです。パーサー、IMOが本当に必要です。オプションk = 2;セットは、レクサー ルールではなく、パーサー ルールを先読みします。

于 2012-08-23T19:36:45.863 に答える