summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorBenedikt Böhm <bb@xnull.de>2009-05-21 18:21:20 +0200
committerBenedikt Böhm <bb@xnull.de>2009-05-21 18:21:20 +0200
commit028a685f7c19dee1af0482cf5ed142e751d36a62 (patch)
tree3b857f3ae599175e2ad9726b2e1e340501473582 /src
parentccdf1686129f73765cf9b771c04f4676e0ad22bd (diff)
downloadswppy-028a685f7c19dee1af0482cf5ed142e751d36a62.tar.gz
swppy-028a685f7c19dee1af0482cf5ed142e751d36a62.tar.xz
swppy-028a685f7c19dee1af0482cf5ed142e751d36a62.zip
implement AST interfaces, which also superseeds parser tokens
Diffstat (limited to 'src')
-rw-r--r--src/front/ast.py87
-rw-r--r--src/front/lexer.py36
-rw-r--r--src/front/token.py47
3 files changed, 111 insertions, 59 deletions
diff --git a/src/front/ast.py b/src/front/ast.py
new file mode 100644
index 0000000..26cda51
--- /dev/null
+++ b/src/front/ast.py
@@ -0,0 +1,87 @@
+class Node(object):
+ pass
+
+class Program(Node):
+ def __init__(self, functions, lineno = None):
+ self.functions = functions
+ self.lineno = lineno
+
+class Function(Node):
+ def __init__(self, name, params, statements, lineno = None):
+ self.name = name
+ self.params = params
+ self.statements = statements
+ self.lineno = lineno
+
+ def __repr__(self):
+ return "<Function: %s at line %d>" % (name, lineno)
+
+class Statement(Node):
+ pass
+
+class IfStatement(Statement):
+ def __init__(self, expression, true_statements, false_statements, lineno = None):
+ self.expression = expression
+ self.true_statements = true_statements
+ self.false_statements = false_statements
+ self.lineno = lineno
+
+ def __repr__(self):
+ return "<IfStatement at line %d>" % lineno
+
+class WhileStatement(Statement):
+ def __init__(self, expression, statements, lineno = None):
+ self.expression = expression
+ self.statements = statements
+ self.lineno = lineno
+
+ def __repr__(self):
+ return "<WhileStatement at line %d>" % lineno
+
+class ReturnStatement(Statement):
+ def __init__(self, expression, lineno = None):
+ self.expression = expression
+ self.lineno = lineno
+
+ def __repr__(self):
+ return "<ReturnStatement at line %d>" % lineno
+
+class AssignStatement(Statement):
+ def __init__(self, ident, expression, lineno = None):
+ self.ident = ident
+ self.expression = expression
+ self.lineno = lineno
+
+ def __repr__(self):
+ return "<AssignStatement for %s at line %d>" % (ident, lineno)
+
+class FunctionCall(Statement):
+ def __init__(self, ident, arguments, lineno = None):
+ self.ident = ident
+ self.arguments = arguments
+ self.lineno = lineno
+
+ def __repr__(self):
+ return "<FunctionCall for %s at line %d>" % (ident, lineno)
+
+class Expression(Node):
+ pass
+
+class UnaryExpression(Expression):
+ def __init__(self, op, right, lineno = None):
+ self.op = op
+ self.right = right
+ self.lineno = lineno
+
+ def __repr__(self):
+ return "<UnaryExpression: %s(%s) at line %d>" % (op, right, lineno)
+
+class BinaryExpression(Expression):
+ def __init__(self, left, op, right, lineno = None):
+ self.left = left
+ self.op = op
+ self.right = right
+ self.lineno = lineno
+
+ def __repr__(self):
+ return "<BinaryExpression: %s(%s, %s) at line %d>" % (op, left, right, lineno)
diff --git a/src/front/lexer.py b/src/front/lexer.py
index 5605fe3..ff67e6d 100644
--- a/src/front/lexer.py
+++ b/src/front/lexer.py
@@ -11,18 +11,18 @@ class Lexer:
self.currentLine = ''
# reservierte Wörter initialisieren
- self.reservedWords = {'True': LeafToken(Tag.TRUE),
- 'False': LeafToken(Tag.FALSE),
- '[': LeafToken(Tag.LBRAK),
- ']': LeafToken(Tag.RBRAK),
- '(': LeafToken(Tag.LPAREN),
- ')': LeafToken(Tag.RPAREN),
- ',': LeafToken(Tag.COMMA),
- 'while': LeafToken(Tag.WHILE),
- 'if': LeafToken(Tag.IF),
- 'else': LeafToken(Tag.ELSE),
- 'fun': LeafToken(Tag.FUN),
- 'end': LeafToken(Tag.END)}
+ self.reservedWords = {'True': Token(Tag.BOOL, True),
+ 'False': Token(Tag.BOOL, False),
+ '[': Token(Tag.LBRAK),
+ ']': Token(Tag.RBRAK),
+ '(': Token(Tag.LPAREN),
+ ')': Token(Tag.RPAREN),
+ ',': Token(Tag.COMMA),
+ 'while': Token(Tag.WHILE),
+ 'if': Token(Tag.IF),
+ 'else': Token(Tag.ELSE),
+ 'fun': Token(Tag.FUN),
+ 'end': Token(Tag.END)}
return
def reserve(self, word, token):
@@ -43,7 +43,7 @@ class Lexer:
# newline zurückgeben
if self.doubleNewlineCheck:
self.doubleNewlineCheck = False
- return LeafToken(Tag.NEWLINE)
+ return Token(Tag.NEWLINE)
# leerzeichen entfernen
self.currentLine = self.currentLine.strip()
@@ -59,7 +59,7 @@ class Lexer:
# Token parsen
if self.currentLine.startswith('@'):
self.currentLine = self.currentLine[1:]
- return LeafToken(Tag.RETURN)
+ return Token(Tag.RETURN)
# reservierte Wörter (da stehen auch schon erkannte Identifyer drine)
for reservedWord, token in self.reservedWords.iteritems():
@@ -74,26 +74,26 @@ class Lexer:
match = re.match(r"^([0-9]+)", self.currentLine)
if match:
self.currentLine = self.currentLine[match.end(0):]
- return LeafToken(Tag.NUMBER, int(match.group(0)))
+ return Token(Tag.NUMBER, int(match.group(0)))
# operatoren matchen
match = re.match(r"^(<=|==|>=|&&|\|\||<|>|\+|-|\*|/)", self.currentLine)
if match:
self.currentLine = self.currentLine[match.end(0):]
- return LeafToken(Tag.OPERATOR, match.group(0))
+ return Token(Tag.OPERATOR, match.group(0))
# idents matchen
match = re.match(r"^([a-zA-Z][a-zA-Z0-9]*)", self.currentLine)
if match:
self.currentLine = self.currentLine[match.end(0):]
- token = LeafToken(Tag.IDENT, match.group(0))
+ token = Token(Tag.IDENT, match.group(0))
self.reserve(match.group(0), token)
return token
# assignments
if self.currentLine.startswith('='):
self.currentLine = self.currentLine[1:]
- return LeafToken(Tag.ASSIGNMENT)
+ return Token(Tag.ASSIGNMENT)
# wenn die programmausführung hier ist,
# ist ein syntaxfehler aufgetreten
diff --git a/src/front/token.py b/src/front/token.py
index 31159bf..e1bc8d8 100644
--- a/src/front/token.py
+++ b/src/front/token.py
@@ -1,5 +1,4 @@
# -*- coding: utf-8 -*-
-# date: 20 Mai 2009
class Tag(object):
__slots__ = ["name"]
@@ -13,10 +12,9 @@ class Tag(object):
def __repr__(self):
return "<Tag: %s>" % self
-# lexer tokens
+# token tags
Tag.NUMBER = Tag("NUMBER")
-Tag.TRUE = Tag("TRUE")
-Tag.FALSE = Tag("FALSE")
+Tag.BOOL = Tag("BOOL")
Tag.IDENT = Tag("IDENT")
Tag.WHILE = Tag("WHILE")
Tag.IF = Tag("IF")
@@ -33,47 +31,14 @@ Tag.ASSIGNMENT = Tag("ASSIGNMENT")
Tag.RETURN = Tag("RETURN")
Tag.OPERATOR = Tag("OPERATOR")
-# parser tokens
-Tag.BOOL = Tag("BOOL")
-Tag.JOIN = Tag("JOIN")
-Tag.EQUALITY = Tag("EQUALITY")
-Tag.RELATION = Tag("RELATION")
-Tag.EXPRESSION = Tag("EXPRESSION")
-Tag.TERM = Tag("TERM")
-Tag.UNARY = Tag("UNARY")
-Tag.FACTOR = Tag("FACTOR")
-Tag.IDENT = Tag("IDENT")
-Tag.EXPRESSION = Tag("EXPRESSION")
-Tag.PROGRAM = Tag("PROGRAM")
-Tag.FUNCTION = Tag("FUNCTION")
-Tag.STATEMENT = Tag("STATEMENT")
-Tag.STATEMENTS = Tag("STATEMENTS")
-Tag.IF = Tag("IF")
-Tag.WHILE = Tag("WHILE")
-Tag.RETURN = Tag("RETURN")
-Tag.ASSIGN = Tag("ASSIGN")
-Tag.FUNCTION = Tag("FUNCTION")
-
class Token(object):
- __slots__ = ["tag"]
-
- def __init__(self, tag):
- self.tag = tag
-
- def __repr__(self):
- return "<Token: %s>" % self.tag
-
-class LeafToken(Token):
- __slots__ = ["value"]
+ __slots__ = ["tag","value"]
def __init__(self, tag, value = None):
- Token.__init__(self, tag)
+ self.tag = tag
self.value = value
def __repr__(self):
if self.value:
- return "<LeafToken: %s, Value: %s>" % (self.tag, self.value.__str__())
- return "<LeafToken: %s>" % self.tag
-
-class NodeToken(Token):
- pass
+ return "<Token: %s, Value: %s>" % (self.tag, str(self.value))
+ return "<Token: %s>" % self.tag