我正在开发一种语言,其中有一个定义对象的外部语法和一个定义代码的内部语法。内部语法嵌入在各个地方。内部语法以 BEGIN 开始,以 END 结束。这很简单,除了内部代码语法也可以在代码内有多个 BEGIN/END block 。所以我的问题是,当我到达最后一个匹配的 END 对时,我可以仅将 BEGIN/END 对的计数引用到 popmode 吗?我猜这一定是可能的,但我只是不确定如何在 ANTLR 中最好地做到这一点。下面是语法的一个小例子:
procedure Foobar(somethingHappens: boolean)
var
MyRecord: Record "Some Table";
MyDecimal: Decimal;
otherBoolean: Boolean;
begin
if (somethingHappens) then
BEGIN
// do some stuff
END
// do other stuff
end;
我有很多单词在外部语法中是特殊标记,但可以在内部语法中用作代码中的普通标识符,因此我需要两种模式。
最佳答案
是的,您可以通过在 @lexer::members {} block 中定义适当的变量并在附加到词法分析器规则的操作中操作它来引用计数 BEGIN/END 对,有条件地调用 PushMode() 和 popMode() 或许还有 _modeStack.peek()。但您可能不需要。
根据您的 BEGIN 规则pushMode(BEGINEND_MODE)
。
编写一条附加规则来匹配 BEGINEND_MODE 中的 BEGIN,该规则执行相同的操作,递归地输入 BEGINEND_MODE。
在 BEGINEND_MODE 中编写一条执行 popMode()
的 END 规则。
BEGIN:
'BEGIN'
->pushMode(BEGINEND_MODE)
;
[...]
mode BEGINEND_MODE;
BEGIN1:
'BEGIN'
->pushMode(BEGINEND_MODE),type(BEGIN)
;
END:
'END'
->popMode()
;
[...]
关于antlr - 您可以有条件地更改 ANTLR 词法分析器模式吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/77470874/