This is an old revision of the document!
The purpose of the homework is to write the semantic analysis, the intermediate language 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 source.alf.json
You may use your grammar file or the reference file
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 error_list [] // the error list }
The symbol table is an array of context objects.
[ // context object id 0 - the context of the main script { ... }, // context object id 1 - the context object of a function { ... }, ... ]
While determining the symbol table, add to each AST node a parameter symbol with the value of the its context id.
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 "value": // the expression that the variable initially has (optional, if the define was with an assignment) } }, "messages": { // a dictionary of functions "message_name": { "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 "symbol": // the context object id that the function creates } }, "types": { // a dictionary of types "type": { "type": // the type of the new type class or array "line": // the line where the type was declared // for array "elements_type": // the type of each array element "from": // the first index "to": // the last index // for class "elements": [ // a list of array elements (the node form the AST) { "type": "id": "line": }, ... ] } }, "parent": 0, // the parent context position in the symbol_table (except of the main script that has no parent), usually 0, "type": // the type of the "message": // the message name if this is a function context "class": // the class name if the context is in a message that is in a class "return_value": // the return type of the function if this is a function context }
{ "variables": { "s": { "type": "school", "line": 8 } }, "messages": {}, "types": { "school": { "type": "class", "line": 6, "elements": [ { "type": "int", "id": "type", "line": 5 }, { "type": "logic", "id": "private", "line": 4 }, { "type": "string", "id": "name", "line": 3 } ] } } }
For each of the following nodes, determine the return type
Set type the by adding a parameter type in the node.
{ "id": "exp", "op": "=", "left": { "id": "exp", "op": "mod", "left": { "id": "id", "value": "n", "line": 8, "symbol": 1, "type": "int" }, "right": { "id": "id", "value": "i", "line": 8, "symbol": 1, "type": "int" }, "line": 8, "symbol": 1, "t": "int" }, "right": { "id": "value", "type": "int", "value": 0, "line": 8, "symbol": 1 }, "line": 8, "symbol": 1, "type": "logic" }
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 line: // the line number in the source (starting at 1) elements: // items for the error, each type of error has different items 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.
{
struct: // struct type name element: // element name
}
The error occurs when the array lower index is higher than the higher index
{ array: // array type name low_index: // the lower index value high_index: // the higher index value }
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 element { struct: // name of struct type element: // name of struct element with the unresolved type }
The error occurs when a function call is made to a function that is not defned.
{ id: // message name }
The error occurs when a variable that is not defined is used.
{ variable: // variable name }
The error occurs when a type that is not defined is used.
{
variable: // the variable that has that type type: // the type that is undefined
}
The error occurs when an element is not part of that struct.
{ class: // struct name property: // element name }
The error occurs when a property is requested for a variable that is not a class 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 a number or symbol
{ array: // array type index: // supplied index type }
The error occurs when a value statement (return node) is used outside a message
{ // empty }
The error occurs when an expression has incompatible types
// left op right { left: right: op: } // op value { value: op: } // if, while or repeat - aslongas { expression: // expression type op: // if, while, repeat } // for { expression: // expression type op: "for" element: // variable, from, to or step } // value_of_function { op: "value" to: // return type from: // provided type } // is { op: "is" to: // to type from: // from type } // struct element type is undefined { struct: // struct type, element: // name of struct element } // variable type is undefined { variable: // name of the variable }
This is a lexical error
{ 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