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

时间:2017-04-02 12:45:12

标签: python parsing antlr antlr4 lexer

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的第一个项目。谢谢!

1 个答案:

答案 0 :(得分:1)

现在你告诉你的词法分析器产生一个适合标识符而不是标识符的字符集合。遵循简化的语法(词法分析器和解析器)应该适合您:

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()));

这是stdout的结果:

abc
a0bc
a_bc