Merge pull request #23 from ltworf/improve_parser

Improve parser
master
Salvo 'LtWorf' Tomaselli 2020-06-18 17:16:53 +07:00 committed by GitHub
commit 3b1e90b30e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 10 additions and 11 deletions

@ -150,7 +150,7 @@ class Node:
elif isinstance(self, Binary) and self.name == DIVISION:
return list(set(self.left.result_format(rels)) - set(self.right.result_format(rels)))
elif self.name == PROJECTION:
return [i.strip() for i in self.prop.split(',')]
return self.get_projection_prop()
elif self.name == PRODUCT:
return self.left.result_format(rels) + self.right.result_format(rels)
elif self.name == SELECTION:
@ -231,7 +231,7 @@ class Unary(Node):
# Converting parameters
if self.name == PROJECTION:
prop = '\"%s\"' % prop.replace(' ', '').replace(',', '\",\"')
prop = repr(self.get_projection_prop())
elif self.name == RENAME:
prop = repr(self.get_rename_prop())
else: # Selection
@ -270,8 +270,6 @@ class Unary(Node):
self.prop = ','.join(f'{k}{ARROW}{v}' for k, v in renames.items())
def parse_tokens(expression: List[Union[list, str]]) -> Node:
'''Generates the tree from the tokenized expression
If no expression is specified then it will create an empty node'''
@ -281,12 +279,14 @@ def parse_tokens(expression: List[Union[list, str]]) -> Node:
while len(expression) == 1 and isinstance(expression[0], list):
expression = expression[0]
if len(expression) == 0:
raise ParserException('Failed to parse empty expression')
# The list contains only 1 string. Means it is the name of a relation
if len(expression) == 1:
if not rtypes.is_valid_relation_name(expression[0]):
raise ParserException(
u"'%s' is not a valid relation name" % expression[0])
f'{expression[0]!r} is not a valid relation name')
return Variable(expression[0]) #FIXME Move validation in the object
# Expression from right to left, searching for binary operators
@ -302,28 +302,27 @@ def parse_tokens(expression: List[Union[list, str]]) -> Node:
for i in range(len(expression) - 1, -1, -1):
if expression[i] in b_operators: # Binary operator
if len(expression[:i]) == 0:
raise ParserException(
u"Expected left operand for '%s'" % self.name)
f'Expected left operand for {expression[i]!r}')
if len(expression[i + 1:]) == 0:
raise ParserException(
u"Expected right operand for '%s'" % self.name)
f'Expected right operand for {expression[i]!r}')
return Binary(expression[i], parse_tokens(expression[:i]), parse_tokens(expression[i + 1:]))
'''Searches for unary operators, parsing from right to left'''
for i in range(len(expression) - 1, -1, -1):
if expression[i] in u_operators: # Unary operator
if len(expression) <= i + 2:
raise ParserException(
u"Expected more tokens in '%s'" % self.name)
f'Expected more tokens in {expression[i]!r}')
return Unary(
expression[i],
prop=expression[1 + i].strip(),
child=parse_tokens(expression[2 + i])
)
raise ParserException('Parse error') #FIXME more details
raise ParserException(f'Parse error on {expression!r}')
def _find_matching_parenthesis(expression: str, start=0, openpar='(', closepar=')') -> Optional[int]: