Using LEPL to analyze a logical search query

I am trying to write a LEPL grammar to describe a logical search language. This is what I have so far:

from lepl import * text = String() | Word() tail = ~Lookahead('AND') & ~Lookahead('OR') & text with DroppedSpace(): andClause = (tail & Lookahead('AND') & Drop('AND') & tail)[1:] > tuple orClause = (tail & Lookahead('OR') & Drop('OR') & tail)[1:] > list andOrText = (andClause & Lookahead('OR') & Drop('OR') & tail)[1:] > list orAndText = (orClause & Lookahead('AND') & Drop('AND') & tail)[1:] > tuple oredAnds = (andClause & Lookahead('OR') & Drop('OR') & andClause)[1:] > list andedOrs = (orClause & Lookahead('AND') & Drop('AND') & orClause)[1:] > tuple query = (oredAnds | andedOrs | orAndText | andOrText | orClause | andClause | text)[:] query.parse('foo AND bar') # Works query.parse('"bar none" OR foo') # Works query.parse('foo AND "bar none" OR baz AND floo') # Works query.parse('a AND b OR c AND d OR e') # Doesn't work 

The last parse produces the following:

 [[('a', 'b'), ('c', 'd')], 'OR', 'e'] 

He must produce this:

 [[('a', 'b'), ('c', 'd'), 'e']] 

How can I fix this to get the parsing I want? I think this will fix it if I could say that โ€œanythingโ€ becomes tuple , and โ€œwhateverโ€ becomes list .

+4
source share
1 answer

Edit: got rid of the rest of sloooooow recursion thanks to this article and added keyword options.

 from lepl import * def ander(result): if len(result) == 2: return (result[0], result[1]) return result[0] text = String() | Word() andClausePrime = Delayed() label = text & Drop(':') with DroppedSpace(): parameter = label & text > (lambda r: {r[0]: r[1]}) andClause = (parameter | text) & andClausePrime > ander andClausePrime += (Drop('AND') & (andClause | parameter | text) & andClausePrime)[:] expr = andClause | parameter | text query = expr & (Drop('OR') & expr)[:] 

Results:

 >>> query.parse('a AND b') [('a', 'b')] >>> query.parse('a AND b AND c') [('a', ('b', 'c'))] >>> query.parse('a AND b AND c AND d') [('a', ('b', ('c', 'd')))] >>> query.parse('a AND b AND c AND d OR e AND f') [('a', ('b', ('c', 'd'))), ('e', 'f')] >>> query.parse('a AND b AND c AND d OR e OR f') [('a', ('b', ('c', 'd'))), 'e', 'f'] >>> query.parse('foo AND bar') [('foo', 'bar')] >>> query.parse('"bar none" OR foo') ['bar none', 'foo'] >>> query.parse('key:value AND "hey now":5 OR "what is":up') [({'key': 'value'}, {'hey now': '5'}), {'what is': 'up'}] 
+5
source

All Articles