作为Antlr语法中的表达式赋值

时间:2011-12-06 10:52:21

标签: parsing antlr ll

我正在尝试扩展the grammar of the Tiny Language以将赋值视为表达式。因此,编写

是有效的
a = b = 1; // -> a = (b = 1)
a = 2 * (b = 1); // contrived but valid
a = 1 = 2; // invalid

分配在两个方面与其他运营商不同。这是正确的联想(并不是一件大事),它的左侧必须是一个变量。所以我改变了这样的语法

statement: assignmentExpr | functionCall ...;

assignmentExpr: Identifier indexes? '=' expression;

expression: assignmentExpr | condExpr;

它不起作用,因为它包含非LL(*)决定。我也试过这个变种:

assignmentExpr: Identifier indexes? '=' (expression | condExpr);

但我得到了同样的错误。我对

感兴趣
  • 此具体问题
  • 给定一个非LL(*)决策的语法,如何找到导致问题的两个路径
  • 如何解决问题

2 个答案:

答案 0 :(得分:2)

我认为你可以改变你的语法来达到同样的目的,而不使用句法谓词:

statement: Expr ';' | functionCall ';'...;

Expr: Identifier indexes? '=' Expr  |  condExpr ;

condExpr: .... and so on;

我考虑到这个想法改变了Bart的例子:

grammar TL;

options {
  output=AST;
}

tokens {
  ROOT;
}

parse
  :  stat+ EOF -> ^(ROOT stat+)
  ;

stat
  :  expr ';' 
  ;

expr
  : Id Assign expr -> ^(Assign Id expr)

  | add
  ;

add
  :  mult (('+' | '-')^ mult)*
  ;

mult
  :  atom (('*' | '/')^ atom)*
  ;

atom
  :  Id
  |  Num
  |  '('! expr ')' !
  ;

Assign  :   '=' ;
Comment : '//' ~('\r' | '\n')* {skip();};
Id      : 'a'..'z'+;
Num     : '0'..'9'+;
Space   : (' ' | '\t' | '\r' | '\n')+ {skip();};

输入:

a=b=4;
a = 2 * (b = 1);

你得到以下解析树: enter image description here

答案 1 :(得分:1)

这里的关键是你需要“确保”解析器在表达式中,前面有一些东西满足表达式。这可以使用句法谓词(( ... )=>add规则中的mult部分)来完成。

快速演示:

grammar TL;

options {
  output=AST;
}

tokens {
  ROOT;
  ASSIGN;
}

parse
  :  stat* EOF -> ^(ROOT stat+)
  ;

stat
  :  expr ';' -> expr
  ;

expr
  :  add
  ;

add
  :  mult ((('+' | '-') mult)=> ('+' | '-')^ mult)*
  ;

mult
  :  atom ((('*' | '/') atom)=> ('*' | '/')^ atom)*
  ;

atom
  :  (Id -> Id) ('=' expr -> ^(ASSIGN Id expr))?
  |  Num
  |  '(' expr ')' -> expr
  ;

Comment : '//' ~('\r' | '\n')* {skip();};
Id      : 'a'..'z'+;
Num     : '0'..'9'+;
Space   : (' ' | '\t' | '\r' | '\n')+ {skip();};

将解析输入:

a = b = 1;       // -> a = (b = 1)
a = 2 * (b = 1); // contrived but valid

进入以下AST:

enter image description here