From 028a685f7c19dee1af0482cf5ed142e751d36a62 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benedikt=20B=C3=B6hm?= Date: Thu, 21 May 2009 18:21:20 +0200 Subject: implement AST interfaces, which also superseeds parser tokens --- src/front/ast.py | 87 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/front/lexer.py | 36 +++++++++++----------- src/front/token.py | 47 ++++------------------------- 3 files changed, 111 insertions(+), 59 deletions(-) create mode 100644 src/front/ast.py (limited to 'src') 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 "" % (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 "" % lineno + +class WhileStatement(Statement): + def __init__(self, expression, statements, lineno = None): + self.expression = expression + self.statements = statements + self.lineno = lineno + + def __repr__(self): + return "" % lineno + +class ReturnStatement(Statement): + def __init__(self, expression, lineno = None): + self.expression = expression + self.lineno = lineno + + def __repr__(self): + return "" % lineno + +class AssignStatement(Statement): + def __init__(self, ident, expression, lineno = None): + self.ident = ident + self.expression = expression + self.lineno = lineno + + def __repr__(self): + return "" % (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 "" % (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 "" % (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 "" % (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 "" % 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 "" % 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 "" % (self.tag, self.value.__str__()) - return "" % self.tag - -class NodeToken(Token): - pass + return "" % (self.tag, str(self.value)) + return "" % self.tag -- cgit v1.2.3