if then else 条件评估
我有一种语言,基本上是将列映射到数组中的新结构。该语言旨在让产品经理定义映射,而无需了解大量编程细节。我确信这里还有很多需要改进的地方,但这就是我所拥有的。
大多数情况下,语言是有效的。我遇到的问题是条件语句。
我的解析器具有以下规则:
conditionalexpr : IF^ LPAREN! (statement) RPAREN! THEN! LCURLY! statement RCURLY! (ELSE! LCURLY! statement RCURLY!)?;
它可以生成具有三个子级的树。
我的问题是在条件不允许的情况下避免评估语句。
我非常天真地这么做了:
conditionalexpr returns[Object o]:
^(IF a=statement b=statement (c=statement)?)
{
$o = (Boolean)$a.o ? $b.o : $c.o != null ? $c.o : "";
}
;
显然这是行不通的。
我一直在研究句法谓词,但我无法使它们正常工作。
语句当前返回一个对象。该语言主要处理字符串,但我也需要支持布尔值和数字(整数和小数)。
如果我添加类似 {$ao}?=> 的内容我在生成的代码中得到一个 $a 。
我查看了antlr兴趣列表,但这个问题并没有得到很好的回答,很可能是因为这对他们来说似乎是显而易见的。
我愿意发布完整的语法,但为了保持简短而将其省略。
I have a language which basically is meant to map columns to a new structure in an array. The language is meant for product managers to define mappings without having to know a lot of programming details. I'm sure there is a lot more to improve here but this is what I have.
The language works, mostly. The problem I have is with conditional statements.
My parser has the following rule:
conditionalexpr : IF^ LPAREN! (statement) RPAREN! THEN! LCURLY! statement RCURLY! (ELSE! LCURLY! statement RCURLY!)?;
Which works to generate a tree with three children.
My problem is to avoid evaluating the statements if the condition doesn't allow it.
Very naively I did:
conditionalexpr returns[Object o]:
^(IF a=statement b=statement (c=statement)?)
{
$o = (Boolean)$a.o ? $b.o : $c.o != null ? $c.o : "";
}
;
Obviously this will not work.
I have been playing around with syntactic predicates but I can't make those work properly.
statement returns an object currently. Mostly the language deals in Strings but I need to support booleans and numbers (integer and decimal) as well.
If I add anything like {$a.o}?=> I get a $a in the generated code.
I have looked on the antlr-interest list but this question is not really answered well there, most likely because it seems obvious to them.
I am willing to post the complete grammar but have left it out to keep this short.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
如果您不希望评估某些子树,则需要让树规则返回节点而不是实际值。您可以扩展 CommonTree 并提供自定义 TreeAdaptor 来帮助构建您自己的节点,但就我个人而言,我发现创建自定义节点类(或类)并使用是最简单的而是他们。澄清的演示:
Tg
Main.java
我创建了一个
Node
接口,它有一个eval(): Object
方法,还创建了一个抽象类BinaryNode
实现了Node
并且总是有 2 个子节点。正如您在这些 Java 类之后的树语法中所看到的,所有规则现在都返回一个Node
。TWalker.g
如果您现在运行主类,并评估:
true
正在打印到控制台:但是如果您检查
b
b
a
,导致执行else
,您将看到以下内容:对于更复杂的语言结构(作用域、函数等)的实现,请参见我的博客。
祝你好运!
If you don't want certain sub-trees to be evaluated, you'll need to let the tree rules return nodes instead of actual values. You can either extend
CommonTree
and provide a customTreeAdaptor
to help build your own nodes, but personally, I find it easiest to create a custom node class (or classes) and use them instead. A demo to clarify:T.g
Main.java
I've created a
Node
interface that has aeval(): Object
method, and also created an abstract classBinaryNode
which implementsNode
and will have always 2 children. As you can see in the tree grammar that follows after these Java classes, all rule now return aNode
.TWalker.g
If you now run the main class, and evaluate:
true
is being printed to the console:But if you check if
b < a
, causing theelse
to be executed, you'll see the following:For implementations of more complicated language constructs (scopes, functions, etc.), see my blog.
Good luck!