| Lexical elements: | |
The Jack language includes five types of terminal elements (tokens), and two comment sequences1: |
| comment: | |
'/*' A sequence of characters not including */ '*/' |
| eolComment: | |
'//' A sequence of characters not including newline '\n' |
| keyword: | |
'class' | 'constructor' | 'function' | 'method' | 'field' | 'static' | 'var' | 'int' | 'char' | 'boolean' | 'void' | 'true' | 'false' | 'null' | 'this' | 'let' | 'do' | 'if' | 'else' | 'while' | 'return'
|
| symbol: | |
'{' | '}' | '(' | ')' | '[' | ']' | '.' | ',' | ';' | '+' | '-' | '*' | '/' | '&' | '|' | '<' | '>' | '=' | '~' |
| integerConstant: | |
A decimal number in the range 0..32767 |
| stringConstant: | |
' " ' A sequence of characters including /* and // not including double quote or newline ' " ' |
| identifier: | |
A sequence of letters, digits, and underscore ('_') not starting with a digit |
|
| Program structure: | |
A Jack program is a collection of classes, each appearing in a separate file. The compilation unit is a class. A class is a sequence of tokens structured according to the following context free syntax: |
| class: | |
'class' className '{' classVarDec* subroutineDec* '}' |
| classVarDec: | |
('static' | 'field') type varName (',' varName)* ';' |
| type: | |
'int' | 'char' | 'boolean' | className |
| subroutineDec: | |
('constructor' | 'function' | 'method') ('void' | type) subroutineName '(' parameterList ')' subroutineBody |
| parameterList: | |
( (type varName) (',' type varName)* )? |
| subroutineBody: | |
'{' varDec* statements '}' |
| varDec: | |
'var' type varName (',' varName)* ';' |
| className: | |
identifier |
| subroutineName: | |
identifier |
| varName: | |
identifier |
|
| Statements: |
| statements: | |
statement* |
| statement: | |
letStatement | ifStatement | whileStatement | doStatement | returnStatement |
| letStatement: | |
'let' varName ('[' expression ']')? '=' expression ';' |
| ifStatement: | |
'if' '(' expression ')' '{' statements '}' ('else' '{' statements '}')? |
| whileStatement: | |
'while' '(' expression ')' '{' statements '}' |
| doStatement: | |
'do' subroutineCall ';' |
| returnStatement: | |
'return' expression )? ';' |
|
| Expressions: |
| expression: | |
term (op term)* |
| term: | |
integerConstant | stringConstant | keywordConstant | varName | varName '[' expression ']' | subroutineCall | '(' expression ')' | unaryOp term |
| subroutineCall: | |
subroutineName '(' expressionList ')' | ( className | varName) '.' subroutineName '(' expressionList ')' |
| expressionList: | |
(expression (',' expression)* )? |
| op: | |
'+' | '-' | '*' | '/' | '&' | '|' | '<' | '>' | '=' |
| unaryOp: | |
'-' | '~' |
| keywordConstant: | |
'true' | 'false' | 'null' | 'this' |
|
1 The course treats comment sequenceses as external to the grammar, but they are much easier to handle in the context of the grammar. Consider this command:
let str = "Comments can start with //.";
You must know that you are within the StringConstant element so that you do not recognize //."; as an end-of-line comment and remove it. |