Удалить ненужный символ макета из выражения - PullRequest
1 голос
/ 18 марта 2020

Я пытаюсь добиться этого негодяем:

select   a from     myTable; => select a from myTable

По сути, я просто хочу удалить ненужный Макет выражения, а также комментарии, чтобы получить минимальную форму моего выражения.

Как мне добиться этого в Rascal?

1 Ответ

0 голосов
/ 18 марта 2020
  1. Вы можете заменить указанный c узел дерева разбора на себя посещением => и заменить дочерние элементы обратно. В приведенном ниже примере заменяются только пробелы вокруг +, затем
  2. Вы можете заменить все макеты в одном go, посетив дерево и сопоставив его в нетерминальном макете (может быть другой название для вашей грамматики). В приведенном ниже примере вы также можете увидеть, как это делается.
module NormalizeLayout

import demo::lang::Pico::Syntax;
import ParseTree;
import IO;

// a stub space
private Layout space = appl(prod(layouts("Layout"), [], {}), [char(32)]);

void example() {
   t = parse(#start[Program], 
     "begin
     '  declare 
     '    a : natural;
     '
     '    a := 1 +
     '         1
     'end");

   t = visit (t) {

   // this one sets the spaces only of a very specific rule, namely + expressions:
      case (Expression) `<Expression l> + <Expression r>` 
        => (Expression) `<Expression l> + <Expression r>`

   // as an alternative here we match all layout in the entire program and replace it     
     case Layout _ => space
   }

   println(t); //  begin declare a : natural ; a := 1 + 1 end 
}

Основная трудность заключается в получении примера дерева разбора для пробела, начиная с обозначений (NT) и [NT] не поддерживает синтаксический анализ непосредственно из нетерминального макета. Поэтому в этом примере я перешел на общий уровень c и изобрел дерево разбора для Layouts (см. Модуль ParseTree, чтобы узнать, как деревья разбора определяются внутри Rascal).

Другой (тип -безопасно) уловка для получения такого дерева примеров заключается в том, чтобы получить пример из следующего примера:

private Layout space() {
  visit ((Expression) `1 + 1`) {
    case Layout x : return x;
  }

  fail;
}
...