aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xparsertest.py94
1 files changed, 77 insertions, 17 deletions
diff --git a/parsertest.py b/parsertest.py
index b7515d9..9e8fdfa 100755
--- a/parsertest.py
+++ b/parsertest.py
@@ -148,6 +148,40 @@ class EmptyNode:
self.colno = 0
self.value = None
+class OrNode:
+ def __init__(self, lineno, colno, left, right):
+ self.lineno = lineno
+ self.colno = colno
+ self.left = left
+ self.right = right
+
+class AndNode:
+ def __init__(self, lineno, colno, left, right):
+ self.lineno = lineno
+ self.colno = colno
+ self.left = left
+ self.right = right
+
+class EqualNode:
+ def __init__(self, lineno, colno, left, right):
+ self.lineno = lineno
+ self.colno = colno
+ self.left = left
+ self.right = right
+
+class NEqualNode:
+ def __init__(self, lineno, colno, left, right):
+ self.lineno = lineno
+ self.colno = colno
+ self.left = left
+ self.right = right
+
+class NotNode:
+ def __init__(self, lineno, colno, value):
+ self.lineno = lineno
+ self.colno = colno
+ self.value = value
+
class CodeBlockNode:
def __init__(self, lineno, colno):
self.lineno = lineno
@@ -179,6 +213,20 @@ class AssignmentNode:
assert(isinstance(var_name, str))
self.value = value
+class IfClauseNode():
+ def __init__(self, lineno, colno):
+ self.lineno = lineno
+ self.colno = colno
+ self.ifs = []
+ self.elseblock = EmptyNode()
+
+class IfNode():
+ def __init__(self, lineno, colno, condition, block):
+ self.lineno = lineno
+ self.colno = colno
+ self.condition = condition
+ self.block = block
+
class ArgumentNode():
def __init__(self, token):
self.lineno = token.lineno
@@ -267,24 +315,26 @@ class Parser:
def e2(self):
left = self.e3()
if self.accept('or'):
- self.e3()
+ return OrNode(left.lineno, left.colno, left, self.e3())
return left
def e3(self):
left = self.e4()
if self.accept('and'):
- self.e4()
+ return AndNode(left.lineno, left.colno, left, self.e4())
return left
def e4(self):
left = self.e5()
if self.accept('equal'):
- self.e5()
+ return EqualNode(left.lineno, left.colno, left, self.e5())
+ if self.accept('nequal'):
+ return NEqualNode(left.lineno, left.colno, left, self.e5())
return left
def e5(self):
if self.accept('not'):
- pass
+ return NotNode(self.current.lineno, self.current.colno, self.e6())
return self.e6()
def e6(self):
@@ -294,6 +344,10 @@ class Parser:
elif self.accept('lparen'):
args = self.args()
self.expect('rparen')
+ if not isinstance(left, IdNode):
+ raise ParseException('Function call must be applied to plain id',
+ left.lineno, left.colno)
+ return FunctionNode(left.lineno, left.colno, left.value, args)
return left
def e7(self):
@@ -321,7 +375,7 @@ class Parser:
def args(self):
s = self.statement()
if isinstance(s, EmptyNode):
- ArgumentNode(self.current.lineno, self.current.colno)
+ ArgumentNode(s)
if self.accept('comma'):
rest = self.args()
@@ -351,26 +405,34 @@ class Parser:
self.expect('rparen')
return MethodNode(methodname.lineno, methodname.colno, source_object, methodname.value, args)
- def ifelseblock(self):
+ def ifblock(self):
+ condition = self.statement()
+ clause = IfClauseNode(condition.lineno, condition.colno)
+ block = self.codeblock()
+ clause.ifs.append(IfNode(clause.lineno, clause.colno, condition, block))
+ self.elseifblock(clause)
+ clause.elseblock = self.elseblock()
+ return clause
+
+ def elseifblock(self, clause):
while self.accept('elif'):
- self.statement()
+ s = self.statement()
self.expect('eol')
- self.codeblock()
+ b = self.codeblock()
+ clause.ifs.append(IfNode(s.lineno, s.colno, s, b))
def elseblock(self):
if self.accept('else'):
self.expect('eol')
- self.codeblock()
+ return self.codeblock()
def line(self):
+ if self.current == 'eol':
+ return EmptyNode()
if self.accept('if'):
- self.statement()
- self.codeblock()
- self.ifelseblock()
- self.elseblock()
+ block = self.ifblock()
self.expect('endif')
- if self.current == 'eol':
- return
+ return block
return self.statement()
def codeblock(self):
@@ -381,8 +443,6 @@ class Parser:
if not isinstance(curline, EmptyNode):
block.lines.append(curline)
cond = self.accept('eol')
- if self.current == 'elif' or self.current == 'else':
- cond = False
return block
if __name__ == '__main__':