2015-05-27 6 views
2

Какова наилучшая практика для обработки сложных литералов в Rascal?Обработка лексических программ в Rascal

Два примера из JavaScript (мой DSL имеет подобные случаи):

  • Строка с \ побегами - должно быть незаменяемым в реальную стоимость.
  • Литералы регулярного выражения - нуждаются в собственном суб-АСТ.

implode отказывается карту лексических абстрактных деревьев, они, очевидно, handed differently из синтаксических производств, несмотря на наличие полных разбора деревьев доступны. Например, следующий синтаксический анализатор не может с IllegalArgument("Missing lexical constructor"):

module lexicals 

import Prelude; 

lexical Char = "\\" ![] | ![\\]; // potentially escaped character 
lexical String = "\"" Char* "\""; // if I make this "syntax", implode works as expected 

start syntax Expr = string: String; 

data EXPR = string(list[str] chars); 

void main(list[str] args) { 
    str text = "\"Hello\\nworld\""; 
    print(implode(#EXPR, parse(#Expr, text))); 
} 

Единственная идея, которую я до сих пор, чтобы захватить все лексические в качестве исходных строк, а затем повторно проанализировать их (лопается и все) с использованием отдельно определенный синтаксиса без разметки пробельного , Надеюсь, есть лучший способ.

ответ

2

Способ implode преобразует дерево разбора в документ ast в документе rascal tutor:implode. Это правило содержит следующее правило:

Немаркированные лексики вставляются в str, int, real, bool в зависимости от ожидаемого типа в ADT. Чтобы развязать лексику по типам, отличным от str, используются функции синтаксического анализа PDB для целых чисел и удвоений. Логические лексики должны соответствовать «true» или «false». NB: лексики взорваны таким образом, даже если они неоднозначны.

Таким образом, решение 1 является добавление метки к вашей продукции:

lexical String = string: "\"" Char* "\""; 

Кроме того, возможно, вам не нужно иметь AST рядом с синтаксическим деревом? По крайней мере, не тот, который должен соответствовать вашей грамматике. Два общих сценария:

  1. Вам нужен AST, поскольку структура грамматики не подходит для вашей цели. В этом случае вам необходимо вручную написать функцию implode.
  2. Структура вашего дерева синтаксического анализа достаточно хороша. В этом случае проверьте пример для Concrete Syntax. Это очень чистый способ работы с целевым языком, вложенным внутри негодяя.

Мы все больше склоняемся к обесцениванию функции implode, поскольку наш конкретный синтаксис достаточно мощный для большинства случаев.

+0

Маркировка с помощью "string:" конфликтует с существующим конструктором. Маркировка с помощью чего-то еще («string1:») приводит к «Не удается найти конструктор для EXPR». (У меня есть последняя ошибка с моими фактическими определениями, используя версию 0.7.2.201501130937). Мои АСТ очень близки к грамматике (это типичная грамматика «Expr»), но мне нужно применить много терминов переписывания (канонизация и оптимизация), поэтому я пошел с Rascal в первую очередь: это простой, но практичный язык, который имеет как синтаксический анализ, так и переписывание встроенных. –

+0

Я думаю, что это можно решить, разбив их на 2 модуля. И действительно, мошенник - очень хороший язык для разбора и переписывания. И, в определенной степени, это возможно и при разборе деревьев. –

+0

Пошаговое развязывание и ручное сопоставление деревьев синтаксического анализа с «основным языком», вероятно, лучше, чем репарация лексики, я поеду с ним. Обсуждение. Я понимаю идеи работы в конкретном синтаксисе (вентилятор TXL здесь), но это ДЕЙСТВИТЕЛЬНО неудачно, что Rascal движется в этом направлении. Неизменяемые данные и встроенный backtracking ('fail') делают его идеальным хозяином для классического подхода« парсер с использованием АСТ ». Легкий синоним построения дерева (a la ANTLR 3) + автоматическое оформление с данными компоновки (пробелы и комментарии) + автоматическое разделение ... Можно мечтать. –

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

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