Вопрос

Я пытаюсь разработать островную грамматику, используя RACCAL MPL , но я столкнулся с Проблема:

При реализации островной грамматики в SDF очень распространенный подход - это определить добычу воды «Catch-All» с использованием атрибута {избежать}. Это мешает парсеру использовать эту продукцию, если другие применимы. Это позволяет указать поведение по умолчанию , которое может быть переопределено другими производствами, создавающими абиги. Очень простой пример этого будет:

context free syntax
    Chunk*         -> Input
    Water          -> Chunk
lexical syntax
    ~[\t\n\ ]+   -> Water {avoid}  // avoid the Water production
.

Я пытался воспроизвести это поведение с помощью ZASCAL MPL. Моя цель состоит в том, чтобы создать грамматическую грамматию, которая собирает все условные препроцессорные директивы внутри куска кода C / C ++ и пропускают остальную часть ввода с использованием продуктов воды.

layout LAYOUT = [\t\n\ ];
lexical WATER = ![\t\n\ ]+;

start syntax Program = Line*;       // program consists of lines

syntax Line = ConditionalDirective  // preprocessor directives
            > WATER;                // catch-all option

syntax ConditionalDirective = "#ifdef" 
                            | "#ifndef"
                            | "#if"
                            | "#elif";
.

Я пытался создать эффект {избежать}, давая выработку conditaldirective более высокий приоритет, используя оператор ">", но это не работает, по-видимому, видимо. Разборное дерево все еще содержит двусмысленность.

#ifdef asd
.

Если я аналогирую вышеуказанный код, например, я получаю дерево разбора, которая выглядит следующим образом:

неоднозначный табло

Насколько я могу сказать из ZASCAL Документация , используя «приоритет» -оператора, может быть не так, чтобы пойти в моем случае, но я не вижу никаких других возможностей. Я предполагаю, что есть путь, однако, потому что авторы негодяя четко утверждают, что каждая грамматика SDF может быть преобразована на грамматику Rauscal.

Есть ли способ воспроизводить функциональные возможности SDFS {избежать} с помощью ZASCAL MPL? Или можно ли каким-то образом отфильтровать разбовое лес, повторно приоритет приоритеты?

Это было полезно?

Решение

Краткий ответ: Избегайте в SDF2 A Post Parse Filter. В RAUSCAL вы можете определить их сами, увидеть https://github.com/cwi-swat/rascal/blob/master/src/org/rascalmpl/library/lang/sdf2/filters/preferavoid.rsc для примера, который имитирует SDF2 избегайте поведения, не игнорируя цепочки впрыска и без подсчета. Вы можете импортировать его в свою грамматику и использовать @avoid и @Prefer Tags, как и в SDF2 или написать свои собственные фильтры.

Предостережение: избегать, как правило, не было достаточно, чтобы определить поведение воды в SDF2, и он тоже не на него. Причина в том, что вода может стать дольше, чем ее альтернатива. Предпочтите и избегайте можете выбрать только между альтернативами равной длины с точки зрения длины доверенности. Один человек, но медленный способ борьбы с водой в RACCAL - посчитать его в каждой альтернативе и выбирать производные с меньшим количеством воды.

Другой проблемой с предпочтением и избежать того, что использование начнет вмешиваться, особенно когда они были подсчитаны. Это можно избежать в RACCAL, специализирующие фильтры для конкретных нетерминалов или даже альтернативных правил.

Другой вариант - использовать \ и! Операторы разобрания. Смотрите руководство. Однако все и все Я считаю, что вариант фильтрации по пазоре в настоящее время является лучшим способом справиться с грамматическими грамматиками острова, потому что вы контролируете то, что происходит.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top