summaryrefslogtreecommitdiffstats
path: root/src/front/parser.py
diff options
context:
space:
mode:
Diffstat (limited to 'src/front/parser.py')
-rw-r--r--src/front/parser.py59
1 files changed, 29 insertions, 30 deletions
diff --git a/src/front/parser.py b/src/front/parser.py
index 610a5bb..511e929 100644
--- a/src/front/parser.py
+++ b/src/front/parser.py
@@ -1,37 +1,41 @@
# -*- coding: utf-8 -*-
from ast import *
-from lexer import *
-from token import *
+from token import Tag
+from scope import Scope
+
+class ParseError(Exception):
+ pass
class Parser:
- def __init__(self, lex):
- self.lexer = lex
- self.token = lex.scan()
- self.count = 1 #debug
- return
+ def __init__(self, lexer):
+ self.lexer = lexer
+ self.scope = Scope()
+ self.move()
def parse(self):
return self.program()
def move(self):
- print self.count, self.token #debug
- self.count += 1 #debug
self.token = self.lexer.scan()
- return
+ #print "move(): %s" % self.token
def error(self, msg):
- raise Exception(msg)
+ raise ParseError(msg)
- def match(self, tag):
+ def _match(self, tag):
if self.token == None:
self.error("Unexpected end of file.")
-
if self.token.tag != tag:
self.error("match: expected %s got %s\n" %(tag, self.token.tag))
val = self.token.value
self.move()
return val
+ def match(self, tag, *tags):
+ for t in (tag,) + tags:
+ res = self._match(t)
+ return res
+
# boolean = join { "||" join }.
def boolean(self):
res = self.join()
@@ -94,8 +98,7 @@ class Parser:
# function_call = "call" ident "[" [ expression_list ] "]".
def function_call(self):
- self.match(Tag.CALL)
- name = self.match(Tag.IDENT)
+ name = self.match(Tag.CALL, Tag.IDENT)
self.match(Tag.LBRAK)
args = [] if self.token.tag == Tag.RBRAK else self.expression_list()
self.match(Tag.RBRAK)
@@ -126,23 +129,20 @@ class Parser:
# statement_list = statement { statement }.
def statement_list(self):
- stat = [self.statement()]
- while self.token.tag not in [Tag.END, Tag.ELSE]:
- stat.append(self.statement())
- return stat
+ if self.token.tag in [Tag.END, Tag.ELSE]:
+ return None
+ return Sequence(self.statement(), self.statement_list(), self.lexer.line)
# function = "fun" ident "[" [ ident_list ] "]" nl statement_list "end" nl.
def function(self):
line = self.lexer.line
- self.match(Tag.FUN)
- name = self.match(Tag.IDENT)
+ name = self.match(Tag.FUN, Tag.IDENT)
self.match(Tag.LBRAK)
args = [] if self.token.tag == Tag.RBRAK else self.ident_list()
- self.match(Tag.RBRAK)
- self.match(Tag.NEWLINE)
+ self.match(Tag.RBRAK, Tag.NEWLINE)
+ self.scope.new(name, args)
block = self.statement_list()
- self.match(Tag.END)
- self.match(Tag.NEWLINE)
+ self.match(Tag.END, Tag.NEWLINE)
return Function(name, args, block, line)
# statement = [ if_statement | while_statement | assign_statement | return_statement | function_call ].
@@ -161,13 +161,12 @@ class Parser:
condition = self.boolean()
self.match(Tag.NEWLINE)
true_case = self.statement_list()
- else_case = []
+ else_case = None
if self.token.tag == Tag.ELSE:
self.move()
self.match(Tag.NEWLINE)
else_case = self.statement_list()
- self.match(Tag.END)
- self.match(Tag.NEWLINE)
+ self.match(Tag.END, Tag.NEWLINE)
return IfStatement(condition, true_case, else_case, line)
# while_statement = "while" boolean nl statement_list "end" nl.
@@ -177,8 +176,7 @@ class Parser:
condition = self.boolean()
self.match(Tag.NEWLINE)
body = self.statement_list()
- self.match(Tag.END)
- self.match(Tag.NEWLINE)
+ self.match(Tag.END, Tag.NEWLINE)
return WhileStatement(condition, body, line)
# return_statement = "@" boolean nl.
@@ -196,6 +194,7 @@ class Parser:
self.match(Tag.ASSIGNMENT)
exp = self.boolean()
self.match(Tag.NEWLINE)
+ self.scope.add(name)
return AssignStatement(name, exp, line)
# program = function_list.