简体   繁体   English

在ANTLR BNF语法符号中,epsilon的等价物是什么?

[英]What is the equivalent for epsilon in ANTLR BNF grammar notation?

During taking advantage of ANTLR 3.3, I'm changing the current grammar to support inputs without parenthesis too. 在利用ANTLR 3.3时,我正在改变当前语法以支持没有括号的输入。 Here's the first version of my grammar : 这是我的语法的第一个版本:

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; } ;

Then I changed it this way to support the appropriate features : 然后我改变它以支持适当的功能:

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; } ;

But I've been faced with following error : 但我一直面临以下错误:

error<100>:  syntax error: invalid char literal: ''
error<100>:  syntax error: invalid char literal: ''

Does anybody know that how can I overcome this error? 有谁知道我怎么能克服这个错误?

Your EM token: 您的EM令牌:

EM : '' ;

is invalid: you can't match an empty string in lexer rules. 无效:您无法匹配词法规则中的空字符串。

To match epsilon (nothing), you should do: 要匹配epsilon(无),你应该这样做:

rule 
  :  A 
  |  B 
  |  /* epsilon */ 
  ;

Of course, the comment /* epsilon */ can safely be removed. 当然,可以安全地删除注释/* epsilon */

Note that when you do it like that in your current grammar, ANTLR will complain that there can be rules matched using multiple alternatives. 请注意,当您在当前语法中执行此操作时,ANTLR会抱怨可以使用多个备选方案匹配规则。 This is because your grammar is ambiguous. 这是因为你的语法含糊不清。

I'm not an ANTLR expert, but you might try: 我不是ANTLR专家,但您可以尝试:

formula : term ((AND | OR | IMPLIES ) term )*;
term :  OP formula CP | NOT term | SYMBOL ;

If you want traditional precedence of operators this won't do the trick, but that's another issue. 如果你想要传统的运算符优先级,这将无法解决问题,但这是另一个问题。

EDIT: OP raised the ante; 编辑:OP提高了赌注; he wants precedence too. 他也想要优先权。 I'll meet him halfway, since it wasn't part of the orginal question. 我会中途见到他,因为它不是原始问题的一部分。 I've added precedence to the grammar that makes IMPLIES the lower precedence than other operators, and leave it to OP to figure out how to do the rest. 我已经在语法中添加了优先级,使IMPLIES的优先级低于其他运算符,并将其留给OP来弄清楚如何完成剩下的操作。

 formula:  disjunction ( IMPLIES disjunction )* ;
 disjunction:  term (( AND | OR ) term )* ;
 term:  OP formula CP | NOT term | SYMBOL ;

OP additionally asked, "how to convert (!p or q ) into p -> q". OP另外问,“如何将(!p或q)转换为p - > q”。 I think he should have asked this as a separate question. 我认为他应该把这个问题作为一个单独的问题。 However, I'm already here. 但是,我已经在这里了。 What he needs to do is walk the tree, looking for the pattern he doesn't like, and change the tree into one he does, and then prettyprint the answer. 他需要做的是走树,寻找他不喜欢的模式,然后将树改成他所做的一个,然后将答案弄清楚。 It is possible to do all this with ANTLR, which is part of the reason it is popular. 使用ANTLR可以做到这一切,这也是它受欢迎的部分原因。

As a practical matter, procedurally walking the tree and checking the node types, and splicing out old nodes and splicing in new is doable, but a royal PitA. 作为一个实际问题,程序性地走树和检查节点类型,拼接旧节点和拼接新的是可行的,但是皇家PitA。 Especially if you want to do this for lots of transformations. 特别是如果你想要进行大量的转换。

A more effective way to do this is to use a program transformation system , which allows surface syntax patterns to be expressed for matching and replacement. 更有效的方法是使用程序转换系统 ,该系统允许表达表面语法模式以进行匹配和替换。 Program transformation systems of course include parsing machinery and more powerful ones let you (and indeed insist) that you define a grammar up front much as you for ANTLR. 程序转换系统当然包括解析机制和更强大的程序,让你(并且确实坚持)你为ANTLR预先定义一个语法。

Our DMS Software Reengineering Toolkit is such a program transformation tool, and with a suitably defined grammar for propositions, the following DMS transformation rule would carry out OP's additional request: 我们的DMS软件再造工具包是一个程序转换工具,并且具有适当定义的命题语法,以下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 ";

The " ... " is "domain notation", eg, surface syntax from the proplogic domain, the "\\" are meta-escapes, so "\\p" and "\\q" represent any arbitrary term from the proplogic grammar. “...”是“域符号”,例如来自proplogic域的表面语法,“\\”是元转义,因此“\\ p”和“\\ q”表示来自proplogic语法的任意术语 Notice the rule has to reach "across" precedence levels when being applied, as "NOT \\p OR \\q" isn't a formula and "\\p IMPLIES \\q" is; 请注意,规则在应用时必须达到“跨越”优先级,因为“NOT \\ p OR \\ q”不是公式,“\\ p IMPLIES \\ q”是; DMS takes care of all this (the "formula -> formula" notation is how DMS knows what to do). DMS处理所有这些(“公式 - >公式”表示法是DMS知道该怎么做)。 This rule does a tree-to-tree rewrite. 此规则执行树到树的重写。 The resulting tree can be prettyprinted by DMS. 生成的树可以由DMS进行精心打印。

You can see a complete example of something very similar, eg, a grammar for conventional algebra and rewrite rule to simplify algebraic equations . 您可以看到非常相似的完整示例,例如, 常规代数的语法和简化代数方程的重写规则

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

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