gpt4 book ai didi

dynamic - Antlr 4 停用左递归规则中的子规则

转载 作者:行者123 更新时间:2023-12-05 08:00:16 28 4
gpt4 key购买 nike

我正在为序言写一个解析器,以下是源代码的一部分。 “arg_term”和“term”非常相似,但是它不能匹配','表达式,因为我需要统计参数的个数。 “arg_item”需要匹配 ',' 表达式,所以我创建了两个相似的规则。我尝试使用语义谓词,但 Antlr 4 报告编译错误。现在似乎不支持直接左递归规则中的语义谓词。实现看起来很笨拙。谁能提供更好的解决方案?

我对 Antlr 和编译器的实现不是很熟悉。在序言中,用户可以定义自己的运算符和相关的优先级。如何应对此类情况?现在我只是忽略它们的优先级并将它们放在“术语”规则的末尾。

arguments returns [ int argc ]  //return argument number
:
arg {$argc = 1; } (',' arg {$argc = $argc + 1;} )*
;

arg :
arg_term
| '(' arg_item ')'
| '{' arg_item '}'
;

arg_item:
':-' term
| term ':-' term
| term
;

arg_term :
simple_term
|'(' arg_term ')'
| ('+'|'-') arg_term //here '+, -' denotes number's sign.
| arg_term ('**'|'^'|'isa'|'has') arg_term
| arg_term ('//' | 'mod' | 'rem' | '<<' | '>>' |'*' |'/') arg_term
| arg_term ('+'|'-'|'#') arg_term
| arg_term ':' arg_term
| arg_term (OP_XFY_700|'<'|'>'|'=') arg_term
| '\\+' arg_term
| arg_term '->' arg_term
| arg_term ';' arg_term
| OP_FX_1150 arg_term
| arg_term user_op arg_term
;

term
:
simple_term
|'(' term ')'
| ('+'|'-') term
| term ('**'|'^'|'isa'|'has') term
| term ('//' | 'mod' | 'rem' | '<<' | '>>' |'*' |'/') term
| term ('+'|'-'|'#') term
| term ':' term
| term (OP_XFY_700|'<'|'>'|'=') term
| '\\+' term
| term ',' term
| term '->' term
| term ';' term
| OP_FX_1150 term
| term user_op term
;

最佳答案

1) ANTLR4 中的语义谓词自 v3 以来发生了变化(参见 here)。

2) 要清理您的 arg_termterm 作品,请尝试类似于此语法片段的操作:

grammar Prolog;

...

argTerm: term (',' term)*;

term :
simpleTerm
|'(' term ')'
| ('+'|'-') term
| term ('**'|'^'|'isa'|'has') term
| term ('//' | 'mod' | 'rem' | '<<' | '>>' |'*' |'/') term
| term ('+'|'-'|'#') term
| term ':' term
| term (OP_XFY_700|'<'|'>'|'=') term
| '\\+' term
| term '->' term
| term ';' term
| OP_FX_1150 term
| term user_op term
;

...

3) 与其将 Java 代码嵌入语法中,不如使用 ANTLR4 生成的 ParseTreeVisitor .

您可以使用命令行中的 -visitor 参数生成 PrologBaseVisitor:

org.antlr.v4.Tool -visitor Prolog.g4

这是一个扩展生成的 PrologBaseVisitor 的实现示例,它将计算您的参数:

public class ProglogArgCountVis extends PrologBaseVisitor<Integer> {

// By default, all productions will return 0.
@Override
protected Integer defaultResult() {
return 0;
}

// Return the size of ctx.term(), which is a list of
// TermContexts... see generated parser code.
@Override
public Integer visitArgTermContext(ArgTermContext ctx) {
return ctx.term().size();
}

}

使用这个访问者看起来像这样:

PrologParser p;

....

Integer argCount = new PrologArgCountVis().visit(p.argTerm());

用户定义的优先级很容易实现。我认为处理这种情况的最佳方法是定义另一个 PrologBaseVisitor,让它检查它访问的每个运算符的优先级并相应地进行评估。

关于dynamic - Antlr 4 停用左递归规则中的子规则,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18565020/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com