121 lines
3.0 KiB
Python
121 lines
3.0 KiB
Python
from keywords import Keyword
|
|
|
|
"""
|
|
The grammar is defined by the following constructs:
|
|
|
|
The top level object is called GRAMMAR, which is the grammar for a class. It is a list object.
|
|
|
|
Inside this list, each element can be any of the following:
|
|
|
|
- a token (denoted by a Keyword enum)
|
|
- a bitwise mask of the Keyword enum to denote multiple possibilities
|
|
- Another list, to denote zero-or-more of a inner-sequence
|
|
- A tuple, to denote zero-or-one of a inner-sequence
|
|
|
|
This is basically an attempt to translate Figure 10.5 from the book into
|
|
a Python structure.
|
|
|
|
"""
|
|
|
|
TYPE = Keyword.INT | Keyword.CHAR | Keyword.BOOLEAN | Keyword.IDENTIFIER
|
|
|
|
UNARY_OP = Keyword.NOT | Keyword.MINUS
|
|
|
|
TERM = Keyword.INTEGERCONSTANT | Keyword.STRINGCONSTANT | Keyword.TRUE | Keyword.FALSE | Keyword.IDENTIFIER
|
|
|
|
OP = Keyword.PLUS | Keyword.MINUS | Keyword.MUL | Keyword.DIV | Keyword.AND | Keyword.OR | Keyword.GT | Keyword.LT | Keyword.EQ
|
|
|
|
EXPRESSION = [TERM, [OP, TERM]]
|
|
|
|
EXPRESSIONLIST = (EXPRESSION, [Keyword.COMMA, EXPRESSION])
|
|
|
|
SUBROUTINE_CALL = {
|
|
(Keyword.IDENTIFIER, Keyword.PARAN_OPEN): [
|
|
EXPRESSIONLIST,
|
|
Keyword.PARAN_CLOSE,
|
|
],
|
|
(Keyword.IDENTIFIER, Keyword.DOT): [
|
|
Keyword.IDENTIFIER,
|
|
Keyword.PARAN_OPEN,
|
|
EXPRESSIONLIST,
|
|
Keyword.PARAN_CLOSE
|
|
]
|
|
}
|
|
|
|
STATEMENTS = {
|
|
(Keyword.LET): [Keyword.IDENTIFIER, (Keyword.SQUARE_OPEN, EXPRESSION, Keyword.SQUARE_CLOSE)],
|
|
(Keyword.IF): [
|
|
Keyword.PARAN_OPEN,
|
|
EXPRESSION,
|
|
Keyword.PARAN_CLOSE,
|
|
Keyword.BRACE_OPEN,
|
|
lambda:STATEMENTS,
|
|
Keyword.BRACE_CLOSE,
|
|
( Keyword.ELSE, Keyword.BRACE_OPEN, lambda:STATEMENTS, Keyword.BRACE_CLOSE)
|
|
],
|
|
(Keyword.WHILE): [
|
|
Keyword.PARAN_OPEN,
|
|
EXPRESSION,
|
|
Keyword.PARAN_CLOSE,
|
|
Keyword.BRACE_OPEN,
|
|
lambda:STATEMENTS,
|
|
Keyword.BRACE_CLOSE,
|
|
],
|
|
(Keyword.DO): SUBROUTINE_CALL,
|
|
(Keyword.RETURN): [(EXPRESSION), Keyword.SEMICOLON]
|
|
}
|
|
|
|
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 =
|
|
# (
|
|
# (type varName) (, type varName)*
|
|
# )?
|
|
# we use tuples for zero OR one of a sequence
|
|
(
|
|
TYPE,
|
|
Keyword.IDENTIFIER,
|
|
[Keyword.COMMA, TYPE, Keyword.IDENTIFIER]
|
|
),
|
|
Keyword.PARAN_CLOSE,
|
|
# Subroutine Body {
|
|
Keyword.BRACE_OPEN,
|
|
# One or more variable declarations
|
|
# `var type varName (, varName)* ;`
|
|
[
|
|
Keyword.VAR,
|
|
TYPE,
|
|
Keyword.IDENTIFIER,
|
|
[Keyword.COMMA, Keyword.IDENTIFIER],
|
|
Keyword.SEMICOLON
|
|
],
|
|
STATEMENTS,
|
|
Keyword.BRACE_CLOSE,
|
|
]
|
|
|
|
CLASSVARDEC = [
|
|
# static|field type (, name)* ;
|
|
Keyword.STATIC | Keyword.FIELD,
|
|
TYPE,
|
|
[Keyword.COMMA, Keyword.IDENTIFIER],
|
|
Keyword.SEMICOLON
|
|
]
|
|
|
|
GRAMMAR = [
|
|
# 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
|
|
]
|