Распознавание нескольких new_lines в PEGKit

Я учусь использовать PEGKit, но столкнулся с проблемой создания грамматики для скрипта, который анализирует строки, даже если они разделены несколькими символами разрыва строки. Я свел проблему к этой грамматике:

expr
@before {
    PKTokenizer *t = self.tokenizer;
    self.silentlyConsumesWhitespace = NO;
    t.whitespaceState.reportsWhitespaceTokens = YES;
    self.assembly.preservesWhitespaceTokens = YES;
}
= Word nl*;
nl = nl_char nl_char*;
nl_char = '\n'! | '\r'!;

Эта простая грамматика для меня должна содержать по одному слову в строке с таким количеством разрывов строк, сколько необходимо. Но он допускает только одно слово с необязательным переводом строки. Кто-нибудь знает, что здесь не так? Спасибо.

1 ответ

Решение

Создатель PEGKit здесь.

Вместо этого попробуйте следующую грамматику (убедитесь, что вы используете HEAD of master):

@before {
    PKTokenizer *t = self.tokenizer;

    [t.whitespaceState setWhitespaceChars:NO from:'\\n' to:'\\n'];
    [t.whitespaceState setWhitespaceChars:NO from:'\\r' to:'\\r'];
    [t setTokenizerState:t.symbolState from:'\\n' to:'\\n'];
    [t setTokenizerState:t.symbolState from:'\\r' to:'\\r'];
}

lines = line+;
line  = ~eol* eol+; // note the `~` Not unary operator. this means "zero or more NON eol tokens, followed by one or more eol token"
eol   = '\n'! | '\r'!;

Обратите внимание, что здесь я настраиваю токенизатор, чтобы распознать переводы строки и возврат каретки как Symbol а не пробел. Это облегчает сопоставление и отбрасывание их (они отбрасываются ! оператор).

Для другого подхода к той же проблеме с помощью встроенного S правило пробелов, смотрите здесь.

Другие вопросы по тегам