Не совсем, похоже, у них разные ошибки.Первая последовательность неоднозначна вокруг «элемента», видя, что «дополнительный» является необязательным.Вы можете переписать его следующим образом, чтобы убрать неоднозначность:
sequence3 ::=
item extra* sequence3
Второй неоднозначен вокруг «extra», поскольку в основном это два вложенных цикла, начинающихся с «extra».Вы можете переписать его следующим образом, чтобы убрать неоднозначность:
sequence4 ::=
item ((extra|item))*
Ваша первая версия, вероятно, захлебнется входной последовательностью, состоящей из одного «элемента» (это зависит от реализации синтаксического анализатора), потому что она не будетнеоднозначность.
Мои переписки предполагают, что вы хотите сопоставить последовательность, начинающуюся с «item» и, возможно, за которой следует последовательность (0 или более) «item» или «extra» в любом порядке.
например
item
item extra
item extra item
item extra extra item
item item item item
item item item item extra
etc.
Без дополнительной информации я лично был бы склонен к опции, которую я пометил "sequence4", поскольку все другие опции просто используют рекурсию в качестве дорогостоящей конструкции цикла.Если вы захотите дать мне больше информации, я смогу дать лучший ответ.
РЕДАКТИРОВАТЬ: на основе превосходного наблюдения Йорна (с небольшим модом).
Если вы переписали «sequence3» для удаления рекурсии, вы получите следующее:
sequence5 ::=
(item extra*)+
Это будет моя предпочтительная версия, а не «sequence4».
Я должен указать, чтовсе три версии выше функционально эквивалентны (как распознаватели или генераторы).Деревья разбора для 3 будут отличаться от 4 и 5, но я не могу думать, что это повлияет на что-то кроме, возможно, производительности.
РЕДАКТИРОВАТЬ: Относительно следующего:
lineto-argument-sequence:
coordinate-pair
| coordinate-pair comma-wsp? lineto-argument-sequence
В этом произведении говорится, что lineto-argument-sequence
состоит по крайней мере из одного coordinate-pair
, за которым следует ноль или более coordinate-pair
, разделенных необязательной белой / запятой.Любое из следующего будет составлять lineto-argument-sequence
(читается -> как «становится»):
1,2 -> (1, 2)
1.5.6 -> (1.5, 0.6)
1.5.06 -> (1.5, 0.06)
2 3 3 4 -> (2,3) (3,4)
2,3-3-4 -> (2,3) (-3,-4)
2 3 3 -> ERROR
Так что coordinate-pair
- это действительно любые 2 последовательных number
с.
Я разработал грамматику в ANTLR, которая, кажется, работает.Обратите внимание, что шаблон, используемый для lineto_argument_sequence
, аналогичен шаблону, который Jorn и я рекомендовал ранее.
grammar SVG;
lineto_argument_sequence
: coordinate_pair (COMMA_WSP? coordinate_pair)*
;
coordinate_pair
: coordinate COMMA_WSP? coordinate
;
coordinate
: NUMBER
;
COMMA_WSP
: ( WS+|WS*','WS*) //{ $channel=HIDDEN; }
;
NUMBER
: '-'? (INT | FLOAT) ;
fragment
INT
: '0'..'9'+ ;
fragment
FLOAT
: ('0'..'9')+ '.' ('0'..'9')* EXPONENT?
| '.' ('0'..'9')+ EXPONENT?
| ('0'..'9')+ EXPONENT
;
fragment
WS : ' ' | '\t' | '\r' | '\n' ;
fragment
EXPONENT
: ('e'|'E') ('+'|'-')? ('0'..'9')+ ;
Учитывая следующий ввод:
2, 3 -3 -4 5.5.65.5.6
он создает это дерево разбора.
альтернативный текст http://www.freeimagehosting.net/uploads/85fc77bc3c.png