Парсинг комментария в мошеннике

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

import lang::pico::\syntax::Main;

Затем мы выполняем следующее:

 parse(#Id,"a");

дает, как и ожидалось:

 Id: (Id) `a`

Тем не мение,

parse(#Id,"a\n%% some comment\n");

выдает ошибку разбора.

Что я здесь не так делаю?

1 ответ

Есть несколько проблем.

  1. Id является лексическим, означающим макет (комментарии) никогда не бывают
  2. Макет вставляется только между элементами в производстве и Id У lexical есть только класс символов, поэтому нет места для вставки макета.
  3. Даже если бы 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
Другие вопросы по тегам