0

驚いたことに、私はプロジェクト用に SQL のような言語パーサーを構築しています。

ほとんど動作していましたが、実際のリクエストに対してテストを開始すると、内部で思っていたよりも異なる動作をしていることに気付きました。

次の文法の主な問題は、言語キーワード ' pct_within ' に対してレクサー規則PCT_WITHINを定義していることです。これは正常に動作しますが、「 attributes.pct_vac 」のようなフィールドを照合しようとすると、 「 attributes.ac 」のテキストと次のかなりの ANTLR エラーを含むフィールドが表示されます。

line 1:15 mismatched character u'v' expecting 'c'

文法

grammar Select;

options {
  language=Python;
}

eval returns [value]
    : field EOF 
    ;

field returns [value]
    : fieldsegments {print $field.text}
    ;

fieldsegments
    : fieldsegment (DOT (fieldsegment))*
    ;

fieldsegment
    : ICHAR+ (USCORE ICHAR+)*
    ;

WS                      : ('\t' | ' ' | '\r' | '\n')+ {self.skip();};

ICHAR                   : ('a'..'z'|'A'..'Z');

PCT_CONTAINS            : 'pct_contains';

USCORE                  : '_';
DOT                     : '.';

このトピックについて見つけられるものはすべて読んでいます。たとえそれが間違っていたとしても、レクサーが見つけたものをどのように消費するか。セマンティック述語を使用してあいまいさを取り除く方法/先読みの使用方法。しかし、私が読んだすべてがこの問題の解決に役立ったわけではありません。

正直なところ、それが問題になる可能性さえありません。私が目にする他の文法にはEXISTSのような Lexer ルールがあるため、非常に明白な何かが欠けているに違いありませんが、パーサーが「 existsOrNot 」のような文字列を取得し、 「 rNot 」のテキストを吐き出してIDENTIFIERを吐き出すことはありません。

私は何が欠けているか、または完全に間違っていますか?

4

1 に答える 1

1

fieldsegment パーサー ルールをレクサー ルールに変換します。現状では、次のような入力を受け入れます

"abc      
_     abc"

これはおそらくあなたが望むものではありません。キーワード「pct_contains」は、個別に定義されているため、このルールには一致しません。特定のシーケンスでキーワードを通常の識別子として受け入れたい場合は、受け入れられた識別子ルールに含める必要があります。

于 2013-06-01T10:24:28.997 に答える