2015-01-14 5 views
1

Я пытаюсь внедрить исчисление лямбда внутри Rascal, но у меня возникают проблемы с получением приоритета и синтаксического анализа, чтобы работать так, как хотелось бы. В настоящее время у меня есть грамматики, которая выглядит примерно так:Анализ и внедрение исчисления лямбда в Rascal

keyword Keywords= "if" | "then" | "else" | "end" | "fun"; 

lexical Ident = [a-zA-Z] !>> [a-zA-Z]+ !>> [a-zA-Z0-9] \ Keywords; 
lexical Natural = [0-9]+ !>> [0-9]; 
lexical LAYOUT = [\t-\n\r\ ]; 
layout LAYOUTLIST = LAYOUT* !>> [\t-\n\r\ ]; 

start syntax Prog = prog: Exp LAYOUTLIST; 

syntax Exp = 
    var: Ident 
    | nat: Natural 
    | bracket "(" Exp ")" 
    > left app: Exp Exp 
    > right func: "fun" Ident "-\>" Exp 

Когда я анализирую программу формы:

(fun x -> fun y -> x) 1 2

Полученное дерево является:

prog(app(
    app(
     func(
     "x", 
     func(
      "y", 
      var("x") 
     nat(1), 
    nat(2)))))) 

Где на самом деле я Я ищу что-то вроде этого (я думаю):

prog(app(
    func(
     "x", 
     app(
     func(
      "y", 
      var("x")), 
     nat(2))), 
    nat(1))) 

Я пробовал ряд вариантов приоритета в грамматике, я пробовал обернуть правило приложения в круглых скобках и ряд других вариантов. Кажется, что-то происходит здесь, я не понимаю. Любая помощь будет оценена по достоинству. Благодарю.

+0

Я думаю, что вы получаете то, что должны получить, и то, что вы считаете нужным, - нет. Лямбда принимает аргумент и возвращает лямбду, которая затем применяется ко второму аргументу. Другими словами, второй применяет работы по результату первого применения, поэтому я ожидал бы, что дерево будет appy (apply (...), 2) – rici

ответ

1

Я использовал следующую грамматику, которая удаляет дополнительные LAYOUTLIST и мертвые right, но это не должно меняться. Это похоже на работу, как вы хотите, когда я использую общую implode функцию:

keyword Keywords= "if" | "then" | "else" | "end" | "fun"; 

lexical Ident = [a-zA-Z] !>> [a-zA-Z]+ !>> [a-zA-Z0-9] \ Keywords; 
lexical Natural = [0-9]+ !>> [0-9]; 
lexical LAYOUT = [\t-\n\r\ ]; 
layout LAYOUTLIST = LAYOUT* !>> [\t-\n\r\ ]; 

start syntax Prog = prog: Exp; 

syntax Exp = 
    var: Ident 
    | nat: Natural 
    | bracket "(" Exp ")" 
    > left app: Exp Exp 
    > func: "fun" Ident "-\>" Exp 
    ; 

Затем призывающий анализатор и разрушающийся в нетипизированный AST (я удалил аннотаций местоположения для удобства чтения):

rascal>import ParseTree; 
ok 
rascal>implode(#node, parse(#start[Prog], "(fun x -\> fun y -\> x) 1 2")) 
node: "prog"("app"(
     "app"(
      "func"(
      "x", 
      "func"(
       "y", 
       "var"("x"))), 
      "nat"("1")), 
     "nat"("2"))) 

Итак, я предполагаю, что вы получили правильную грамматику для нужной вам формы дерева. Как вы идете от конкретного дерева разбора до абстрактного АСТ? Возможно, там что-то смешное.

+0

Я использую тот же метод, показанный здесь, чтобы перейти от конкретного к абстрактному , Дерево, которое у вас здесь, похоже на первый пример (от чего я хочу уйти), в отличие от второго примера (это то, что я хотел бы, чтобы мои деревья выглядели). Если я чего-то не хватает :). Для справки мое конкретное -> абстрактное преобразование таково: 'public Prog parse (loc l) = parse (#Prog, l);' и 'public Prog load (loc l) = implode (#Prog, parse (l)); '(Также завершающий LAYOUTLIST в Prog, кажется, единственный способ, который я могу успешно прочитать из файла). – josh

+0

Есть ли причина, по которой вы хотите, чтобы ваши деревья выглядели так? Если вы полностью заключили в скобки свое выражение, у вас будет нечто вроде '(((fun x -> fun y -> x) 1) 2)', поэтому вам нужен узел приложения, где '(fun x -> fun y -> x) 'применяется к' 1'. Тогда это будет дочерним элементом другого узла приложения, где применяется (fun x -> fun y -> x) 1. 2. Предпочтительным деревом будет такая программа, как '(fun x -> ((fun y -> x) 2)) 1'. –

+0

Спасибо @MarkHills. Я определенно согласен. По какой-то причине было разумнее, чтобы одним из дочерних узлов каждого приложения являлась функция, а другой - аргументом. Вы правы, хотя. Благодаря! – josh

 Смежные вопросы

  • Нет связанных вопросов^_^