Парсинг комментария в мошеннике
У меня очень простой вопрос о разборе фрагмента, содержащего комментарий. Сначала мы импортируем мой любимый язык, Пико:
import lang::pico::\syntax::Main;
Затем мы выполняем следующее:
parse(#Id,"a");
дает, как и ожидалось:
Id: (Id) `a`
Тем не мение,
parse(#Id,"a\n%% some comment\n");
выдает ошибку разбора.
Что я здесь не так делаю?
1 ответ
Есть несколько проблем.
Id
является лексическим, означающим макет (комментарии) никогда не бывают- Макет вставляется только между элементами в производстве и
Id
У lexical есть только класс символов, поэтому нет места для вставки макета. - Даже если бы Id был синтаксическим нетерминалом с несколькими элементами, он бы анализировал комментарии между ними не до или после.
Подробнее о разнице между syntax
, lexical
, а также layout
см.: Rascal Syntax Definitions.
Если вы хотите проанализировать комментарии без терминала, у нас есть start
модифицировано для нетерминала. Обычно макет вставляется только между элементами в производстве, при запуске он также вставляется до и после него.
Пример возьмем этот грамматик:
layout L = [\t\ ]* !>> [\t\ ];
lexical AB = "A" "B"+;
syntax CD = "C" "D"+;
start syntax EF = "E" "F"+;
это будет преобразовано в эту грамматику:
AB = "A" "B"+;
CD' = "C" L "D"+;
EF' = L "E" L "F"+ L;
"B"+ = "B"+ "B" | "B";
"D"+ = "D"+ L "D" | "D";
"F"+ = "F"+ L "F" | "F";
Поэтому, в частности, если вы хотите проанализировать строку с разметкой вокруг нее, вы можете написать так:
lexical Id = [a-z]+;
start syntax P = Id i;
layout L = [\ \n\t]*;
parse(#start[P], "\naap\n").top // parses and returns the P node
parse(#start[P], "\naap\n").top.i // parses and returns the Id node
parse(P, "\naap"); // parse error at 0 because start wrapper is not around P