У меня есть два необязательных значения, и когда оба присутствуют, между ними должна быть запятая. Если присутствует одно или оба значения, может быть запятой, но если значения отсутствуют, запятая не допускается.
Допустимые примеры:
(first,second,)
(first,second)
(first,)
(first)
(second,)
(second)
()
Неверно примеров:
(first,first,)
(first,first)
(second,second,)
(second,second)
(second,first,)
(second,first)
(,first,second,)
(,first,second)
(,first,)
(,first)
(,second,)
(,second)
(,)
(,first,first,)
(,first,first)
(,second,second,)
(,second,second)
(,second,first,)
(,second,first)
У меня есть код EBNF ( XML-приправленный ), которого достаточно, но есть ли способ, которым я могу упростить его? Я хотел бы сделать его более читабельным / менее повторяющимся.
tuple ::= "(" ( ( "first" | "second" | "first" "," "second" ) ","? )? ")"
Если это легче понять в регулярных выражениях, вот эквивалентный код, но мне нужно решение в EBNF.
/\(((first|second|first\,second)\,?)?\)/
А вот полезная железнодорожная схема:
Этот вопрос становится еще более сложным, когда мы абстрагируем его от трех терминов : "first"
, "second"
и "third"
не являются обязательными, но они должны появляться в том порядке, разделенном запятыми , с дополнительной запятой. Лучшее, что я могу придумать, - это метод грубой силы:
"(" (("first" | "second" | "third" | "first" "," "second" | "first" "," "third" | "second" "," "third" | "first" "," "second" "," "third") ","?)? ")"
Очевидно, что решение, включающее O (2 n ) сложность, не очень желательно.