1

我想解析一些作业,我只关心整个作业。不是关于任务中的内容。分配由 表示':='。(编辑:在分配之前和之后其他事情可能会发生)

一些例子:

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' ';'! ;

((OPERATOR | NAME) & ~('case' | 'esac'))+ ';'! ;我尝试用以下内容替换,因为eclipse-interpreter 似乎不喜欢'and'.

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

但这不起作用。我明白了

“错误(139):/AntlrTutorial/src/foo/NusmvInput.g:78:5:设置补码为空|--->〜(〜OPERATOR |〜NAME |('case'|'esac')))EOC !;"

我该如何解析它?

4

1 回答 1

2

这里有几件事出了问题:

  • &在语法中使用它,而它应该带有引号:'&'
  • 除非您确切知道自己在做什么,否则不要在解析器规则中使用~and .(尤其不要.+!):仅在词法分析器规则中使用它们;
  • 创建词法分析器规则,而不是在解析器规则中定义'case''esac'(如果没有其他词法分析器规则可能匹配,则在解析器规则中使用文字标记是安全的,但是看起来很像,并且'case'它们可能最终出现在您的 AST 中,在这种情况下它是最好自己在词法分析器中明确定义它们)'esac' NAME

这是一个快速演示:

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;

如下:

在此处输入图像描述

于 2012-06-07T20:16:39.570 回答