私が通常行っていることは、最初にトークンをダンプして、パーサーが期待する実際のトークンが作成されているかどうかを確認することです。
あなたが行うことができます(簡単には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')");
}
}
、以下をごコンソールに出力されます
ご覧のとおり、d
はTIME_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
ルールの前に置く必要があります。
リンクが壊れています!正しいものは 'Metrink.g4'です(大文字のMを使用) – Athafoud