2015-07-28 22 views
3

Я пишу парсер для анализа математических выражений, которые содержат переменные между прочим. Мне нужен список всех захваченных переменных. Но я получаю только последнюю захваченную переменную. Ниже приведен минимальный пример, чтобы показать проблему.pyparsing: названные результаты?

>>> from pyparsing import * 
    >>> var = Word(alphas) 
    >>> expr = Forward() 
    >>> expr << var('var') + ZeroOrMore(Literal('+') + expr) 
    >>> foo = expr.parseString("x + y + z") 
    >>> foo 
    (['x', '+', 'y', '+', 'z'], {'var': [('x', 0), ('y', 2), ('z', 4)]}) 
    >>> foo['var'] 
    'z' 

Я ожидал ['x', 'y', 'z']. Я использую pyparsing версии 2.1.

ответ

2

По умолчанию названные результаты только фиксируют последний элемент. Если вы используете явный вызов метода setResultsName, вы можете получить все элементы, добавив необязательный аргумент listAllMatches=True. Так как вы используете форму быстрого var('var'), вы можете получить поведение listAllMatches если вы заканчиваете имя результатов с «*»:

expr << var('var*') + ZeroOrMore(Literal('+') + expr) 

Я предпочитаю использовать метод dump() перечислить тело и имена из разобраны результаты:

>>> foo = expr.parseString("x + y + z") 
>>> foo.var 
(['x', 'y', 'z'], {}) 
>>> print foo.dump() 
['x', '+', 'y', '+', 'z'] 
- var: ['x', 'y', 'z'] 

Кстати, так как вы определили вашу грамматику таким образом, ваши действия будут оценены справа налево. Это будет хорошо, если вы оцениваете только добавление, но выполнение «3 - 5 + 2» справа налево даст вам -4, когда вы должны получить 0. Посмотрите на использование infixNotation (ранее называвшегося operatorPrecedence) для определения и оценки арифметики и булевы выражения. Есть также несколько примеров, доступных на вики-пираре на pyparsing.wikispaces.com.

+0

Спасибо, Пол. Просто интересно, почему listAllMatches не является True по умолчанию, мне кажется, что это более полезный случай. – Tima

+0

Возможно, я мог бы обосноваться, но, скорее всего, это проблема истории. Сначала я реализовал одно значение return, а затем добавил параметр «listAllMatches» позже. «Более полезный случай»? Не так уверен в этом - через 12 лет после первого выпуска pyparsing только небольшая группа людей спросила об этой функции. Но я рад, что вы смогли решить вашу проблему с существующей функцией в pyparsing. – PaulMcG

Смежные вопросы