Parsing ANTLR解析赋值

Parsing ANTLR解析赋值,parsing,antlr,antlr3,Parsing,Antlr,Antlr3,我想分析一些赋值,我只关心赋值的整体。不是关于作业的内容。赋值由':='表示。(编辑:作业前后可能会有其他事情发生) 一些例子: a := TRUE & FALSE; c := a ? 3 : 5; b := case a : 1; !a : 0; esac; 目前,我对包含“案例”的作业和其他作业进行了区分。对于简单的赋值,我尝试了一些类似于~('case''esac''esac')的方法,但后来antlr抱怨没有匹配的标记(

我想分析一些赋值,我只关心赋值的整体。不是关于作业的内容。赋值由
':='
表示。(编辑:作业前后可能会有其他事情发生)

一些例子:

a := TRUE & FALSE;
c := a ? 3 : 5;
b := case 
          a : 1;
          !a : 0;
        esac;
目前,我对包含“案例”的作业和其他作业进行了区分。对于简单的赋值,我尝试了一些类似于
~('case''esac''esac')
的方法,但后来antlr抱怨没有匹配的标记(比如
'='

我尝试用以下内容替换,因为eclipse解释器似乎不喜欢
((操作符名称)&('case'|'esac'))+'和'
的原因

   (~(OPERATOR | ~NAME | ('case' | 'esac')) |
    ~(~OPERATOR | NAME | ('case' | 'esac')) |
    ~(~OPERATOR | ~NAME | ('case' | 'esac')))  ';'!
但这是行不通的。我明白了

“错误(139):/antlrtuitorial/src/foo/NusmvInput.g:78:5:集合补码为空|-->~(~OPERATOR | ~NAME |('case'|'esac'))EOC!”


如何解析它?

这里有两个问题:

  • 您在语法中使用的是
    &
    ,而它周围应该有引号:
    '&
  • 除非您确切地知道自己在做什么,否则不要在解析器规则中使用
    ~
    (特别是不要使用
    +
    !):仅在lexer规则中使用它们
  • 创建lexer规则,而不是在解析器规则中定义
    'case'
    'esac'
    (如果没有其他lexer规则可能与之匹配,那么在解析器规则中使用文字标记是安全的,但是
    'case'
    'esac'
    看起来很像
    NAME
    ,它们可能会在AST中结束,在这种情况下,最好自己在lexer中显式定义它们)
下面是一个快速演示:

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;
详情如下:


我还没有完全理解lexer和parser的机制,所以这就是我应该研究的^^^。您的解决方案当然给了我一些见解,谢谢。
a := TRUE & FALSE;
c := a ? 3 : 5;
b := case 
          a : 1;
          !a : 0;
        esac;