ANTLR4无法正确管理左递归

时间:2016-08-23 13:53:34

标签: java intellij-idea antlr4

我试图用ANTLR4描述逻辑表达式的语法。 当然,这个语法有直接左递归,而且我读过ANTLR4支持它。

<html>
<link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/1.10.12/css/jquery.dataTables.min.css"/>
<div id="exampleDiv">hello</div>
<table width="100%" class="display" id="example">
  <thead>
    <tr>
      <th>Ticket RT</th>
      <th>Last up time</th>
      <th>Last down time</th>
      <th>Date du Diag RT</th>
      <th>Commentaire FT</th>
      <th>Code Retour FT</th>
      <th>Supprimer</th>
    </tr>
  </thead>
</table>

</html>
<script src="https://code.jquery.com/jquery-1.12.3.js" ></script>
<script src="https://cdn.datatables.net/1.10.12/js/jquery.dataTables.min.js" ></script>
<script>
$(document).ready(function() {
  $('#example').DataTable({
    "bProcessing": true,
      "ajax": {
    "url": "http://www.json-generator.com/api/json/get/bUCyQgmGeW?indent=2",
    "dataSrc": "syncok"
      },
      "columns": [
    { "data": "Ticket_RT" },
    { "data": "Code_Retour_FT" },
    { "data": "Date_du_Diag_RT" },
    { "data": "Last_up_time" },
    { "data": "Supprimer" },
    { "data": "Last_down_time" },
    { "data": "Commentaire_FT" }
      ]
    });
});

</script>

但是当我运行antlr为我的语法生成解析器时,它会产生一些奇怪的错误:

grammar Logic;
@header {
package parser;
import expression.*;
}

expression returns [Expression value] : disjunction {$value = $disjunction.value;}
                                      | disjunction IMPLIES expression {$value = new Implication($disjunction.value, $expression.value);};

disjunction returns [Expression value] : conjunction {$value = $conjunction.value;}
                                       | disjunction OR conjunction {$value = new Disjunction($disjunction.value, $conjunction.value);};

conjunction returns [Expression value] : negation {$value = $negation.value;}
                                       | conjunction AND negation {$value = new Conjunction($conjunction.value, $negation.value);};

negation returns [Expression value] : variable {$value = $variable.value;}
                                    | NOT negation {$value = new Negation($negation.value);}
                                    | OB expression CB {$value = $expression.value;};

variable returns [Expression value] : VAR {$value = new Variable($VAR.text);};

IMPLIES : '->';
OR : '|';
AND : '&';
NOT : '!';
OB : '(';
CB : ')';
VAR : [A-Z]([0-9])*;

当我在分离规则中交换析取和连接时,使析取权变为关联,它起作用,但这可能会导致我的工作中出现一些错误。

因为它可能很重要,我使用ANTLR4-plugin为Intellij Idea生成解析器。

我做错了什么? 先感谢您。

1 个答案:

答案 0 :(得分:1)

在您的代码中引用disjunction时:

disjunction returns [Expression value]
 : conjunction {$value = $conjunction.value;}
 | disjunction OR conjunction {$value = new Disjunction($disjunction.value, $conjunction.value);}
 ;

如果value代替$disjunction中的disjunction,ANTLR会尝试获取整个封闭规则的disjunction OR ...

如果您想引用disjunction中的disjunction OR ...,则需要在引用之前对其进行标记:

disjunction returns [Expression value]
 : c1=conjunction                  {$value = $c1.value;}
 | d=disjunction OR c2=conjunction {$value = new Disjunction($d.value, $c2.value);}
 ;

这是一个完整的工作(测试)示例:

grammar Logic;

@header {
  import expression.*;
}

expression returns [Expression value]
 : d1=disjunction                      {$value = $d1.value;}
 | d2=disjunction IMPLIES e=expression {$value = new Implication($d2.value, $e.value);}
 ;

disjunction returns [Expression value]
 : c1=conjunction                  {$value = $c1.value;}
 | d=disjunction OR c2=conjunction {$value = new Disjunction($d.value, $c2.value);}
 ;

conjunction returns [Expression value]
 : n1=negation                   {$value = $n1.value;}
 | c=conjunction AND n2=negation {$value = new Conjunction($c.value, $n2.value);}
 ;

negation returns [Expression value]
 : variable         {$value = $variable.value;}
 | NOT n=negation   {$value = new Negation($n.value);}
 | OB expression CB {$value = $expression.value;}
 ;

variable returns [Expression value]
 : VAR {$value = new Variable($VAR.text);}
 ;

IMPLIES : '->';
OR      : '|';
AND     : '&';
NOT     : '!';
OB      : '(';
CB      : ')';
VAR     : [A-Z]([0-9])*;
SPACE   : [ \t\r\n] -> skip;