Python 3 の AST ダンプ形式を解析して、より簡単に操作できる AST 形式に変換できる文法を構築する際に問題が発生しています。そのためにANTLR文法を書くことにしましたが、キーワードブロックの処理に問題があります(ただし、何らかの理由でキーワードブロックのみです)。次のように、キーワードの文法を分離しました。
grammar kwds;
options {output=AST;}
keywords: 'keywords=['((', '?)keyword)*']' -> keyword*
;
keyword : 'keyword(arg='STRING', value='str')'
;
str : 'Str(s='STRING')' -> STRING
;
STRING
: '\'' ( ESC_SEQ | ~('\\'|'\'') )* '\''
;
fragment
ESC_SEQ
: '\\' ('b'|'t'|'n'|'f'|'r'|'\"'|'\''|'\\')
| UNICODE_ESC
| OCTAL_ESC
;
EMPTYBRACKETS
: '[]';
fragment
OCTAL_ESC
: '\\' ('0'..'3') ('0'..'7') ('0'..'7')
| '\\' ('0'..'7') ('0'..'7')
| '\\' ('0'..'7')
;
fragment
UNICODE_ESC
: '\\' 'u' HEX_DIGIT HEX_DIGIT HEX_DIGIT HEX_DIGIT
;
fragment
HEX_DIGIT : ('0'..'9'|'a'..'f'|'A'..'F') ;
これは、キーワード ルールに示されている形式で、キーワードのリスト (カンマ区切りで 0 以上) を受け入れるように設計されています。
上記の文法に次の (有効な) 入力を与えると、
キーワード=[キーワード(引数='名前', 値=Str(s='UGA')), キーワード(引数='ランク', 値=Str(s='2'))]
文法はこれを認識します。
ただし、私が書いた「完全な」python 3 AST 形式の文法を使用すると (スペース節約のためにhttp://pastebin.com/ETrSVXvfにあり、上記の 2 つのルールはそれぞれ 106 行目と 109 行目にあります)、これは実質的にまったく同じ文法規則を使用しますが、上記のサンプルの最初のキーワード一致を解析した後、トークン ストリームは数文字ずれているように見えます。キーワード ルールに対して解析すると、次の出力が生成されます。
sample3.txt line 1:52 mismatched character 'e' expecting 'w'
sample3.txt line 1:53 no viable alternative at character 'y'
sample3.txt line 1:54 no viable alternative at character 'w'
sample3.txt line 1:55 no viable alternative at character 'o'
sample3.txt line 1:56 no viable alternative at character 'r'
sample3.txt line 1:57 no viable alternative at character 'd'
sample3.txt line 1:58 no viable alternative at character '('
sample3.txt line 1:59 missing ENDBR at 'arg='
これが発生する可能性は 1 つだけ考えられます。複数のキーワード ステートメントを検出するために使用したパターンは、他のタイプのステートメントでも機能するため、文法のあいまいさが原因で、何かが正しくトークン化されていません。しかし、そのあいまいさが実際に文法のどこにあるのか、私は完全に立ち往生しています。
また、一般的に文法を改善する方法に関する一般的な改善のヒントをいただければ幸いです。