Что не так с этим ParseKit BNF?

Я использую ParseKit для Objective-C, который использует синтаксис, подобный BNF, для указания грамматиков:

@start = command+;
command = new;
new = 'new' object ';';
object = 'house' | other;

Включение последней строки вызывает ошибку. В основном я хочу сказать, что объект может быть домом или чем-то еще. Предполагается, что нетерминальный элемент «другой» улавливает любое слово, которое не было домом.

Я неправильно понимаю идею «что-нибудь здесь»?

Спасибо!


person FBryant87    schedule 21.07.2011    source источник
comment
Это не так, я хочу, чтобы собиралось любое слово, которое не является домом.   -  person FBryant87    schedule 21.07.2011
comment
Например: новый отель Я думал, что это позволит вставить любое слово после «новый», и я мог сопоставить «другое», чтобы найти его содержимое.   -  person FBryant87    schedule 21.07.2011
comment
Вы создали правило для других?   -  person Joe    schedule 21.07.2011
comment
нет, как я уже говорил выше. Это то, что я думаю, что я ошибаюсь, как я могу сопоставить «что угодно». Посмотрите на этот грамматик для адреса электронной почты: электронная почта = имя пользователя '@' домен '.com' имя пользователя и домен могут быть любыми, так как я могу указать правила для них?   -  person FBryant87    schedule 21.07.2011
comment
Я не работал с parsekit и его синтаксисом BNF, но я использовал flex/bison, и он должен поддерживать регулярное выражение. Замените other на \w+ (просто для проверки)   -  person Joe    schedule 21.07.2011
comment
Глядя на исходный код, для этого могут быть встроены значения. Попробуйте заменить другое на Word   -  person Joe    schedule 21.07.2011
comment
ах, большое спасибо, похоже, это было принято. Не могли бы вы подытожить, для чего предназначен «Word»?   -  person FBryant87    schedule 21.07.2011
comment
Я ищу его, дайте мне немного времени, определение, похоже, похоронено глубоко в исходном коде. Когда я найду, я опубликую ответ. Кроме того, Word не будет тем, что вам нужно, потому что он позволяет именам начинаться с цифр и тому подобного.   -  person Joe    schedule 21.07.2011
comment
Хорошо, большое спасибо за вашу помощь, я пытался посмотреть источник, но не мог понять его.   -  person FBryant87    schedule 21.07.2011
comment
Я не могу говорить о том, как работает ParseKit, но кажется, что ваша фундаментальная проблема заключается в том, что вы не контролируете определение other, и у вас, похоже, нет возможности определить его с помощью ParseKit (честно говоря, я был бы поражен найти систему генератора синтаксических анализаторов, которая не позволяла бы вам каким-то образом определять токены, но мир полон странных вещей). Итак, либо узнайте, как ParseKit позволяет определить собственный токен, либо переключитесь на систему генератора парсеров, в которой понятно, как это сделать (канонический ответ — Flex и YACC).   -  person Ira Baxter    schedule 21.07.2011


Ответы (2)


Как было предложено в комментариях, вы должны либо заменить other на Word, либо добавить новое правило:

other = Word;

Поскольку 'house' является Word, вы также можете напрямую заменить правило object на:

object = Word;

Word в ParseKit — это непрерывная последовательность символов ([a-zA-Z]), чисел ([0-9]) и символов -, _ и ', которая начинается с символа. Дополнительную информацию о токенах ParseKit можно найти в документации.

person Carmine Paolino    schedule 19.08.2011

Разработчик ParseKit здесь. Ответ Кармине выше превосходен, и вы должны последовать его совету. Одно небольшое дополнение:

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

object = house | other;
house = 'house';
other = Word;

Затем вы должны реализовать два следующих метода обратного вызова в делегате Parser:

- (void)parser:(PKParser *)p didMatchHouse:(PKAssembly *)a;
- (void)parser:(PKParser *)p didMatchOther:(PKAssembly *)a;

Если вы хотите, чтобы other вообще соответствовало любому токену (не только словам, но и числам, символам, строкам в кавычках и т. д.), вы можете использовать встроенный тип Any. В этом случае вы должны изменить последнюю строку моего примера выше на:

other = Any;
person Todd Ditchendorf    schedule 14.10.2011