简体   繁体   English

将BNF语法转换为Java

[英]Convert BNF grammar to Java

How can I convert this simple (recursive) grammar to Java? 如何将这种简单的(递归)语法转换为Java?

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

This question is not meant what tool I have to use to parse a grammar (like Javacc or Antlr), but the way to model this simple grammar using the object-oriented paradigm. 这个问题并不意味着我必须使用哪种工具来解析语法(例如Javacc或Antlr),而是使用面向对象范例对这种简单语法建模的方式。

This is a very broad question to answer without actually mentioning specific tools as your implementation of any grammar could happen in a huge number of ways depending on which language you choose to implement your parser in...if you look at the source of tools such as the ones you mentioned ANTLR and Javacc it will reveal how others implemented their tools and the techniques they used to develop top down parsers etc but just because thats how they implemented theirs does not mean its necessarily the only way. 这是一个非常广泛的问题,无需实际提及特定的工具即可回答,因为任何语法的实现都可能以多种方式发生,具体取决于您选择使用哪种语言来实现解析器...如果您查看这些工具的来源就像您提到的ANTLR和Javacc一样,它将揭示其他人如何实现他们的工具以及他们用于开发自上而下的解析器等的技术,但是仅仅因为那是他们实现自己的工具的方式并不一定意味着唯一的方法。

The BNF is used only for giving a formal way of describing the structure of the language: BNF仅用于给出描述语言结构的正式方法:

They are applied wherever exact descriptions of languages are needed: for instance, in official language specifications, in manuals, and in textbooks on programming language theory. 它们可用于需要精确描述语言的地方:例如,官方语言规范,手册和编程语言理论教科书。

As they are only used to give a break down of what is expected from input its up to the programmer to decide how that is implemented with the language tools and api's available to them whether it be regex's in java or string searches or tokenizing provided by another language its unfortunately entirely your choice to decide thenless you are working with a tool specifically for generating a parser for your language at which point we could answer this question if it makes sense. 因为它们仅用于分解从输入到程序员的期望值,从而决定程序员如何使用语言工具和api来实现该实现,无论是Java中的regex还是字符串搜索或其他提供的标记化不幸的是,语言的选择完全取决于您的决定,除非您使用的是专门用于为您的语言生成解析器的工具,到那时我们可以回答这个问题是否可行。

I don't think there's a single way to model this using OOP and that there are many equally valid ways you could go about approaching this. 我认为,没有一种方法可以使用OOP对其进行建模,并且可以使用许多同样有效的方法来实现这一目标。 The following is one reasonable strategy for thinking about what this might look like in code. 以下是考虑代码中的外观的一种合理策略。

Usually, when parsing an expression, your goal is to reconstruct an abstract syntax tree for the input. 通常,在解析表达式时,您的目标是为输入重建抽象语法树。 That tree structure has different types of nodes based on the different productions that are possible, and in Java you'd probably represent them with some polymorphic type. 该树结构根据可能的不同生成具有不同类型的节点,在Java中,您可能用某种多态类型来表示它们。 For example, you might have a base class ASTNode that has children ANode , NotNode , AndNode , and OrNode . 例如,你可能有一个基类ASTNode有孩子ANodeNotNodeAndNodeOrNode These last three types would store pointers to the subexpressions that make up the compound expression. 最后三种类型将存储指向组成复合表达式的子表达式的指针。

Once you have these types, you'd then need to put together some sort of parser - and possibly a scanner - that would take the input and construct the appropriate tree from it. 一旦拥有了这些类型,就需要将某种解析器(可能还有扫描器)放在一起,它们将接受输入并从中构造适当的树。 Since you're looking at a grammar that consists of different operators with different precedences, you could use a simple precedence parser like Dijkstra's shunting-yard algorithm to do the parsing. 由于您要查看的语法由具有不同优先级的不同运算符组成,因此您可以使用简单的优先级解析器(例如Dijkstra的shunting-yard算法)进行解析。 That algorithm is relatively straightforward to implement. 该算法相对容易实现。

At that point it really depends on what you want to do with the AST. 在那时,它实际上取决于您要对AST进行的处理。 If you want to evaluate the expression depending on what inputs are provided, for example, you could add an abstract method evaluate to the ASTNode type and then have each derived type provide an implementation that performs the appropriate operation. 例如,如果要根据提供的输入来评估表达式,则可以向ASTNode类型添加evaluate的抽象方法,然后让每个派生类型提供执行适当操作的实现。 You could also consider using the visitor pattern to build visitors that walk the AST and perform appropriate operations at each step. 您还可以考虑使用访问者模式来构建沿AST走并在每个步骤执行适当操作的访问者。

I'm not sure whether this would be helpful, but a while back I wrote something very similar to what you're looking at to generate truth tables for propositional logic for a class I often teach. 我不确定这是否会有所帮助,但是不久前,我写了一些与您正在寻找的东西非常相似的东西,以便为我经常教授的课程的命题逻辑生成真值表。 The tool itself is available here , and the source files, which are decently well-commented, are available here . 该工具本身在此处可用 ,并且注释良好的源文件在此处可用 It's written in JavaScript rather than Java, but it shows off all the pieces described above - the AST node type, the shunting-yard algorithm to do parsing, and overridden methods to evaluate the different expressions. 它是用JavaScript而不是Java编写的,但是它展示了上述所有内容-AST节点类型,用于解析的shunting-yard算法以及用于评估不同表达式的重写方法。

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

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