WIP at enginev2

This commit is contained in:
Nemo 2020-07-06 14:36:41 +05:30
parent 333484ce7f
commit deeebda14d
4 changed files with 105 additions and 67 deletions

View File

@ -62,11 +62,8 @@ class CompilationEngine:
self.close('classVarDec') self.close('classVarDec')
self.advance() self.advance()
""" Writes a single line(with \n) on the XML, taking into account the indentation """ """ Writes a single line(with \n) on the XML, taking into account the indentation """
def write(self, klass, subklass = None): def write(self, klass, subklass = None):
print(self.type())
print(klass)
assert(klass == self.type()) assert(klass == self.type())
if (klass == Token.SYMBOL): if (klass == Token.SYMBOL):
assert(subklass == self.s()) assert(subklass == self.s())
@ -94,7 +91,7 @@ class CompilationEngine:
self.write(T) self.write(T)
self.advance() self.advance()
def CompuleSubroutine(self): def CompileSubroutine(self):
self.open('subroutineDec') self.open('subroutineDec')
self.write() self.write()
pass pass

View File

@ -1,4 +1,6 @@
from tokenizer import JackTokenizer from tokenizer import JackTokenizer
from keywords import *
from grammar import CLASS
""" """
New Compilation Engine New Compilation Engine
@ -8,3 +10,6 @@ class Engine:
self.i = 0 self.i = 0
self.jt = JackTokenizer(input_file, False) self.jt = JackTokenizer(input_file, False)
self.file = open(input_file + ".xml", 'w') self.file = open(input_file + ".xml", 'w')
def xml_file(self, input_file):
return input_file + ".xml"

View File

