Как маркировать отступы в Coco / R (Python, Boo как отступ) - PullRequest
2 голосов
/ 27 ноября 2010

Есть ли там общеизвестный способ, как реализовать в Coco / R отступы, как в Python / Boo?

Coco / R игнорирует пробелы, но мне нужно каким-то образом генерировать токены beginBlock / endBlock, основываясь на отступе следующей строки.

Прямо сейчас я использую препроцессор, который вставляет '{', '}' и ';' во входном потоке, сравнивая отступы между строками. В грамматике Coco / R я использую изогнутые скобки в качестве токенов beginBlock / endBlock. Это хорошо работает, если входной поток не имеет комментариев (которые также могут быть вложенными). Как только поступают неупорядоченные комментарии, логика сравнения намерений не работает.

Реализация препроцессора, который отслеживает комментарии, выглядит для меня слишком большой.

Итак, вопрос в том, возможно ли вообще разобрать грамматику, основанную на отступе, с Coco / R? Или я должен попробовать что-то еще?

Ответы [ 2 ]

2 голосов
/ 13 января 2011

Нашли идеальный способ сделать это.

  • обернуть GetNextToken методом, который сравнивает позиции потока следующего токен с последним.

  • если позиция.Y изменена, но position.X увеличил N вкладок, введите N виртуальные токены INDENT.

  • если позиция.Y изменена, но position.X уменьшил N вкладок, введите N виртуальные токены DENDENT.

  • если позиция.Y изменена, но position.X - нет, введите виртуальный Маркер СЕПАРАТОРА.

  • , если position.Y не изменяется, вернуть Оригинальный следующий токен.

  • если предыдущий токен был мягким разрывом (в python \), игнорировать логику выше.

2 голосов
/ 05 декабря 2010

Прежде всего, Coco / R по умолчанию игнорирует только пробелы (пробелы). Вкладки не игнорируются:

2.3.5 Пробел
Такие символы, как пробелы, табуляторы или конец строки символы обычно рассматриваются как пустое пространство, которое должно игнорироваться сканер. Пробелы игнорируются дефолт. Если другие персонажи должны игнорироваться, а пользователь должен укажите их следующим образом:

WhiteSpaceDecl = "IGNORE" Set.

Пример IGNORE '\ t' + '\ r' + '\ n'

Я не проверял это, но я думаю, что вы должны переписать поведение сканера по умолчанию:

Token NextToken() {
    while (ch == ' ' ||
        false
    ) NextCh();

Самый простой способ сделать это - сначала изменить сгенерированный код, пока он не заработает, а затем внести те же изменения в файлы фреймов (Scanner.frame и Parser.frame), чтобы вы не потеряли изменения после регенерации. код.

...