Вот упрощение моей рабочей EBNF грамматики:Как решить эту проблему S/R конфликт
%token NEWLINE BLOCK_MARK A
%start file
file: block+ NEWLINE*;
block: BLOCK_MARK line;
line: A+;
И \ п и EOF выплюнуть NEWLINE как знак (так что один окончание NEWLINE не требуется до EOF). Он работает с потоком, как это:
BLOCK_MARK A A BLOCK_MARK A NEWLINE[actually EOF]
Теперь я хочу иметь несколько line
в block
, по крайней мере, один является обязательным, а остальным разделено NEWLINE
. Например .:
BLOCK_MARK A A NEWLINE A A BLOCK_MARK A A A EOF
Я попытался сделать это:
file: block+ NEWLINE*;
block: BLOCK_MARK line moreline*;
line: A+;
moreline: NEWLINE line;
Но Jison жалуется на S/R конфликт, когда опережения является NEWLINE
. Я предполагаю, что машина состояний запуталась, решив, является ли NEWLINE
частью нового блока line
или окончательного NEWLINE*
в file
(что необходимо, потому что файл может закончиться с NEWLINE/EOF).
Как это исправить?
Одним из механизмов может быть прекращение обработки новых строк как EOF; они совсем не то же самое. Я более чем озадачен тем, как это работает. –
@JonathanLeffler это наоборот, я рассматриваю EOF как NEWLINE. Я думаю, что я не единственный, кто делает это, чтобы сделать окончание NEWLINE не обязательным (так как EOF анализируется как NEWLINE). Изменение 'file' на' file: block + NEWLINE * EOF' не устраняет проблему и делает ее еще хуже, требуя как 'NEWLINE' (для' line'), так и 'EOF' (для' file') в качестве последних проанализированных токенов. – kaoD