在利用ANTLR 3.3时,我正在改变当前语法以支持没有括号的输入。这是我的语法的第一个版本:
grammar PropLogic;
NOT : '!' ;
OR : '+' ;
AND : '.' ;
IMPLIES : '->' ;
SYMBOLS : ('a'..'z') | '~' ;
OP : '(' ;
CP : ')' ;
prog : formula EOF ;
formula : NOT formula
| OP formula( AND formula CP | OR formula CP | IMPLIES formula CP)
| SYMBOLS ;
WHITESPACE : ( '\t' | ' ' | '\r' | '\n'| '\u000C' )+ { $channel = HIDDEN; } ;
然后我改变它以支持适当的功能:
grammar PropLogic;
NOT : '!' ;
OR : '+' ;
AND : '.' ;
IMPLIES : '->' ;
SYMBOL : ('a'..'z') | '~' ;
OP : '(' ;
CP : ')' ;
EM : '' ;
prog : formula EOF ;
formula : OP formula( AND formula CP | OR formula CP | IMPLIES formula CP)
| ( NOT formula | SYMBOL )( AND formula | OR formula | IMPLIES formula | EM ) ;
WHITESPACE : ( '\t' | ' ' | '\r' | '\n'| '\u000C' )+ { $channel = HIDDEN; } ;
但我一直面临以下错误:
error<100>: syntax error: invalid char literal: ''
error<100>: syntax error: invalid char literal: ''
有人知道我该如何克服这个错误?
答案 0 :(得分:7)
您的EM
令牌:
EM : '' ;
无效:您无法匹配词法规则中的空字符串。
要匹配epsilon(无),你应该这样做:
rule
: A
| B
| /* epsilon */
;
当然,可以安全地删除评论/* epsilon */
。
请注意,当您在当前语法中执行此操作时,ANTLR会抱怨可以使用多个备选方案匹配规则。这是因为你的语法含糊不清。
答案 1 :(得分:2)
我不是ANTLR专家,但您可以尝试:
formula : term ((AND | OR | IMPLIES ) term )*;
term : OP formula CP | NOT term | SYMBOL ;
如果你想要运营商的传统优先权,这将无法解决问题,但这是另一个问题。
编辑:OP提高了赌注;他也想要优先权。我会中途见到他,因为它不属于他 原始问题。我已经为使IMPLIES的语法添加了优先权 优先于其他运算符的优先级,并留给OP来弄清楚如何完成其余操作。 formula: disjunction ( IMPLIES disjunction )* ;
disjunction: term (( AND | OR ) term )* ;
term: OP formula CP | NOT term | SYMBOL ;
OP还问道,“如何将(!p或q)转换为p - > q”。我想他应该 将此问作为一个单独的问题。但是,我已经在这里了。 他需要做的是走树,寻找他没有的模式 喜欢,并将树改成他所做的一个,然后将答案弄清楚。 使用ANTLR可以做到这一切,这也是原因之一 它很受欢迎。
实际上,在程序上走树并检查节点 类型,拼接旧节点和拼接新的是可行的,但皇家PitA。 特别是如果你想要进行大量的转换。
更有效的方法是使用a program transformation system,允许表达表面语法模式以进行匹配和替换。程序转换系统当然包括解析机制和更强大的程序,让你(并且确实坚持)你定义 与ANTLR一样,前面的语法很多。
我们的DMS Software Reengineering Toolkit是一个程序转换工具,并且具有适当定义的命题语法, 以下DMS转换规则将执行OP的附加请求:
domain proplogic; // tell DMS to use OP's definition of logic as a grammar
rule normalize_implies_from_or( p: term, q: term): formula -> formula
" NOT \p OR \q " -> " \p IMPLIES \q ";
“...”是“域名表示法”,例如,来自proplogic域的表面语法,“\”是元逃逸, 所以“\ p”和“\ q”代表proplogic语法中的任意术语。请注意,规则在应用时必须达到“跨越”优先级,因为“NOT \ p OR \ q”不是公式,“\ p IMPLIES \ q”是; DMS负责所有这些(“公式 - &gt;公式”符号是DMS知道该怎么做的表示法)。此规则执行树到树的重写。生成的树可以由DMS进行漂亮打印。
您可以看到非常相似的完整示例,例如a grammar for conventional algebra and rewrite rule to simplify algebraic equations。