Antlr 4:是否可能获得这种形式的输出?

Antlr 4: Is getting this form of output possible?

在扫描上下文中,当我的文本被扫描时,我需要覆盖、扩展、收听、访问什么才能打印出这种形式的信息输出?

-- Example output only ---------
DEBUG ... current mode: DEFAULT_MODE
DEBUG ... matching text '#' on rule SHARP ; pushing and switching to DIRECTIVE_MODE
DEBUG ... matching text 'IF" on rule IF ; pushing and switching to IF_MODE
DEBUG ... matching text '          ' on rule WS; skipping
DEBUG ... no match for text %
DEBUG ... no match for text &

DEBUG ... mathcing text '\r\n' on rule EOL; popping mode; current mode: DIRECTIVE_MODE
...

谢谢

解决方案比我想象的要简单得多。 您只需要将生成的 Lexer 子类化并覆盖 popMode()、pushMode() 等方法即可获得您想要的打印输出。如果您这样做,您还应该重写 emit() 方法以获取正确的顺序和上下文信息。

这是一个 C# 示例:

class ExtendedLexer : MyGeneratedLexer
{
public ExtendedLexer(ICharStream input)
    : base(input)  { }
public override int PopMode()
{
    Console.WriteLine($"Mode is being popped: Line: {Line} Column:{Column} ModeName: {ModeNames[ModeStack.Peek()]}");
    return base.PopMode();
}
public override void PushMode(int m)
{
    Console.WriteLine($"Mode is being pushed: Line: {Line} Column:{Column} ModeName: {ModeNames[m]}");
    base.PushMode(m);
}
public override void Emit(IToken t)
{
    Console.WriteLine($"[@{t.TokenIndex},{t.StartIndex}:{t.StopIndex}, <{Vocabulary.GetSymbolicName(t.Type)}> = '{t.Text}']");
    base.Emit(t);
}

}

输出会是这样的:

Mode is being pushed: Line: 4 Column:3 ModeName: IF_MODE
[@-1,163:165, <IF> = '#IF']
Mode is being pushed: Line: 4 Column:4 ModeName: CONDITION_MODE
[@-1,166:166, <LPAREN> = '(']
[@-1,167:189, <EXP> = '@setStartDateAndEndDate']
Mode is being popped: Line: 4 Column:28 ModeName: IF_MODE
[@-1,190:190, <RPAREN> = ')']