С помощью библиотеки синтаксического анализа pyparsing
Я хочу, чтобы анализировать конструкции, как это:Как сделать первую часть двух частей синтаксического эквивалентных необязательных при анализе с Pyparsing
123 456
-^- -^-
[A] B
где обе части и B только содержат номера и часть A не является обязательным. Вот некоторые примеры того, как синтаксический анализатор для этого будет ломают строк вниз в их части:
123 456 ==> A="123", B="456"
456 ==> A="", B="456"
123 ==> A="", B="123"
1 123 ==> A="1", B="123"
Уроженец подход написать парсер выглядит следующим образом:
a = pp.Optional(pp.Word(pp.nums)).setName("PART_A")
b = pp.Word(pp.nums).setName("PART_B")
expr = a('A') + b('B')
Этот анализатор работает для "123 456"
возвращения, как ожидается, {'A': '123', 'B': '456'}
, Однако он не на "456"
с:
ParseException:
Expected PART_B (at char 3), (line:1, col:4)
"456>!<"
Это понятно, так как необязательная часть уже потребляет текст, который должен соответствовать частям B даже если был необязательным ... Моя идея состояла в том, чтобы установить stopOn=
вариант, но для этого нужно остановиться на выражение того же типа, что и выражение он хочет, чтобы соответствовать ...
Update: Моя вторая идея состояла в том, чтобы переписать Optional
конструкт Int К О Or
конструкция:
a = pp.Word(pp.nums).setName("PART_A")('A')
b = pp.Word(pp.nums).setName("PART_B")('B')
just_b = b
a_and_b = a + b
expr = pp.Or(just_b, a_and_b)
Однако это сейчас не выполняется для текстов вида "123 456"
- несмотря на то, что a_and_b
является альтернативой в Or
классе ...
Любое предложение, что делать?
Работает отлично. Какой надзор с моей стороны: или ожидает списки! – halloleo
Итак, правильно ли я понимаю, что класс 'Optional' не нужен при использовании' a + b | b' construct? – halloleo
Правильно, поскольку вы явно описываете два разрешенных случая. Ведущий необязательный сам по себе не будет работать так, как вы обнаружили. Если вы хотите, чтобы «b» был необязательным, вы могли бы сделать «a + b | a' или просто 'a + Необязательный (b)'. Но, как вы видели, ведущий факультатив не так прост. 'Необязательно (a) + b' будет терпеть неудачу на '456', потому что« 456 »будет соответствовать« a », а затем не будет« b ». Мы должны заставить парсер мыслить так, как мы. То есть, мы знаем, что присутствует только, если следовать b. Поэтому это должно работать, если вы хотите использовать опцию: expr = необязательный (a + FollowedBy (b)) + b'. – PaulMcG