javacc中的右关联运算符

时间:2015-11-15 21:43:04

标签: javacc

我需要编写一个检查F1类型系统类型的程序,而且我不知道如何制定能够建立正确关联运算符的规则。

我需要的是,如果我解析像Nat这样的东西 - > Nat - > Nat,应解析为Nat - > (Nat - > Nat),而不是(Nat - > Nat) - > Nat(我想建立一个AST并做一些事情)

我现在拥有的是:

Node Type2() {Node t1;}
{
    "Nat" { return Node("Nat", null, null);}
    |
    "Bool" { return Node("Bool", null, null);}
    |
    "(" t1=Type() ")" {return t1;}
}
Node Type() {Node t1; Node t2;}
{
    t1 = Type2() (" -> " t2 = Type2() { return Node("->", t1, t2); }
}

但它是关联的,我怎么能做到这一点?

语法是:

type              = "Bool" | "Nat" | type, "->", type | "(", type, ")";
lambda_expression = variable
              | "\", variable, ":", type, ".", lambda_expression
              | lambda_expression, " ", lambda_expression
              | "(", lambda_expression, ")";
type_context      = variable, ":", type, { ",", variable, ":", type };
expression        = [ type_context ], "|-", lambda_expression, ":", type;

感谢

2 个答案:

答案 0 :(得分:0)

使用循环代替递归

Node Type() :
{Node t1; Node t2;}
{
    t1 = Type2()
    (   " -> "
        t2 = Type2() 
        { t1 =  Node("->", t1, t2); }
    )*
    {return t1 ; }
}

或者 - 相同的东西 - 使用正确的递归。

Node Type() :
{Node t1;}
{
    t1 = Type2()
    t1 = MoreType( t1 ) ;
    {return t1 ; }
}

Node MoreType(Node t1) :
{Node t2;}
{
    " -> " t2 = Type2() t1 = MoreType( new Node( "->", t1, t2 ) ) {return t1; }
|
    {return t1; }
}

答案 1 :(得分:0)

以下是直接使用LL(1)语法的解决方案:

Type2 =
| "Nat"
| "Bool"
| "(" Type ")"

Type =
| Type2 ( "->" Type )?

以解析Nat -> Bool -> Nat为例:

  1. 从解析Type开始,NatType2匹配。
  2. 然后解析器看到->,因此它知道( ... )?中的所有内容都应被解析而不是被忽略。现在,它尝试将Type与其余的Bool -> Nat递归匹配。
  3. Type的递归解析中,首先,BoolType2匹配,然后解析器看到->。因此,它再次尝试将Type与其余输入Nat进行递归匹配。
  4. Type的第三次解析中,NatType2匹配,但是解析器在其后看不到->,因此决定忽略{{1} }并终止。

在上面的解析中,( ... )?在步骤2〜4中一起解析,Bool -> Nat在步骤1〜4中一起解析。这样就获得了正确的关联性。

对应的JavaCC代码:

Nat -> (Bool -> Nat)