ParseKit: Какие встроенные продукты я должен использовать в своих грамматиках?

Я только начал использовать ParseKit, чтобы изучить создание языка и, возможно, создать небольшую игрушечную DSL. Однако текущий транк SVN от Google выдает -[PKToken intValue]: unrecognized selector sent to instance ... при разборе этой грамматики:

@start = identifier ;
identifier = (Letter | '_') | (letterOrDigit | '_') ;
letterOrDigit = Letter | Digit ;

Против этого ввода:

foo

Очевидно, я что-то упускаю или неправильно настроил свой проект. Что я могу сделать, чтобы решить эту проблему?


person Grimless    schedule 09.12.2012    source источник


Ответы (1)


Разработчик ParseKit здесь.

Во-первых, см. документацию по токенизации ParseKit.

По сути, ParseKit может работать в одном из двух режимов: назовем их Tokens Mode и Chars Mode. (Для этих двух режимов нет официальных названий, но, возможно, они должны быть.)

Tokens Mode намного популярнее. Практически каждый пример использования ParseKit, который вы найдете, показывает, как использовать Tokens Mode. Я считаю, что вся документация на http://parsekit.com использует Tokens Mode. Функция грамматики ParseKit (которую вы используете в своем примере, работает только в Tokens Mode).

Chars Mode — очень малоизвестная функция ParseKit. Я никогда раньше не спрашивал об этом.

Итак, отличия в режимах:

  • В Tokens Mode токенизатор ParseKit создает многосимвольные токены (например, слова, символы, числа, строки в кавычках и т. д.), которые затем анализируются созданными вами парсерами ParseKit (программно или с помощью грамматик).
  • В Chars Mode токенизатор ParseKit всегда выдает токены односимвольные, которые затем анализируются синтаксическими анализаторами ParseKit, которые вы создаете программно. (грамматика в настоящее время не работает с этим режимом, так как этот режим не популярен).

Вы можете использовать Chars Mode для реализации регулярных выражений, которые анализируют посимвольно.


В вашем примере вы должны игнорировать Chars Mode и просто использовать Tokens Mode. Следующие встроенные продукты предназначены только для Chars Mode. Не используйте их в своих грамматиках:

(PK)Letter
(PK)Digit
(PK)Char
(PK)SpecificChar 

Обратите внимание, как все эти произведения звучат так, как будто они соответствуют отдельным символам. Это потому, что они делают.

Ваш пример выше, вероятно, должен выглядеть так:

@start = identifier;
identifier = Word; // by default Words start with a-zA-Z_ and contain -0-9a-zAZ_'

Имейте в виду, что продукты в ваших грамматиках (парсеры, такие как identifier) будут работать с токенами, уже выпущенными из токенизатора ParseKit. Не отдельные символы.

IOW: к тому времени, когда ваша грамматика начнет анализировать входные данные, входные данные уже будут токенизированы в токены типа Word, Number, Symbol, QuotedString и т. д.

Вот все встроенные продукты, доступные для использования в вашей грамматике:

Word
Number 
Symbol
QuotedString
Comment
Any
S // Whitespace. only available when @preservesWhitespaceTokens=YES. NO by default.

Также:

DelimitedString('start', 'end', 'allowedCharset')
/xxx/i // RegEx match

Также есть операторы для составных парсеров:

  // Sequence
| // Alternation
? // Optional
+ // Multiple
* // Repetition
~ // Negation
& // Intersection
- // Difference
person Todd Ditchendorf    schedule 09.12.2012
comment
Итак, вывод заключается в том, что значение PK по умолчанию Word уже имеет неявное определение identifier, что делает мое определение избыточным и трудным для разрешения в режиме токена PK? Значит, простого изменения identifier = Word ; должно быть достаточно, чтобы вернуть меня в нужное русло? Спасибо! - person Grimless; 10.12.2012