Antlr4 - 将标识符作为单个标记进行匹配

Antlr4 - matching an identifier as a single token

BLOCK_COMMENT : '/*' .*? '*/' -> skip;
EOL_COMMENT : '//' ~[\r\n]* -> skip;
WS: [ \n\t\r]+ -> skip;

program: usingDirectives? EOF;

usingDirectives: usingDirective+;

usingDirective: USING
        fullyQualifiedType
        (usingAlias | USING_ALL)?
        END;

USING: 'using';

fullyQualifiedType: identifier (DOT identifier)*;

identifier: (LETTER | UNDERSCORE)
        (LETTER | DIGIT | UNDERSCORE)*;

DOT: '.';

usingAlias: AS identifier;

USING_ALL: '.*';

AS: 'as';

END: ';';

LETTER: [a-zA-Z];

DIGIT: [0-9];

UNDERSCORE: '_';

这是我的语法。

using IO.Console.Print as Print;
using IO.Console; // same as using IO.Console as Console;
using IO.Console.*;

这是我的测试数据。

语法按预期工作,但标识符中的每个字母都变成一个标记,这有点没用。

如果我尝试使标识符成为词法分析器规则 (IDENTIFIER),那么我会收到以下错误,当 运行 测试时:

line 1:23 extraneous input 'as' expecting {'.', '.*', 'as', ';'}

即使我尝试让 IDENTIFIER 只是 [a-zA-Z],没有子规则,同样的情况也会发生。

如果重要的话,我使用 Python3 作为目标语言。 请指出任何其他菜鸟错误,因为这是我使用 Antlr 的第一个项目。谢谢!

现在你告诉你的词法分析器产生一组适合标识符的字符,而不是整个标识符。以下简化语法(词法分析器和解析器)应该适合你:

grammar test;

root
    : identifier*;

identifier
    : IdentifierChars;

IdentifierChars
    : [a-zA-Z0-9_]+;

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

这是我用来检查的示例 Java 代码:

    InputStream input = IntegrationMain.class.getResourceAsStream("test.txt");
    ANTLRInputStream inputStream = new ANTLRInputStream(input);
    TokenSource tokenSource = new testLexer(inputStream);
    CommonTokenStream tokenStream = new CommonTokenStream(tokenSource);
    testParser parser = new testParser(tokenStream);
    testParser.RootContext root = parser.root();

    root.identifier().forEach(identifier -> System.out.println(identifier.getText()));

这是标准输出的结果:

abc
a0bc
a_bc