2016-05-03 10 views
1

ANTLR4文法に問題があり、文字列を正しく解析できません。私は自分の問題を解決する方法を学ぶことにもっと興味を持っています。どんなタイプのデバッグ情報を生成することができますか?パーサーが文字列を解析する際にパーサーが「考えている」ことを知りたい。Python ANTLR4文法のデバッグ

文法は、ここで見つけることができます:https://github.com/Metrink/metrink-fe/blob/master/metrink.g4私は簡単なテスト文字列使用してい

1:2 missing TIME_INDICATOR at 'd'

文法はので、私は」TIME_INDICATOR[shmd]として定義されています。私は次のエラーを取得する-1d metric('blah', 'blah', 'blah')

を考えられるトークンの1つである場合、dの文字でTIME_INDICATORがどのように欠落しているかわかりません。私はここで何が欠けていますか?

私はANTLR4から生成されたPython3を使用しています。

+0

リンクが壊れています!正しいものは 'Metrink.g4'です(大文字のMを使用) – Athafoud

答えて

4

私が通常行っていることは、最初にトークンをダンプして、パーサーが期待する実際のトークンが作成されているかどうかを確認することです。

あなたが行うことができます(簡単にはPythonに移植)、このような小さなテストクラスを持つ:

input: `-1d metric('blah', 'blah', 'blah')` 
    MINUS    - 
    INTEGER_LITERAL  1 
    IDENTIFIER   d 
    METRIC    metric 
    LPAREN    (
    STRING_LITERAL  'blah' 
    COMMA    , 
    STRING_LITERAL  'blah' 
    COMMA    , 
    STRING_LITERAL  'blah' 
    RPAREN    ) 
:あなたは上記のコードを実行した場合

public class Main { 

    static void test(String input) { 

     metrinkLexer lexer = new metrinkLexer(new ANTLRInputStream(input)); 
     CommonTokenStream tokenStream = new CommonTokenStream(lexer); 
     tokenStream.fill(); 

     System.out.printf("input: `%s`\n", input); 

     for (Token token : tokenStream.getTokens()) { 
      if (token.getType() != TLexer.EOF) { 
       System.out.printf(" %-20s %s\n", metrinkLexer.VOCABULARY.getSymbolicName(token.getType()), token.getText()); 
      } 
     } 

     System.out.println(); 
    } 

    public static void main(String[] args) throws Exception { 
     test("-1d metric('blah', 'blah', 'blah')"); 
    } 
} 

、以下をごコンソールに出力されます

ご覧のとおり、dTIME_INDICATORの代わりにIDENTIFIERとトークン化されています。これは、お客様のTIME_INDICATORルールの前にIDENTIFIERルールが定義されているためです。レクサーはパーサーが必要とするものを「聴いていない」、可能な限り多くの文字を単にマッチさせ、2つ以上のルールが同じ量の文字に一致する場合、最初に定義されたルールが「勝つ」。

したがって、dは、TIME_INDICATORまたはIDENTIFIERとしてトークン化できます。これは文脈に依存している場合、私はあなたがIDENTIFIERとしてそれをトークン化(およびTIME_INDICATORを削除)を提案し、このようなパーサールール作成:FALSE、またSemantic predicates in ANTLR4?

{ ... }?が述語と呼ばれる

relative_time_literal: 
    MINUS? INTEGER_LITERAL time_indicator; 

time_indicator: 
    {_input.LT(1)getText().matches("[shmd]")}? IDENTIFIER; 

TRUEは、IDENTIFIERルールの前に置く必要があります。

+0

トークンの印刷を含めるようにコードを更新しました:https://github.com/Metrink/metrink-fe/commit/2ea0dcede1d5febb37374fa43b056953d434fe66 – wspeirs

関連する問題