The purpose of the homework is to create the symbol table and write the semantic analysis for the Alf language.
You will receive an AST from the parser that parses correctly a Alf language source and have to write:
The program will receive two parameters from the command line:
node main.js source.alf.ast.json source.alf.json
Use the ast given here.
The format of the output file is the following
{ symbol_table: {...}, // the symbol_table ast: [...], // the ast with the type for very node that returns a value errors [] // the error list }
The symbol table is represented by a Javascript object, where each property is the name of a context. In the example below you can see there are two contexts:
{ "script": { "type": "script", "variables": {}, "functions": { "sum": { "type": "int", "parameters": [ { "type": "int", "title": "n1", "line": 4 }, { "type": "int", "title": "n2", "line": 4 } ], "line": 4 } }, "types": {} }, "function_sum": { "title": "sum", "type": "function", "parent": "script", "variables": { "n1": { "type": "int", "parameter": true, "index": 0 }, "n2": { "type": "int", "parameter": true, "index": 1 } }, "functions": {}, "types": {} } }
While determining the symbol table, add to each AST node a parameter symbol_table with the name of the symbol table in which it has its variables, functions and types.
The context object stores
The object looks like
{ "variables": { // a dictionary of variables "variable_name": { "type": // type of the variable "line": // the line where the variable was declared "parameter": //true if this is a function parameter, false otherwise "value": // the expression that the variable initially has (optional, if the define was with an assignment) } }, "functions": { // a dictionary of functions "function_title": { "type": // the return type of the function "parameters": [] // the list of parameters the function takes (the parameters node from the AST) "line": // the line where the function was declared } }, "types": { // a dictionary of types "type": { "type": // the type of the new type struct or array "line": // the line where the type was declared // for array "elements_type": // the type of each array element "first": // the first index "length": // the number of elements in the array // for struct "properties": [ // a list of array elements (the node form the AST) { "type": "title": "value": // the expression that the variable initially has (optional, if the define was with an assignment) "line": "symbol_table": // the context title where the structure was defined }, ... ] } }, "parent": // the parent context the symbol_table (except of the main script that has no parent) "type": // the type of the context (script, function or statements) }
script
- scriptfunction
- function_title
if_then
- if_line_where_the_if_then_was_defined
loop_when
- do_while_line_where_the_loop_when_was_defined
loop_go
- while_line_where_the_loop_go_was_defined
The AST from the parser has to be transformed so that it does not contain any variable, function or type definitions.
The new AST is a list of objects, each object being either the script either a function.
[ // the script "script": { statements: [ ... ] }, // a function "function_title": { statements: [ ... ] } ]
The variable definitions will be written to the symbol table. The definition will be deleted from the AST (it will not be placed in the
statements, as it has no actual action). If the definition is with an attribution @var x:int ← 7;
, it will be replaced with
an attribution node equivalent to x ← 7;
.
Structs and vectors are type definitions. These will be written to the types
part in the symbol table.
For structs, if the properties have default values, every struct variable declaration will be replaced with attributions for all the properties. There is an example in the repository.
For each of the following nodes, determine the return type
All the other elements have the return type none
. If there is a type error (eg. float * string) it will be error
.
Set type the by adding a parameter type in the node.
{ "id": "expr", "op": "+", "left": { "id": "value", "type": "int", "value": 2, "line": 3, "symbol_table": "script" }, "right": { "id": "value", "type": "int", "value": 3, "line": 3, "symbol_table": "script" }, "line": 3, "symbol_table": "script", "type": "int" }
For all the AST nodes, verify that the types match:
The error list is an array that contains error objects. The order in which these errors are in the list is up to you.
Each error has the following format:
{ type: // string with the error type elements: { // items for the error, each type of error has different items line: // the line where the error is }, text: // the error text message }
The error type is a string with one of the following titles
The error occurs when a variable definition is repeated.
{ variable: // variable name, }
The error occurs when a function definition is repeated.
{ function: // function name }
The error occurs when a type definition is repeated (array or struct).
{ type: // type name }
The error occurs when a struct element definition is repeated.
{
type: // struct type title title: // property title
}
The error occurs when the array lower index is higher than the higher index
{ array: // array type name length: // the negative length }
The error occurs when the type of a variable is not determinable (bonus only).
// variable { variable: // the name of the variable with the unresolved type } // struct property { struct: // name of struct type property: // name of struct element with the unresolved type }
The error occurs when a function call is made to a function that is not defined.
{ title: // function title }
The error occurs when a variable that is not defined is used.
{ variable: // variable title }
The error occurs when a type that is not defined is used.
{
value: // the type that is undefined
}
The error occurs when an element is not part of that struct.
{ type: // struct title title: // property title }
The error occurs when a property is requested for a variable that is not a struct type
{ type: // actual type that the variable is (instead of a struct type) }
The error occurs when an index is requested for a variable that is not an array
{ type: // actual type that the variable is (instead of an array type) }
The error occurs when an index for an array is not an int
{ type: // the index type }
The error occurs when a value statement (return node) is used outside a function
{ // empty }
The error occurs when an expression has incompatible types
// left op right { left: right: op: } // op value { value: op: } // if, loop-go, loop-when { exp: // expression type op: // if, while, repeat } // attribution (including for variable) { to: // to type, op: "<-", from: // from type } // return { op: "return" to: // return type from: // provided type } // iteration (for i in exp go) { op: "iteration" value: // the exp type } // typecast { op: "typecast", to: // to type, from: // from type } === LEXICAL === This is a lexical error == Elements == <code javascript> { line: // the line number text: // the text of the error }
This is a syntax error
{ line: // the line number text: // the text of the error token: // the token it got expected: [] / the list of expected tokens }
For an additional 0.5p, implement find the type of variables that are declared using just an attribution.
The homework is individual. Any attempt of copying will result in 0p for the homework. Automated anti copying system will be used.
If you have any questions related to the homework, please ask them by posting an issue on the github repository with the title format [calculator] <your question title>. You will need a github account for that.
If you want to receive an email when issues are posted or when there are new messages, got to the github repository and click Watch.
The homework will be tested automatically using a set of public and private tests.
You can download the public tests from the GitHub repository.
To run the tests, download the contents of the repository in the folder with the homework. Enter the verify folder and run ./run_all.sh.
cd verify ./run_all.sh
You will need bash for that. You can use either Linux or Windows Linux Subsystem.
wget https://nodejs.org/dist/v8.9.4/node-v8.9.4-linux-x64.tar.xz tar xvfJ node-v8.9.4-linux-x64.tar.xz cd node-v8.9.4-linux-x64 sudo cp -R * /usr
When uploading the homework, we might have some private tests that it needs to pass. vmchecker will run them.
The homework needs to be uploaded to vmchecker. Login with your moodle user name, select the Automates et Langages Formelles (FILS) course and upload the homework archive.
The readme file has the following format:
Your full name Group An explanation how you wrote your homework, what did you use, what are the main ideas.
To upload your homework, please follow the following:
DO NOT include node_modules.
When the archive is uploaded, vmchecker will run:
unzip archive.zip homework cd homework npm install echo '{ "node":true, "esnext":true }' > .jshintrc jshint *.js