繁体   English   中英

将BNF语法转换为Java

[英]Convert BNF grammar to Java

如何将这种简单的(递归)语法转换为Java?

C --> a | not C | C and C | C or C ;

这个问题并不意味着我必须使用哪种工具来解析语法(例如Javacc或Antlr),而是使用面向对象范例对这种简单语法建模的方式。

这是一个非常广泛的问题,无需实际提及特定的工具即可回答,因为任何语法的实现都可能以多种方式发生,具体取决于您选择使用哪种语言来实现解析器...如果您查看这些工具的来源就像您提到的ANTLR和Javacc一样,它将揭示其他人如何实现他们的工具以及他们用于开发自上而下的解析器等的技术,但是仅仅因为那是他们实现自己的工具的方式并不一定意味着唯一的方法。

BNF仅用于给出描述语言结构的正式方法:

它们可用于需要精确描述语言的地方:例如,官方语言规范,手册和编程语言理论教科书。

因为它们仅用于分解从输入到程序员的期望值,从而决定程序员如何使用语言工具和api来实现该实现,无论是Java中的regex还是字符串搜索或其他提供的标记化不幸的是,语言的选择完全取决于您的决定,除非您使用的是专门用于为您的语言生成解析器的工具,到那时我们可以回答这个问题是否可行。

我认为,没有一种方法可以使用OOP对其进行建模,并且可以使用许多同样有效的方法来实现这一目标。 以下是考虑代码中的外观的一种合理策略。

通常,在解析表达式时,您的目标是为输入重建抽象语法树。 该树结构根据可能的不同生成具有不同类型的节点,在Java中,您可能用某种多态类型来表示它们。 例如,你可能有一个基类ASTNode有孩子ANodeNotNodeAndNodeOrNode 最后三种类型将存储指向组成复合表达式的子表达式的指针。

一旦拥有了这些类型,就需要将某种解析器(可能还有扫描器)放在一起,它们将接受输入并从中构造适当的树。 由于您要查看的语法由具有不同优先级的不同运算符组成,因此您可以使用简单的优先级解析器(例如Dijkstra的shunting-yard算法)进行解析。 该算法相对容易实现。

在那时,它实际上取决于您要对AST进行的处理。 例如,如果要根据提供的输入来评估表达式,则可以向ASTNode类型添加evaluate的抽象方法,然后让每个派生类型提供执行适当操作的实现。 您还可以考虑使用访问者模式来构建沿AST走并在每个步骤执行适当操作的访问者。

我不确定这是否会有所帮助,但是不久前,我写了一些与您正在寻找的东西非常相似的东西,以便为我经常教授的课程的命题逻辑生成真值表。 该工具本身在此处可用 ,并且注释良好的源文件在此处可用 它是用JavaScript而不是Java编写的,但是它展示了上述所有内容-AST节点类型,用于解析的shunting-yard算法以及用于评估不同表达式的重写方法。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM