[Pyparsing] Recursive Grammar
Brought to you by:
ptmcg
From: Will M. <wil...@gm...> - 2014-06-27 17:13:33
|
Hi, I have a moderately complex grammar that is throws a recursion error when parsing the expression "(1,2,3,(4,5,6,(7,8,9)))" (a nested data structure). I've pasted the grammar definition below, can you give me some guidance on where I've made the grammar recursive? Thanks in advance! integer = Word(nums) real = Combine(Word(nums) + "." + Word(nums)) constant = oneOf('True False None yes no') + WordEnd() variable = Regex(r'([a-zA-Z0-9\._]+)') explicit_variable = '$' + Regex(r'([a-zA-Z0-9\._]+)') string = QuotedString('"', escChar="\\") | QuotedString('\'', escChar="\\") regexp = QuotedString('/', escChar=None) timespan = Combine(Word(nums) + oneOf('ms s m h d')) variable_operand = variable explicit_variable_operand = explicit_variable integer_operand = integer real_operand = real number_operand = real | integer string_operand = string #operand = variable | real | integer | string assignop = Literal('=') groupop = Literal(',') signop = oneOf('+ -') multop = oneOf('* / // %') filterop = oneOf('|') plusop = oneOf('+ -') notop = Literal('not') rangeop = Literal('..') exclusiverangeop = Literal('...') ternaryop = ('?', ':') variable_operand.setParseAction(EvalVariable) explicit_variable_operand.setParseAction(EvalExplicitVariable) integer_operand.setParseAction(EvalInteger) real_operand.setParseAction(EvalReal) string_operand.setParseAction(EvalString) constant.setParseAction(EvalConstant) regexp.setParseAction(EvalRegExp) timespan.setParseAction(EvalTimespan) expr = Forward() modifier = Combine(Word(alphas + nums) + ':') callop = Group(('(') + expr + Suppress(')')) index = Group(('[') + expr + Suppress(']')) braceop = callop | index operand = (timespan | real_operand | integer_operand | string_operand | regexp | constant | explicit_variable_operand | variable_operand ) comparisonop = (oneOf("< <= > >= != == ~= ^= $=") | (Literal('is not') + WordEnd()) | (oneOf("is in instr lt lte gt gte matches fnmatches") + WordEnd()) | (Literal('not in') + WordEnd()) | (Literal('not instr') + WordEnd())) logicop = oneOf("and or") + WordEnd() logicopOR = Literal('or') + WordEnd() logicopAND = Literal('and') + WordEnd() formatop = Literal('::') expr << operatorPrecedence(operand, [ (signop, 1, opAssoc.RIGHT, EvalSignOp), (exclusiverangeop, 2, opAssoc.LEFT, EvalExclusiveRangeOp), (rangeop, 2, opAssoc.LEFT, EvalRangeOp), (braceop, 1, opAssoc.LEFT, EvalBraceOp), (modifier, 1, opAssoc.RIGHT, EvalModifierOp), (formatop, 2, opAssoc.LEFT, EvalFormatOp), (multop, 2, opAssoc.LEFT, EvalMultOp), (plusop, 2, opAssoc.LEFT, EvalAddOp), (assignop, 2, opAssoc.LEFT, EvalAssignOp), (groupop, 2, opAssoc.LEFT, EvalGroupOp), (filterop, 2, opAssoc.LEFT, EvalFilterOp), (comparisonop, 2, opAssoc.LEFT, EvalComparisonOp), (notop, 1, opAssoc.RIGHT, EvalNotOp), (logicopOR, 2, opAssoc.LEFT, EvalLogicOpOR), (logicopAND, 2, opAssoc.LEFT, EvalLogicOpAND), (ternaryop, 3, opAssoc.LEFT, EvalTernaryOp), ]) expr.validate() -- Will McGugan http://www.willmcgugan.com |