例如在我的情况下,
给定字符串keyword1 AND (keyword2 OR keyword3)
必须扩展为(keyword1 AND Keyword2) OR (keyword1 AND keyword3)
。
如果可能的话,请建议我实现这一目标的方式。我是JavaCC的新手。
答案 0 :(得分:1)
要完成任务,您需要:
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(而不是布尔代数)。出现了所有相同的问题。