例如,我在语法中定义了几个词法分析器规则:
INT: 'int';
FLOAT: 'float';
...
DIGIT : [0-9];
NUMERIC : (DIGIT+ | DIGIT+ '.' DIGIT+ | '.' DIGIT+ | DIGIT+ '.');
...
我需要以某种方式标记关键字("int"、"float"和其他一些关键字),当我使用 TokenStream 获取令牌时,我可以通过一些自定义符号过滤它们。
可能吗?
现在我只看到一种方法 - 将必要的词法分析器合并为某种规则。
更新
我尝试应用下面第一个答案的第一个选项,但遇到下一个问题: 我收到错误:"令牌名称不是可识别的令牌名称">
因为这个案子是个问题。 我从这里应用建议:
用
options { tokenVocab = MyLexer; }
而不是
import MyLexer;
并得到错误:">错误(114):MyParser.g4:3:23:找不到令牌文件.\MyLexer.tokens">
这里说,我如何理解,当ANTLR源文件(MyParser.g4,MyLexer.g4)放置在放置生成包的同一目录中时,可能会发生这种情况。但是我将输出文件的属性设置为另一个目录。 也许我得到了一些错误的理解...
这里有一个小例子。
根据您使用词法分析器的其他内容,您可以探索 2 种途径。
-
用于重新映射令牌的
type()
词法分析器命令。以那里的文档为例:
lexer grammar SetType; tokens { STRING } DOUBLE : '"' .*? '"' -> type(STRING) ; SINGLE : ''' .*? ''' -> type(STRING) ; WS : [ rtn]+ -> skip ;
这将允许单个类型
STRING
的多个规则,即您将在流中收到的令牌类型。 -
channel()
命令,在拥有令牌流后,可用于标记和筛选令牌。这样做的好处是,如果之后仍需要解析,则保留原始词法分析器流。再次,从antlr文档中窃取示例:
BLOCK_COMMENT : '/*' .*? '*/' -> channel(HIDDEN) ; LINE_COMMENT : '//' ~[rn]* -> channel(HIDDEN) ;