私はANTLRを使い始めており、レクサールールにはかなり気まぐれであることに気付きました。非常にイライラする例は次のとおりです。
grammar output;
test: FILEPATH NEWLINE TITLE ;
FILEPATH: ('A'..'Z'|'a'..'z'|'0'..'9'|':'|'\\'|'/'|' '|'-'|'_'|'.')+ ;
NEWLINE: '\r'? '\n' ;
TITLE: ('A'..'Z'|'a'..'z'|' ')+ ;
この文法は次のようなものと一致しません。
c:\ test.txt
バツ
奇妙なことに、TITLE
をTITLE: 'x' ;
に変更すると、今回はまだ失敗し、「入力 'x'に 'x'が必要です」というエラーメッセージが表示され、非常に混乱します。さらに奇妙なことに、TITLE
のtest
の使用をFILEPATH
に置き換えると、すべてが機能します(ただし、FILEPATH
は一致するものよりも一致します)だから、一般的にそれは私にとって有効な解決策ではありません)。
ANTLRがこのような非常に奇妙なエラーを出し、その後、物事をシャッフルするときに明白な理由もなく突然動作する理由について、私は非常に混乱しています。
これはANTLR
のよくある誤解のようです:
ANTLRでの言語処理:
言語処理は、厳密に分離された2つのフェーズで実行されます。
字句解析は解析に先行する必要があるため、結果があります。字句解析プログラムは構文解析プログラムから独立しているため、構文解析プログラムは字句解析に影響を与えることができません。
Lexing
ANTLRのLexingは次のように機能します。
例:文法の何が問題なのか
文法には、重要な2つのルールがあります。
FILEPATH: ('A'..'Z'|'a'..'z'|'0'..'9'|':'|'\\'|'/'|' '|'-'|'_'|'.')+ ;
TITLE: ('A'..'Z'|'a'..'z'|' ')+ ;
TITLEに一致する各一致は、FILEPATHにも一致します。そして、FILEPATHはTITLEの前に定義されます:したがって、タイトルになると予想される各トークンはFILEPATHになります。
そのための2つのヒントがあります。
これは直接OPの問題ではありませんでしたが、同じエラーメッセージを持っている人のために、ここで確認できるものがあります。
同じMismatched Input 'x' expecting 'x'
新しいキーワードを導入したときのあいまいなエラーメッセージ。私の理由は、新しいキーワードとしてではなく変数名として割り当てたVARNAME
レクサールールの後に新しいキーWordを配置したためです。 VARNAME
ルールの前にキーワードを置くことで修正しました。
同じエラーがありますが、レクサーのどのルールが関係するのか想像できません。
CobolのいくつかのCDEファイルを解析しようとしています-これはHPノンストップ固有のものだと思います。
とにかく、私が解析したいのは次のようなものです
* SCHEMA PRODUCED DATE - TIME : 1/29/2019 - 15:17:01
?SECTION MYREQUEST,NONSTOP
* Definition MYREQUEST created on 05/11/2016 at 11:05
01 MYREQUEST.
...
パーサーは次のエラーで失敗します
mismatched input '?SECTION foo' expecting '?'
私の文法はこれです:
grammar CdeFile;
cdeFile : line+ ;
line : sectionLine ;
sectionLine : QUESTIONMARK SECTION sectionName '\r'? '\n' ;
sectionName : TEXTLIST ;
QUESTIONMARK : '?' ;
SECTION: S E C T I O N ;
TEXTLIST : TEXT (',' TEXT)* ;
TEXT : ~[,\n\r"]+ ;
WS : ( ' ' | '\t' | '\f' )+ -> skip;
LINE_COMMENT
: '*' {Column == 1}? '*'* ~('\n'|'\r')* '\r'? '\n' ->skip
;
// case insensitive chars
fragment A:('a'|'A');
fragment B:('b'|'B');
fragment C:('c'|'C');
fragment D:('d'|'D');
fragment E:('e'|'E');
fragment F:('f'|'F');
fragment G:('g'|'G');
fragment H:('h'|'H');
fragment I:('i'|'I');
fragment J:('j'|'J');
fragment K:('k'|'K');
fragment L:('l'|'L');
fragment M:('m'|'M');
fragment N:('n'|'N');
fragment O:('o'|'O');
fragment P:('p'|'P');
fragment Q:('q'|'Q');
fragment R:('r'|'R');
fragment S:('s'|'S');
fragment T:('t'|'T');
fragment U:('u'|'U');
fragment V:('v'|'V');
fragment W:('w'|'W');
fragment X:('x'|'X');
fragment Y:('y'|'Y');
fragment Z:('z'|'Z');
QUESTIONMARKの値は同期しており、すべてが再構築されます-それでもこの奇妙なメッセージです。