Will McGugan
2014-06-27 17:13:25 UTC
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()
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
Will McGugan
http://www.willmcgugan.com