@ -1,67 +1,5 @@
from keywords import Keyword from keywords import Keyword
class Element:
def __init__(name, grammar, terminal = False):
self.name = name
self.grammar = grammar
self.terminal = terminal
CLASS = Element('class', [
# class className {
Keyword.CLASS,
Keyword.IDENTIFIER,
Keyword.BRACE_OPEN,
# class Variable Declarations (one or more) = list
CLASSVARDEC,
# subroutine declarations (one or more) = list
SUBROUTINEDEC,
# }
Keyword.BRACE_CLOSE
])
CLASSVARDEC = Element('classVarDec', [
# static|field type (, name)* ;
Keyword.STATIC | Keyword.FIELD,
TYPE,
[Keyword.COMMA, Keyword.IDENTIFIER],
Keyword.SEMICOLON
])
# Parameter List =
# (
# (type varName) (, type varName)*
# )?
# we use tuples for zero OR one of a sequence
PARAMETER_LIST = Element('parameterList', (
TYPE,
Keyword.IDENTIFIER,
[Keyword.COMMA, TYPE, Keyword.IDENTIFIER]
))
TYPE = Element('type', Keyword.INT | Keyword.CHAR | Keyword.BOOLEAN | Keyword.IDENTIFIER, True)
SUBROUTINE_BODY = Element('subroutineBody', [
# One or more variable declarations
# `var type varName (, varName)* ;`
[VARDEC],
STATEMENTS
])
SUBROUTINEDEC = Element('subroutineDec', [
# (constructor | function | method) (void | type) subRoutineName '(' parameterList ')'
# subroutineBody
Keyword.CONSTRUCTOR | Keyword.FUNCTION | Keyword.METHOD,
Keyword.VOID | TYPE,
Keyword.IDENTIFIER,
Keyword.PARAN_OPEN,
PARAMETER_LIST,
Keyword.PARAN_CLOSE,
# Subroutine Body {
Keyword.BRACE_OPEN,
SUBROUTINE_BODY,
Keyword.BRACE_CLOSE,
])
""" """
The grammar is defined by the following constructs: The grammar is defined by the following constructs:
@ -79,10 +17,29 @@ This is basically an attempt to translate Figure 10.5 from the book into
a Python structure. a Python structure.
""" """
class Element:
def __init__(self, name, grammar, terminal = False):
self.name = name
self.grammar = grammar
self.terminal = terminal
TYPES = Element('type', Keyword.INT | Keyword.CHAR | Keyword.BOOLEAN | Keyword.IDENTIFIER, True)
CLASSVARDEC = Element('classVarDec', [
# static|field type (, name)* ;
Keyword.STATIC | Keyword.FIELD,
TYPES,
[Keyword.COMMA, Keyword.IDENTIFIER],
Keyword.SEMICOLON
])
VARDEC = Element('varDec', [Keyword.VAR, TYPES, Keyword.IDENTIFIER,
[Keyword.COMMA, Keyword.IDENTIFIER],
Keyword.SEMICOLON
])
UNARY_OP = Element('unaryOp', Keyword.NOT | Keyword.MINUS, True) UNARY_OP = Element('unaryOp', Keyword.NOT | Keyword.MINUS, True)
CONSTANT = Element('KeywordConstant', Keyword.TRUE | Keyword.FALSE, Keyword.NULL, Keyword.THIS, True) CONSTANT = Element('KeywordConstant', Keyword.TRUE | Keyword.FALSE|Keyword.NULL|Keyword.THIS, True)
TERM = Element('term', Keyword.INTEGERCONSTANT | Keyword.STRINGCONSTANT | Keyword.TRUE | Keyword.FALSE | Keyword.IDENTIFIER) TERM = Element('term', Keyword.INTEGERCONSTANT | Keyword.STRINGCONSTANT | Keyword.TRUE | Keyword.FALSE | Keyword.IDENTIFIER)
@ -114,6 +71,7 @@ STATEMENT = Element('statement', {
Keyword.BRACE_OPEN, Keyword.BRACE_OPEN,
lambda: STATEMENTS, lambda: STATEMENTS,
Keyword.BRACE_CLOSE, Keyword.BRACE_CLOSE,
# This is the tricky one
( Keyword.ELSE, Keyword.BRACE_OPEN, lambda:STATEMENT, Keyword.BRACE_CLOSE) ( Keyword.ELSE, Keyword.BRACE_OPEN, lambda:STATEMENT, Keyword.BRACE_CLOSE)
], ],
(Keyword.WHILE): [ (Keyword.WHILE): [
@ -129,3 +87,52 @@ STATEMENT = Element('statement', {
}) })
STATEMENTS = Element('statements', [STATEMENT]) STATEMENTS = Element('statements', [STATEMENT])
SUBROUTINE_BODY = Element('subroutineBody', [
# One or more variable declarations
# `var type varName (, varName)* ;`
[VARDEC],
STATEMENTS
])
""" Pseudo-element to help define subroutine declarations """
RETURN_TYPES= Keyword.INT | Keyword.CHAR|Keyword.BOOLEAN|Keyword.IDENTIFIER|Keyword.VOID
# Parameter List =
# (
# (type varName) (, type varName)*
# )?
# we use tuples for zero OR one of a sequence
PARAMETER_LIST = Element('parameterList', (
TYPES,
Keyword.IDENTIFIER,
[Keyword.COMMA, TYPES, Keyword.IDENTIFIER]
))
SUBROUTINEDEC = Element('subroutineDec', [
# (constructor | function | method) (void | type) subRoutineName '(' parameterList ')'
# subroutineBody
Keyword.CONSTRUCTOR | Keyword.FUNCTION | Keyword.METHOD,
RETURN_TYPES,
Keyword.IDENTIFIER,
Keyword.PARAN_OPEN,
PARAMETER_LIST,
Keyword.PARAN_CLOSE,
# Subroutine Body {
Keyword.BRACE_OPEN,
SUBROUTINE_BODY,
Keyword.BRACE_CLOSE,
])
CLASS = Element('class', [
# class className {
Keyword.CLASS,
Keyword.IDENTIFIER,
Keyword.BRACE_OPEN,
# class Variable Declarations (one or more) = list
CLASSVARDEC,
# subroutine declarations (one or more) = list
SUBROUTINEDEC,
# }
Keyword.BRACE_CLOSE
])

View File

@ -46,3 +46,32 @@ class Keyword(Flag):
IDENTIFIER = auto() IDENTIFIER = auto()
INTEGERCONSTANT = auto() INTEGERCONSTANT = auto()
STRINGCONSTANT = auto() STRINGCONSTANT = auto()
class Symbol(Flag):
# Symbols Start here
BRACE_OPEN = Keyword.BRACE_OPEN
BRACE_CLOSE = Keyword.BRACE_CLOSE
PARAN_OPEN = Keyword.PARAN_OPEN
PARAN_CLOSE = Keyword.PARAN_CLOSE
SQUARE_OPEN = Keyword.SQUARE_OPEN
SQUARE_CLOSE = Keyword.SQUARE_CLOSE
DOT = Keyword.DOT
SEMICOLON = Keyword.SEMICOLON
PLUS = Keyword.PLUS
MINUS = Keyword.MINUS
MUL = Keyword.MUL
DIV = Keyword.DIV
AND = Keyword.AND
OR = Keyword.OR
LT = Keyword.LT
GT = Keyword.GT
EQ = Keyword.EQ
NOT = Keyword.NOT
COMMA = Keyword.COMMA
class Token(Flag):
KEYWORD = auto()
SYMBOL = auto()
IDENTIFIER = Keyword.IDENTIFIER
INTEGERCONSTANT = Keyword.INTEGERCONSTANT
STRINGCONSTANT = Keyword.STRINGCONSTANT