ANTLR

2017-07-27 7 views
0

に一定のルールを必須にするにはどうすれば条件式をチェックする必要があり、次の文法を書きました。以下 例としては、私はこの文法を使用して達成したいものです。ANTLR

test無効
test = 1有効
test = 1 and another_test>=0.2有効
test = 1 kasd y = 1無効(2つの条件がでAND/OR分離しなければならない)
a = 1 or (b=1 and c)無効(そこにはできませんすなわち、 'c'のような孤独な文字です。それは常に三つ組、すなわちリテラル演算子リテラルでなければなりません)

だから私の質問は、上記の例で動作するように文法を取得するにはどうすればいいですか? 2つのトリプレット(リテラル演算子リテラル)の間にある単語を必須とすることはできますか?ある意味では、パーサにwhere句の条件を検証させようとしていますが、単純な条件と関数だけが許されています。私はまた、関数、括弧、任意のリテラルなどのJavaの値を取得する訪問者を持って、どのように達成する必要がありますか?

答えて

1

はいなし。

あなただけの比較や論理演算が同じである表現できるようにあなたの文法を変更することができます:あなたはブール変数や関数を許可する場合は

expr 
: term ('='|'<>'| '<' | '<=' | '>' | '>=') term 
| expr K_AND expr 
| expr K_OR expr 
| '(' expr ')' 
; 

term 
: literal_value 
| function_name '(' (expr (',' expr)* | '*')? ')' 
; 

問題が来るの - あなたは機能を分類する必要がありますあなたのレクサーの/ varsにはそれぞれ異なる端末がありますが、これは手間がかかりエラーが発生しやすくなります。

代わりに、パーサのチェックインのこの種のないことが一般的に優れている - あなたのパーサが許容することがあり、表現のようなものを受け入れて、そしてそれのために式ツリーを生成します。次に、オペランドのオペランドの型と関数の引数をチェックする、ツリー上の別のパス(型チェッカーと呼ばれる)を持っています。

(分離型チェッカ付き)この後者のアプローチは、一般的に、明確に、より柔軟な、はるかに簡単なってしまう、と(むしろ単に「構文エラー」よりも)より良いエラーメッセージを与えます。

+0

ありがとうございます。すべてを受け入れてからエラーを投げる方が良いアプローチだと思われます。しかし、私は木でそれを取得することができませんよ。その例ではhttp://imgur.com/a/68RWI – NEO

+0

のうち表現を作成する方法はありませんとして、あなたは、lals' 'で構文エラーがありますそれは、種類にかかわらず –