mine curses
This commit is contained in:
parent
10be440641
commit
11c8e63d8c
1 changed files with 57 additions and 14 deletions
71
gerlang.py
71
gerlang.py
|
@ -30,11 +30,17 @@ class StringAnalyzer(Analyzer):
|
||||||
|
|
||||||
class TokenListAnalyzer(Analyzer):
|
class TokenListAnalyzer(Analyzer):
|
||||||
def takeUntilType(self,end):
|
def takeUntilType(self,end):
|
||||||
|
return self.takeUntil(lambda t: t[0] == end)
|
||||||
|
|
||||||
|
def takeUntil(self,condition, dropEnd=True):
|
||||||
t = []
|
t = []
|
||||||
while self.next() is not None and self.next()[0] != end:
|
while self.next() is not None and not condition(self.next()):
|
||||||
t.append( self.take() )
|
t.append( self.take() )
|
||||||
|
if dropEnd and self.next() is not None:
|
||||||
|
self.take()
|
||||||
return t
|
return t
|
||||||
|
|
||||||
|
|
||||||
class Lexer:
|
class Lexer:
|
||||||
keywords = ["setze","auf","durch","schreibe"]
|
keywords = ["setze","auf","durch","schreibe"]
|
||||||
operators = ["plus","minus","mal","geteilt"]
|
operators = ["plus","minus","mal","geteilt"]
|
||||||
|
@ -51,6 +57,7 @@ class Lexer:
|
||||||
tokens = []
|
tokens = []
|
||||||
sa = StringAnalyzer(source)
|
sa = StringAnalyzer(source)
|
||||||
braces = 0
|
braces = 0
|
||||||
|
stack = 0
|
||||||
while len(sa) != 0:
|
while len(sa) != 0:
|
||||||
if sa.between('a', 'z') or sa.between('A', 'Z'): #identifier or keyword
|
if sa.between('a', 'z') or sa.between('A', 'Z'): #identifier or keyword
|
||||||
ident = ""
|
ident = ""
|
||||||
|
@ -60,6 +67,12 @@ class Lexer:
|
||||||
tokens.append( (self.KEYWORD,ident.lower()) )
|
tokens.append( (self.KEYWORD,ident.lower()) )
|
||||||
elif ident.lower() in self.operators:
|
elif ident.lower() in self.operators:
|
||||||
tokens.append( (self.OP,ident.lower()) )
|
tokens.append( (self.OP,ident.lower()) )
|
||||||
|
elif ident.lower() == "wenn":
|
||||||
|
tokens.append( ( self.KEYWORD, "wenn", stack ) )
|
||||||
|
stack += 1
|
||||||
|
elif ident.lower() == "ende":
|
||||||
|
stack -= 1
|
||||||
|
tokens.append( ( self.KEYWORD, "ende", stack ) )
|
||||||
else:
|
else:
|
||||||
tokens.append( (self.IDENT,ident) )
|
tokens.append( (self.IDENT,ident) )
|
||||||
elif sa.between('0', '9'): #number
|
elif sa.between('0', '9'): #number
|
||||||
|
@ -108,25 +121,34 @@ class Parser:
|
||||||
if ta.next()[0] != Lexer.KEYWORD or ta.next()[1] != "auf":
|
if ta.next()[0] != Lexer.KEYWORD or ta.next()[1] != "auf":
|
||||||
raise ParserException("missing auf after identifier")
|
raise ParserException("missing auf after identifier")
|
||||||
ta.take()
|
ta.take()
|
||||||
term = self.__parseTerm(ta.takeUntilType(Lexer.NEWLINE))
|
term = self.__parseTerm(ta.takeUntil(lambda t: t[0] == Lexer.NEWLINE))
|
||||||
ta.take()
|
|
||||||
block.append(AssignmentTerm(ident,term))
|
block.append(AssignmentTerm(ident,term))
|
||||||
elif ta.next()[1] == "schreibe":
|
elif ta.next()[1] == "schreibe":
|
||||||
ta.take()
|
ta.take()
|
||||||
term = self.__parseTerm(ta.takeUntilType(Lexer.NEWLINE))
|
term = self.__parseTerm(ta.takeUntilType(Lexer.NEWLINE))
|
||||||
block.append(PrintTerm(term))
|
block.append(PrintTerm(term))
|
||||||
|
elif ta.next()[1] == "wenn":
|
||||||
|
stack = ta.next()[2]
|
||||||
|
ta.take()
|
||||||
|
condition = ta.takeUntil(lambda t: t[0] == Lexer.NEWLINE)
|
||||||
|
b = ta.takeUntil(lambda t: t[0] == Lexer.KEYWORD and t[1] == "ende" and t[2] == stack)
|
||||||
|
block.append( ConditionalTerm(self.__parseTerm(condition), self.parse(b) ) )
|
||||||
|
else:
|
||||||
|
raise Exception("what? %s" % str(ta.next()))
|
||||||
elif ta.next()[0] == Lexer.NEWLINE:
|
elif ta.next()[0] == Lexer.NEWLINE:
|
||||||
ta.take()
|
ta.take()
|
||||||
|
else:
|
||||||
|
raise Exception("huh? %s" % str(ta.next()))
|
||||||
return block
|
return block
|
||||||
|
|
||||||
def __parseTerm(self,tokens):
|
def __parseTerm(self,tokens):
|
||||||
t = tokens[0]
|
t = tokens[0]
|
||||||
if t[0] == Lexer.IDENT:
|
if t[0] == Lexer.INT or t[0] == Lexer.FLOAT:
|
||||||
return IdentifierTerm(t[1])
|
|
||||||
elif t[0] == Lexer.INT or t[0] == Lexer.FLOAT:
|
|
||||||
return ValueTerm(t[1])
|
return ValueTerm(t[1])
|
||||||
|
elif t[0] == Lexer.IDENT:
|
||||||
|
return IdentifierTerm(t[1])
|
||||||
else:
|
else:
|
||||||
raise ParseException("Unexpected token %s" % t)
|
return ValueTerm(0)
|
||||||
|
|
||||||
class Context():
|
class Context():
|
||||||
pass
|
pass
|
||||||
|
@ -134,10 +156,23 @@ class Context():
|
||||||
class SubContext(Context):
|
class SubContext(Context):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
class Term:
|
class Term(object):
|
||||||
def run(self,context):
|
def run(self,context):
|
||||||
raise Exception("get_value must be overwritten")
|
raise Exception("get_value must be overwritten")
|
||||||
|
|
||||||
|
class Operator2(Term):
|
||||||
|
token = None
|
||||||
|
priority = 0
|
||||||
|
def __init__(self, left, right):
|
||||||
|
self.left = left
|
||||||
|
self.right = right
|
||||||
|
|
||||||
|
def run(self,context):
|
||||||
|
return self.calc( self.left.run(context), self.right.run(context) )
|
||||||
|
|
||||||
|
def calc(self, r, l):
|
||||||
|
raise Exception("calc not implemented")
|
||||||
|
|
||||||
class IdentifierTerm:
|
class IdentifierTerm:
|
||||||
def __init__(self, ident):
|
def __init__(self, ident):
|
||||||
self.ident = ident
|
self.ident = ident
|
||||||
|
@ -169,6 +204,17 @@ class PrintTerm(Term):
|
||||||
print self.term.run(context)
|
print self.term.run(context)
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
class ConditionalTerm(Term):
|
||||||
|
def __init__(self,condition,block):
|
||||||
|
self.condition = condition
|
||||||
|
self.block = block
|
||||||
|
|
||||||
|
def run(self,context):
|
||||||
|
m = self.condition.run(context)
|
||||||
|
if m != 0:
|
||||||
|
self.block.run(context)
|
||||||
|
|
||||||
|
|
||||||
class BlockTerm(Term):
|
class BlockTerm(Term):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.terms = []
|
self.terms = []
|
||||||
|
@ -186,12 +232,9 @@ def main():
|
||||||
context = {}
|
context = {}
|
||||||
while True:
|
while True:
|
||||||
code = raw_input(">>> ")
|
code = raw_input(">>> ")
|
||||||
try:
|
tokens = Lexer().lex(code)
|
||||||
tokens = Lexer().lex(code)
|
term = Parser().parse(tokens)
|
||||||
term = Parser().parse(tokens)
|
term.run(context)
|
||||||
term.run(context)
|
|
||||||
except Exception, e:
|
|
||||||
print e
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
main()
|
main()
|
Loading…
Reference in a new issue