2017-03-31 51 views
2

如何使一個解析器,這將使使用pyparsing庫根據表達式算術優先括號,使? 例如*具有比+更高的優先級。的Python語法分析器括號根據運算優先級

應該這樣做:

»> print(wholeexp.parseString('3+5-2')) 
[[['3', '+', '5'], '-', '2']] 
»> print(wholeexp.parseString('3+(5-2)')) 
[['3', '+', ['5', '-', '2']]] 
»> print(wholeexp.parseString('3+5-2*4')) 
[[['3', '+', '5'], '-', ['2', '*', '4']]] 

我嘗試以下,但它並不能很好地工作。我們應該如何改變EXPR這裏:

from pyparsing import * 

numb = Word(nums) 
leftpar = Suppress('(') 
rightpar = Suppress(')') 

expr = Forward() 
expr << Or([numb, 
    Group(leftpar + expr + "+" + expr + rightpar), 
    Group(leftpar + expr + "-" + expr + rightpar), 
    Group(leftpar + expr + "*" + expr + rightpar)]) 

wholeexp = expr + StringEnd() 
+0

您是否檢查了[本文檔](https://pyparsing.wikispaces.com/file/view/SimpleCalc.py)? –

+0

遞歸下降解析器將幫助:https://en.wikipedia.org/wiki/Recursive_descent_parser。或者調車碼算法:https://en.wikipedia.org/wiki/Shunting-yard_algorithm。但首先看到這個問題來決定選擇哪個:http://stackoverflow.com/questions/28256/equation-expression-parser-with-precedence。 – rajah9

回答

0

這篇文章很有前途:Simple Top-Down Parsing in Python 我知道這是很多,但滾動到「精簡令牌類生成」部分的底部,你會看到它的行動。我個人無法得到它,因爲一個錯誤的工作:AttributeError: 'generator' object has no attribute 'next'但我敢肯定它是與事實,未來方法在Python 3.0改變的事情。代碼對於我來說很難理解並解決這個問題,但你可能會有更好的運氣。

編輯:剛跑它的Python 2.7和它的工作。您可以運行在較舊版本的python中,也可以通過代碼嘗試修復它。

+0

任何其他變種? – parYosef

1

你的做法是類似於此pyparsing示例中使用:http://pyparsing.wikispaces.com/file/view/fourFn.py。但最近的pyparsing介紹operatorPrecedence版本,最近更名爲infixNotation,和您的4功能的算術表達式解析器是這樣的:

import pyparsing as pp 

integer = pp.pyparsing_common.integer() 

four_fn_arith_expr = pp.infixNotation(integer, 
            [ 
             # leading sign 
             (pp.oneOf("+ -"), 1, pp.opAssoc.RIGHT,), 
             # multiplication and division 
             (pp.oneOf("* /"), 2, pp.opAssoc.LEFT,), 
             # addition and subtraction 
             (pp.oneOf("+ -"), 2, pp.opAssoc.LEFT,), 
            ]) 

這裏是你的測試用例與此解析器運行:

tests = """ 
    3+5-2 
    3+(5-2) 
    3+5--2 
    3+5-2*4 
    """ 
four_fn_arith_expr.runTests(tests, fullDump=False) 

授予:

3+5-2 
[[3, '+', 5, '-', 2]] 

3+(5-2) 
[[3, '+', [5, '-', 2]]] 

3+5--2 
[[3, '+', 5, '-', ['-', 2]]] 

3+5-2*4 
[[3, '+', 5, '-', [2, '*', 4]]] 
+0

我們需要解析器,它將從左到右並在算術運算後進行。將根據優先級f.e.製作括號。 (fullexp.parseString('3 + 5-2')) [[' .parseString('3+(5-2)')) [['3','+',['5',' - ','2']]] »print(wholeexp.parseString(' print(expr 3 + 5-2 * 4')) [['3','+','5'],' - ',['2','*','4']]] print .parseString('3 + 5-4-2')) [[[[''','','5'],' - ','4'],' - ','2']] 使用轉發和特定功能。 請幫助我,謝謝! – parYosef

+0

剩下的這個轉變留給了OP。 – PaulMcG