将标记移动到公共文件之前的语法
lexer grammar ALexer;
COMMAND_START
: [a-zA-Z] -> pushMode(COMMAND_MODE)
;
EQUALS
: '=' -> pushMode(VALUE_MODE)
;
mode COMMAND_MODE;
COMMAND_NAME_REMAINDER
: ([a-zA-Z0-9_ ]? [a-zA-Z0-9])* -> popMode
;
mode VALUE_MODE;
IDENTIFIER
: A_Z ((UNDERSCORE | A_Z | DIGIT | WS)*? (UNDERSCORE | A_Z | DIGIT))* -> popMode
;
将标记移动到公共文件后的语法
通用lexer由其他3个lexer导入。它具有共享的标识符令牌。
lexer grammar CommonLexer;
..
..
IDENTIFIER
: A_Z ((UNDERSCORE | A_Z | DIGIT | WS)*? (UNDERSCORE | A_Z | DIGIT))*
;
以下lexer导入通用lexer,并具有几种模式
lexer grammar ALexer;
import CommonLexer;
COMMAND_START
: [a-zA-Z] -> pushMode(COMMAND_MODE)
;
EQUALS
: '=' -> pushMode(VALUE_MODE)
;
mode COMMAND_MODE;
COMMAND_NAME_REMAINDER
: ([a-zA-Z0-9_ ]? [a-zA-Z0-9])* -> popMode
;
mode VALUE_MODE;
IDENTIFIER_VALUE_MODE
: IDENTIFIER -> type(IDENTIFIER), popMode
;
解析器语法:
parser grammar AParser;
options { tokenVocab=ALexer; }
genericCommand
: COMMAND_START COMMAND_NAME_REMAINDER? (COLON parameterArray)?
;
结果:一个命令,如“删除资源:A先前标识为COMMAND\u START now的将被识别为标识符。
结果屏幕截图
问题:我如何解决这个问题?标识符应保留在CommonLexer中。
如果您需要更多详细信息,请告诉我,谢谢。
我不能确定(你只是在通用Lexer提取中有日蚀),但是在原始Lexer语法中,IDENTIFIER只有在你被推送VALUE_MODE时才会匹配。当你创建通用Lexer时,你似乎已经失去了这个特性。因为它在通用Lexer中是“公开的”,所以它会匹配你是否VALUE_MODE(长度会使它更强)。这解释了不同的行为。
您的IDENTIFIER lexer规则匹配的字符串比COMMAND_START长,因此它将优先。您不会在COMMAND_START规则上得到“命中”以将您推入COMMAND_MODE。这是您问题的核心。您的IDENTIFIER规则与COMMAND_START规则重叠,并且始终至少与COMMAND_START规则匹配一样长(1个字符)或更长,因此ANTLR将始终支持它。
如果没有A_Z、UNDERSCORE、DIGIT和WS的片段定义(您将它们用作片段,所以我假设它们是),则很难确定您打算在COMMAND和IDENTIFIER之间做什么区别。
您COMMAND_START触发模式却立即弹出它的方式是“不寻常的”。我希望看到包含整个模式的COMMAND Lexer规则:
COMMAND: [a-zA-Z]([a-zA-Z0-9_ ]? [a-zA-Z0-9])*
在这里,我无法真正区分输入流中的命令和标识符。(在令牌中包含WS也是一种反模式)。
这是您可以控制语言设计的地方,还是您必须符合既定定义的地方?
如果你有控制权,我建议你读一读,重新考虑你的方法。
如果它已经建立,也许您可以分享建立的定义以及它如何区分IDENTIFIER和COMMAND。
从这里的行中可以看出,冒号之前的任何内容都是命令,冒号之后的任何内容都是需要标识符的地方。
我认为您试图在Lexer中投入太多工作。尝试将您的命令解析器规则重新思考为更像解析器规则的东西:
genericCommand: +IDENTIFIER (COLON parameterArray)?;
(如果可以管理的话,我建议从命令和标识符标记中删除WS。这往往会产生各种各样的标记化歧义问题。)
如何实现这些模式?
我有一个这样的可重装武器类: 具有以下: 并像这样使用它: 客户: 我想知道,对于命令,对于我看到的示例,除了命令正在操作的对象之外,没有其他。 此示例更改执行方法以允许使用参数。 另一个示例,更接近我在这里拥有的,在构造函数中使用参数。 在命令中包含参数是不是不好的做法/代码气味,在这种情况下是带有项目符号数的?
是否有方法为模式中捕获的所有字符返回一个字符串类型的标记,包括导致进入模式的字符? 模式何时结束? 我知道我也可以像这样编写字符串标记:
如果我对“令牌”不感兴趣,因为规则已经建立了我要匹配的对象,而且我无论如何都要跳过它,那么用和令牌声明替换它有意义吗?(然后,代币的数量将会增加。)为什么在ANTLRWorks中这是一个警告?
我是一个Antlr4新手,有一个相对简单的语法问题。语法在末尾的底部给出。(这是一个语法片段,用于分析生物序列变体的描述)。 在下面的单元测试中,我试图解析字符串。 这里出了什么问题?我在哪里可以学习如何解决这个问题?
我有不同实现的< code>ProductHandler类,例如< code>ABCProductHandler、< code>DEFProductHandler等..它们是使用如下所示的命令模式从< code>ProductServiceImpl类调用的。 产品ServiceImpl类: 但是,我对上面的 类不满意,因为有很多带有样板代码的产品 调用。 现在,我的问题是,有什么方法可以轻松加载?