是否可以使用JavaCC解析器来解析String并对其应用分配律?

时间:2014-01-17 12:54:02

标签: parsing javacc

例如在我的情况下,

给定字符串keyword1 AND (keyword2 OR keyword3)必须扩展为(keyword1 AND Keyword2) OR (keyword1 AND keyword3)

如果可能的话,请建议我实现这一目标的方式。我是JavaCC的新手。

1 个答案:

答案 0 :(得分:1)

要完成任务,您需要:

  • 布尔表达式的语法
  • 您的布尔语言的解析器
  • 解析步骤中的AST构建
  • 一些机制(树匹配/黑客)来实现你的重写规则。

JavaCC为您提供了一个解析器;你必须提供语法。 JavaCC本身并没有提供构建树的任何特定帮助,但是相关的包JJTree使这更容易。它为重写步骤提供零帮助;你必须在程序上实现这个,这意味着在树中上下移动以匹配OR中的AND(你的分配法的基础起点,然后黑客攻击树链接以转换树。最后,你要打印修改后的树退出; JavaCC在这里也没有提供任何帮助。

ANTLR4离得更近了。你提供一个语法;显然它会自动构建一棵树。与JavaCC一样,您必须在程序上实现重写步骤。它不会单独打印修改后的树,但它会帮助完成任务所谓的StringTemplates。

一般来说,你真正想要的是program transformation system,它可以让你以有条理的方式完成所有这些任务。

我们的DMS就是其中之一,可以轻松解决这个问题。您为DMS提供语法。它在解析时自动构建树。您根据语法的表面语言为DMS提供了模式导向的重写规则; DMS将应用它们并修改树木。作为指定解析器的一部分,您还指定(轻松)漂亮的打印规则,因此很容易得到修改后的结果。

使用这种DMS语法(这会跳过词法分析器步骤,但这很容易):

    BOOLEXP = disjunction ;
    disjunction = conjunction ;
    [associative-commutative] disjunction = disjunction 'OR' conjunction ;
    conjunction = term ;
    [associative-commutative] conjunction = conjunction 'AND' term ;
    term = VARIABLENAME ;
    term = '(' disjunction ')' ;
    term = 'NOT' term ;

“[associative-commutative]”部分告诉DMS这些规则具有那些代数属性(“AC”)。

然后,此DMS重写规则直接实现您的请求:

     rule apply_distributive_law(t1:term,t2:disjunction,t3:conjunction):disjunction->disjunctions
          = "\t1 AND ( \t2 OR \t3 ) " ->  " \t1 AND \t2 OR \t1 AND \t3 "; 

请注意我们如何不谈论树木,更不用说操纵它们了。不明显的是,这不仅与所提供的特定模式相匹配,而且与这些术语的任何AC重新排列相匹配。这在程序上很难编码。

因为重写很容易,所以当有人以否定的形式写出你的情况时,我们也可以选择这种情况:

     rule  apply_demorgan(t1:term, t2: conjunction): disjunction -> disjunction
          = " NOT ( \t1 AND \t2 ) " ->   " NOT \t1 OR NOT (\t2) ";

应该很容易看出如何从这里写出针对NOT-OR的DeMorgan定律。默认情况下,DMS会应用您提供的所有规则,直到不再适用其他规则为止。如果你同意上述两条规则,它将使用apply_demorgan转换为否定形式,然后转换为分配法则。随着您添加更多规则,效果可能非常显着,并且很难使用过程代码进行复制。

你可以看到a fully worked example on conventional algebra(而不是布尔代数)。出现了所有相同的问题。