From 48d72383fdd0283c75c11948c5e1346331e1fcb0 Mon Sep 17 00:00:00 2001 From: Nemo Date: Mon, 6 Jul 2020 16:27:19 +0530 Subject: [PATCH] Implement all grammar classes --- compiler/engine.py | 80 ++++++++++++++++++++++++++++++++++++++++++++- compiler/grammar.py | 21 +++++------- 2 files changed, 87 insertions(+), 14 deletions(-) diff --git a/compiler/engine.py b/compiler/engine.py index 0b74b34..72b79fd 100644 --- a/compiler/engine.py +++ b/compiler/engine.py @@ -9,7 +9,7 @@ class Engine: def __init__(self, input_file): self.i = 0 self.jt = JackTokenizer(input_file, False) - self.file = open(input_file + ".xml", 'w') + self.file = open(self.xml_file()) def xml_file(self, input_file): return input_file + ".xml" @@ -19,3 +19,81 @@ class Engine: token = self.jt.tokenType() return Atom(token.value) + def compileClass(self): + self.compile(grammar.CLASS) + + def advance(self): + self.jt.advance() + + def ZeroOrMany(self, grammarList): + if compile(grammarList[0]): + # We now expect the whole of it + for e in grammarList: + self.compile(e) + # We try for another list after this + return self.ZeroOrMany(grammarList) + else: + return None + + def write(self, line): + print(line) + + def MatchDict(self, dictionary): + xml_rows_for_lookup_terms = [] + lookup_keys = () + # How much to lookahead + lookahead = len(list(dict.keys())[0]) + for _ in range(lookahead): + xml_rows_for_lookup_terms += [self.jt.xml_row()] + lookup_keys = lookup_keys + (self.atom(),) + self.advance() + + for line in xml_rows_for_lookup_terms: + self.write(line) + + for e in dict[lookup_keys]: + self.compile(e) + + def ZeroOrOne(self, grammarTuple): + if self.compile(grammarTuple[0]): + for e in grammarTuple: + self.compile(e) + return True + else: + return None + + """ Has to MATCH """ + def Atom(self, atom): + expected = atom + current = self.atom() + # We use in here to accomodate for bitmasks + if current in expected: + print(current) + self.advance() + else: + raise Exception("Expected %s, got %s" % (expected, current)) + + def compile(self, thing): + # TODO: OPEN TAGS + if isinstance(thing, Element): + print("open %s" % thing.name) + grammar = thing.grammar + elif callable(thing): + grammar = thing() + else: + grammar = thing + grammarType = type(grammar) + + elif grammarType == list: + return self.ZeroOrMany(thing) + elif grammarType == dict: + return self.MatchDict(thing) + elif grammarType == tuple: + return self.ZeroOrOne(thing) + elif grammarType == Atom: + return self.Atom(thing) + elif callable(thing): + return self.compile(thing) + + if isinstance(thing, Element): + print("close %s" % thing.name) diff --git a/compiler/grammar.py b/compiler/grammar.py index 5fb0405..9211119 100644 --- a/compiler/grammar.py +++ b/compiler/grammar.py @@ -18,12 +18,11 @@ a Python structure. """ class Element: - def __init__(self, name, grammar, terminal = False): + def __init__(self, name, grammar): self.name = name self.grammar = grammar - self.terminal = terminal -TYPES = Element('type', Atom.INT | Atom.CHAR | Atom.BOOLEAN | Atom.IDENTIFIER, True) +TYPES = Element('type', Atom.INT | Atom.CHAR | Atom.BOOLEAN | Atom.IDENTIFIER) CLASSVARDEC = Element('classVarDec', [ # static|field type (, name)* ; @@ -37,13 +36,13 @@ VARDEC = Element('varDec', [Atom.VAR, TYPES, Atom.IDENTIFIER, [Atom.COMMA, Atom.IDENTIFIER], Atom.SEMICOLON ]) -UNARY_OP = Element('unaryOp', Atom.NOT | Atom.MINUS, True) +UNARY_OP = Element('unaryOp', Atom.NOT | Atom.MINUS) -CONSTANT = Element('KeywordConstant', Atom.TRUE | Atom.FALSE|Atom.NULL|Atom.THIS, True) +CONSTANT = Element('KeywordConstant', Atom.TRUE | Atom.FALSE|Atom.NULL|Atom.THIS) TERM = Element('term', Atom.INTEGERCONSTANT | Atom.STRINGCONSTANT | Atom.TRUE | Atom.FALSE | Atom.IDENTIFIER) -OP = Element('op', Atom.PLUS | Atom.MINUS | Atom.MUL | Atom.DIV | Atom.AND | Atom.OR | Atom.GT | Atom.LT | Atom.EQ, True) +OP = Element('op', Atom.PLUS | Atom.MINUS | Atom.MUL | Atom.DIV | Atom.AND | Atom.OR | Atom.GT | Atom.LT | Atom.EQ) EXPRESSION = Element('expression', [TERM, [OP, TERM]]) @@ -118,21 +117,17 @@ SUBROUTINEDEC = Element('subroutineDec', [ Atom.PARAN_OPEN, PARAMETER_LIST, Atom.PARAN_CLOSE, - # Subroutine Body { + # Subroutine Body Atom.BRACE_OPEN, SUBROUTINE_BODY, Atom.BRACE_CLOSE, ]) CLASS = Element('class', [ - # class className { Atom.CLASS, Atom.IDENTIFIER, Atom.BRACE_OPEN, - # class Variable Declarations (one or more) = list - CLASSVARDEC, - # subroutine declarations (one or more) = list - SUBROUTINEDEC, - # } + [CLASSVARDEC], + [SUBROUTINEDEC], Atom.BRACE_CLOSE ])