2017-09-16 3 views
0

現在、antlr4を使用してパーサーを構築していますが、私はベストを尽くしたが問題は見つからなかった。私はそれを解明して解決するのを助けてくれますか?私は識別子の前にテキストを配置した場合、私はTEXTの前に識別子を置く場合antlr4 2つのレクサールールが同じ文字列に一致します

# grammer file : PluginDoc.g4: 

grammer PluginDoc 

pluginDef : pluginName | pluginDesc; 
pluginName : PluginName IDENTIFIER; 
pluginDesc : PluginDesc TEXT; 

PluginName '@pluginName' 
PluginDesc '@pluginDesc' 

IDENTIFIER : [a-zA-Z_]+; 
TEXT : ~(' ' | '\n' | '\t')+; 

input content is: 
@pluginName kafka 
@pluginDesc abc 

、私は「TEXTを期待不一致入力 『ABC』」を取得します は、私が「不一致入力 『カフカ』期待IDENTIFIER」

を取得しますIDENTIFIERとTEXTの両方が一致しているように見えますが、pluginNameのIDENTIFIERとどのように一致させることができますか?pluginDescのTEXTと一致するだけですか?

をファイルのヘッダが文法、ない文法を指定する必要があります。

+0

両方に 'TEXT'を使用して、後処理フェーズで識別子名を検証してください。 –

答えて

2

まず第一に、あなたはあなたが投稿した文法でいくつかのエラーを持っています。レクサーのトークンPluginNameとPluginDescの前にコロンとセミコロンがありません。パーサールールをすべて小文字で、レクサールールをすべて大文字として記述するのは、(書き込まれていない?)ルールです。

grammar PluginDoc; 

pluginDef : pluginName | pluginDesc; 
pluginName : PLUGIN_NAME IDENTIFIER; 
pluginDesc : PLUGIN_DESC TEXT; 

PLUGIN_NAME : '@pluginName'; 
PLUGIN_DESC : '@pluginDesc'; 

IDENTIFIER : [a-zA-Z_]+; 
TEXT : ~(' ' | '\n' | '\t')+; 

文法のテスト中に発生したいくつかの問題は、未処理の空白が原因でした。まず、Lexerルールを含めて、ファイルの末尾にある空白をスキップして、他のすべてのLexerルールの後に置く必要があります。

WS: [ \n\t\r]+ -> skip; 

次に、あなたがTEXTIDENTIFIER互いに衝突に問題があります。文字ストリームがレクサーによってトークン化された場合、kafkaおよびabcは、IDENTIFIERおよびTEXTトークンの両方になります。レクサーレクゼスはトップダウン形式であるため、両方ともレクサールールがトークン化されています。これにより、発生したエラーが発生します。つまり、2番目のルールとして定義したものは、パーサーではトークンとして送信されなかったため、マッチングできません。

Lucasの示唆したように、おそらくこれらは両方ともTEXTと一致し、後でリスナ/ビジターの入力の有効性をチェックしてください。

grammar PluginDoc; 

pluginDef : (pluginName | pluginDesc)* EOF; 
pluginName : PLUGIN_NAME TEXT; 
pluginDesc : PLUGIN_DESC TEXT; 

PLUGIN_NAME: '@pluginName'; 
PLUGIN_DESC: '@pluginDesc'; 

TEXT : ~[ \r\n\t]+; 

WS: [ \r\n\t]+ -> skip; 

それは一度@pluginName X@pluginDesc Y両方の入力にしたい私の印象だったし、それらを識別するので、私はまた

pluginDef : (pluginName | pluginDesc)* EOF; 

pluginDefパーサルールを変更しました。これが当てはまらない場合は、以前の内容に自由に変更してください。あなたはまた、入力としてテキストファイルでこれを実行することができ enter image description here

サンプル入力onyour上記修飾文法によって生成される結果のAST。

+0

「EOF」とは何ですか? –

+0

@GaryGauh EOFは、ファイル識別子の組み込みの最後です。これは、入力がファイルの場合はファイルのリテラルの終わり、OSに応じて端末のCTRL-Z/Dの場合もあります。ここの例ではおそらく問題なく動作するでしょうが、後で問題を避けるために経験を教えてくれました。 –

関連する問題