2015-11-15 3 views
0

Мне нужно написать программу, которая проверяет типы для системы типа F1, и я не знаю, как создавать правила, которые делают правильный ассоциативный оператор.правый ассоциативный оператор в javacc

Мне нужно, чтобы, если я разбираю что-то наподобие Nat -> Nat -> Nat, это должно анализироваться как Nat -> (Nat -> Nat), а не как (Nat -> Nat) -> Nat (I хотят построить 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; 

благодаря

+0

Я предлагаю пропускать пробелы и использовать '' -> "' как токен для оператора типа функции. –

+0

Я не могу этого сделать, потому что в лямбда-исчислении пространство является символом приложения. Я добавлю грамматику к сообщению – Silver

+0

Это ваша грамматика, поэтому вы должны делать то, что считаете лучшим. Более традиционным выбором было бы пропускать пробелы и использовать 'lambda_expression, lambda_expression' для приложения. Это позволило бы, например, 'f (g x)'. И это позволило бы более чем одному пробелу между функцией и аргументом. –

ответ

0

Используйте петлю вместо рекурсии

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

Или --what составляет тот же thing-- использовать правую рекурсию.

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; } 
} 
Смежные вопросы