Advertisement
D3f1

PyParsing Functions with one or more operands

Feb 9th, 2014
28
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 3.32 KB | None | 0 0
  1. #from pyparsing import (
  2. #    Word, Regex, Group, oneOf, Forward, CaselessKeyword, Suppress,
  3. #    delimitedList, operatorPrecedence, opAssoc, ParseException)
  4.  
  5. from pyparsing import *
  6.  
  7. # Variables
  8. variable = Regex(r'(?P<table>[ai|di|sv]{2})\.(?P<tag>[\w\d]+)\.(?P<attr>\w+)')
  9.  
  10.  
  11. def var_parse_action(text, index, context):
  12.     return context[0]
  13.  
  14. variable.setParseAction(var_parse_action)
  15.  
  16. # Numbers
  17. numeric_literal = Regex(r"\-?\d+(\.\d+)?")
  18.  
  19.  
  20. def number_prase_action(text, index, data):
  21.     number = data[0]
  22.     if '.' in number:
  23.         return float(number)
  24.     else:
  25.         return int(number)
  26.  
  27. numeric_literal.setParseAction(number_prase_action)
  28.  
  29. EXCL, LPAR, RPAR, COLON, COMMA = map(Suppress, '!():,')
  30.  
  31. expr = Forward()
  32.  
  33. # IF CONDITION
  34. COMPARISON_OP = oneOf("< = > >= <= != <>")
  35. condExpr = (expr + COMPARISON_OP + expr) | variable
  36.  
  37. ifFunc = (CaselessKeyword("si") +
  38.           LPAR +
  39.           Group(condExpr)("condition") +
  40.           COMMA + expr("if_true") +
  41.           COMMA + expr("if_false") + RPAR)
  42.  
  43. #def ifFunc_parse_action(text, index, context):
  44. #    print "hola"
  45. #    return context
  46. #
  47. #ifFunc.setParseAction(ifFunc_parse_action)
  48.  
  49. arguments = Forward()
  50.  
  51. one_op_func = lambda name: (CaselessKeyword(name) + LPAR + arguments + RPAR)
  52.  
  53. int_cast = one_op_func('int')
  54.  
  55. def int_cast_parse_action(text, index, context):
  56.     return int(context[1])
  57.  
  58. int_cast.setParseAction(int_cast_parse_action)
  59. float_cast = one_op_func('float')
  60. str_cast = one_op_func('str')
  61.  
  62. sqrt_func = one_op_func('raiz')
  63.  
  64.  
  65. multi_op_func = lambda name: CaselessKeyword(name) + LPAR + delimitedList(arguments) + RPAR
  66.  
  67. # Statistical functions
  68. sumFunc = multi_op_func("sum")
  69. minFunc = multi_op_func("min")
  70. maxFunc = multi_op_func("max")
  71. aveFunc = multi_op_func("ave")
  72.  
  73. # Logical functions
  74. orFunc = multi_op_func('or')
  75. andFunc = multi_op_func('and')
  76.  
  77. multOp = oneOf("* /")
  78. addOp = oneOf("+ -")
  79.  
  80.  
  81. funcCall = (ifFunc | # If expression
  82.             sumFunc | minFunc | maxFunc | aveFunc | # statisticial functions
  83.             int_cast | str_cast | float_cast | # Casts
  84.             orFunc | andFunc | # Logical
  85.             sqrt_func
  86.             )
  87.  
  88. arguments << (Group(expr) | numeric_literal | variable)
  89.  
  90.  
  91. operand = Forward()
  92. arithExpr = operatorPrecedence(operand,[
  93.                                         (multOp, 2, opAssoc.LEFT),
  94.                                         (addOp, 2, opAssoc.LEFT),
  95.                                ])
  96.  
  97. operand << (arithExpr | numeric_literal  | variable)
  98.  
  99. def arithExpr_parse_action(text, index, context):
  100.     print "ARIEXPR", context
  101.  
  102. expr << (arithExpr | funcCall | numeric_literal | variable )
  103.  
  104.  
  105. def test_line(line):
  106.     try:
  107.         print expr.parseString(line)
  108.     except ParseException as err:
  109.         print err.line
  110.         print " "*(err.column-1) + "^"
  111.         print err
  112.  
  113.  
  114. if __name__ == '__main__':
  115.     #main()
  116.     #test_formulas_files()
  117.  
  118.     test_line('int(3)+int(4)')
  119.     test_line('or(0,1,2)')
  120.     test_line('str(aa.bb.cc)')
  121.     test_line('str(si(0>2,aa.bb.cc,4))')
  122.     test_line('RAIZ(ai.E42PA_01.value*ai.E42PA_01.value+ai.E42PR_01.value*ai.E42PR_01.value)*ai.E42PA_01.escala')
  123.     test_line('str(raiz(3)*2)')
  124.     test_line('str(RAIZ(ai.E42PA_01.value*ai.E42PA_01.value+ai.E42PR_01.value*ai.E42PR_01.value)*ai.E42PA_01.escala)')
  125.     test_integer()
  126.     test_logic()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement