ANTLR解析任务(ANTLR parse assignments)

2019-10-16 19:23发布

我想分析的一些任务,在这里我只关心分配的全过程。 不是分配里面什么。 的分配由indiciated ':=' 。 (编辑:前和分配后,其他的事情可能会)

一些例子:

a := TRUE & FALSE;
c := a ? 3 : 5;
b := case 
          a : 1;
          !a : 0;
        esac;

目前,我做一个包含“案例”和其他任务分配之间的差异。 对于简单的作业我想是这样~('case' | 'esac' | ';')但随后ANTLR抱怨无法比拟的标记(如'=' )。

assignment : 
   NAME ':='! expression ;

expression : 
    ( simple_expression | case_expression) ;


simple_expression : 
    ((OPERATOR | NAME) & ~('case' | 'esac'))+  ';'! ;

case_expression : 
    'case' .+ 'esac' ';'! ;

我试着用下面的替换,因为Eclipse的解释似乎并不喜欢((OPERATOR | NAME) & ~('case' | 'esac'))+ ';'! ; ((OPERATOR | NAME) & ~('case' | 'esac'))+ ';'! ; 因为'and'

   (~(OPERATOR | ~NAME | ('case' | 'esac')) |
    ~(~OPERATOR | NAME | ('case' | 'esac')) |
    ~(~OPERATOR | ~NAME | ('case' | 'esac')))  ';'!

但是,这是行不通的。 我得到

“错误(139):/AntlrTutorial/src/foo/NusmvInput.g:78:5:补集是空| --->〜(〜OPERATOR |〜NAME |( '情况下' | 'ESAC')))EOC !“;

我该如何解析呢?

Answer 1:

有一对夫妇的事情去错在这里:

  • 您正在使用&在你的语法,而应与周围的引号: '&'
  • 除非你知道自己在做什么,不要使用~. (特别是没有.+语法规则里面!):在词法规则只使用它们;
  • 创建词法规则,而不是定义'case''esac'在你的语法规则(它是安全的使用文字记号在你的语法规则,如果没有其他的词法规则有可能匹配,但'case''esac' 看起来很像NAME 他们可以在您的AST在这种情况下,最好给自己明确地定义他们在词法分析器结束)

这里有一个快速演示:

grammar T;

options {
  output=AST;
}

tokens {
  ROOT;
  CASES;
  CASE;
}

parse
 : (assignment SCOL)* EOF -> ^(ROOT assignment*)
 ;

assignment 
 : NAME ASSIGN^ expression 
 ;

expression
 : ternary_expression
 ;

ternary_expression
 : or_expression (QMARK^ ternary_expression COL! ternary_expression)?
 ;

or_expression
 : unary_expression ((AND | OR)^ unary_expression)*
 ;

unary_expression
 : NOT^ atom
 | atom
 ;

atom
 : TRUE
 | FALSE
 | NUMBER
 | NAME
 | CASE single_case+ ESAC -> ^(CASES single_case+)
 | '(' expression ')'     -> expression
 ;

single_case
 : expression COL expression SCOL -> ^(CASE expression expression)
 ;

TRUE   : 'TRUE';
FALSE  : 'FALSE';
CASE   : 'case';
ESAC   : 'esac';
ASSIGN : ':='; 
AND    : '&';
OR     : '|';
NOT    : '!';
QMARK  : '?';
COL    : ':';
SCOL   : ';';
NAME   : ('a'..'z' | 'A'..'Z')+;
NUMBER : ('0'..'9')+;
SPACE  : (' ' | '\t' | '\r' | '\n')+ {skip();};

这将解析您的输入:

a := TRUE & FALSE;
c := a ? 3 : 5;
b := case 
          a : 1;
          !a : 0;
        esac;

如下:



文章来源: ANTLR parse assignments