Differences

This shows you the differences between two versions of the page.

Link to this comparison view

alf:teme:tema4_en [2019/04/29 13:13]
teodor.deaconu
alf:teme:tema4_en [2020/04/25 12:15] (current)
alexandru.radovici
Line 14: Line 14:
 ===== What do you have to do ===== ===== What do you have to do =====
  
-The purpose of the homework is to write the semantic analysis, the intermediate language ​for the Alf language.+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: You will receive an AST from the parser that parses correctly a Alf language source and have to write:
   - the symbol table   - the symbol table
-  - add to every AST node an attribute //​symbol// ​with the context id and determine ​the types for the nodes that return (expressionvalueidelement_of_array,​ element_of_struct elements, value_of_function)+  - a new AST with the following modifications:​ 
 +    - the new AST is a list of function statements 
 +      - all the AST nodes will have a property called symbol_table ​that will point towards the symbol table entry where they declare variablesfunctions and types  
 +      - the main program is called "​script"​ 
 +      - all the other function definitions are moved from the old AST to the new AST 
 +    - all the variable definitions AST nodes are deleted orif they have an attribution `@var i:int <- 3;`are replaced by an attribution AST node `i <- 3;`.
   - the semantic error list   - the semantic error list
 +
  
 <​note>​ <​note>​
-All the three requirements are verified and graded separately. Examples that produce no errors will receive ​erroor ​points only if the symbol table and the ast are correct.+All the three requirements are verified and graded separately. Examples that produce no errors will receive ​error points only if the symbol table and the new AST are correct.
 </​note>​ </​note>​
  
Line 29: Line 35:
   * the output file   * the output file
 <code bash> <code bash>
-node main.js source.alf source.alf.json+node main.js source.alf.ast.json ​source.alf.json
 </​code>​ </​code>​
  
Line 48: Line 54:
 <code javascript>​ <code javascript>​
 { {
-    symbol_table: ​[...], // the symbol_table +    symbol_table: ​{...}, // the symbol_table 
-    ast: {...}, // the ast with the type for very node that returns a value +    ast: [...], // the ast with the type for very node that returns a value 
-    ​error_list ​[] // the error list+    ​errors ​[] // the error list
 } }
 </​code>​ </​code>​
Line 56: Line 62:
 ===== Symbol table ===== ===== Symbol table =====
  
-The symbol table is an array of context ​objects+The symbol table is represented by a Javascript object, where each property is the name of context. ​In the example below you 
 +can see there are two contexts: 
 +  * //script// - the context for the main script 
 +  * //​function_sum//​ - the context generated by the `sum` function
  
 <code javascript>​ <code javascript>​
-[ +{ 
-   // context object id 0 - the context of the main script +    "​script": { 
-   ​+        "​type":​ "​script",​ 
-      ... +        "​variables": ​{}, 
-   ​}, +        "​functions":​ { 
-   // context object id 1 - the context object of a function +            "​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":​ {} 
 +    } 
 +}
 </​code>​ </​code>​
  
-While determining the symbol table, add to each AST node a parameter //symbol// with the value of the its context id.+ 
 +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.
  
 ==== Context Object ==== ==== Context Object ====
Line 78: Line 122:
   * the variable declared in that context   * the variable declared in that context
   * the function declared in that context   * the function declared in that context
-  * the struct declared in that context +  * the types (array, ​structdeclared in that context 
-  * the parent context ​id (position in the symbol_table array) +  * the parent context ​name 
-  * the type of the context (module ​or message+  * the type of the context (`script`, `statements` ​or `function`
-  * the name of the function which context it is (unless this is not the module) +  * the title of the function which context it is (if the context type is `function`)
-  * the name of the struct which context ​it is (unless this is not the module) +
-  * the type of the return value of the message which context it is (unless this is not the module)+
  
 <​note>​ <​note>​
Line 89: Line 131:
   * the main module ​   * the main module ​
   * a function definition   * a function definition
-  * a struct+  * a if definition 
 +  * a for definition 
 +  * a loop when and loop go definition
 </​note>​ </​note>​
  
Line 99: Line 143:
          "​type":​ // type of the variable          "​type":​ // type of the variable
          "​line":​ // the line where the variable was declared          "​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)          "​value":​ // the expression that the variable initially has (optional, if the define was with an assignment)
       }       }
    },    },
    "​functions":​ { // a dictionary of functions    "​functions":​ { // a dictionary of functions
-      "function_name": {+      "function_title": {
          "​type":​ // the return type of the function          "​type":​ // the return type of the function
          "​parameters":​ [] // the list of parameters the function takes (the parameters node from the AST)          "​parameters":​ [] // the list of parameters the function takes (the parameters node from the AST)
          "​line":​ // the line where the function was declared          "​line":​ // the line where the function was declared
-         "​symbol":​ // the context object id that the function creates 
                    
       }       }
Line 113: Line 157:
    "​types":​ {  // a dictionary of types    "​types":​ {  // a dictionary of types
       "​type":​ {       "​type":​ {
-               "​type": ​ // the type of the new type class or array+               "​type": ​ // the type of the new type struct ​or array
                "​line": ​ // the line where the type was declared                "​line": ​ // the line where the type was declared
                // for array                // for array
                "​elements_type": ​ // the type of each array element                "​elements_type": ​ // the type of each array element
-               "​from": ​ // the first index +               "​first": ​ // the first index 
-               "​to": // the last index+               "​length": // the number of elements in the array
                // for struct                // for struct
-               "​elements": [ // a list of array elements (the node form the AST)+               "​properties": [ // a list of array elements (the node form the AST)
                   {                   {
                      "​type": ​                      "​type": ​
-                     "​id": ​+                     "​title": ​ 
 +                     "​value":​ // the expression that the variable initially has (optional, if the define was with an assignment)
                      "​line": ​                      "​line": ​
 +                     "​symbol_table":​ // the context title where the structure was defined
                   },                   },
                   ...                   ...
Line 130: Line 176:
             }             }
    },    },
-   "​parent": ​0, // the parent context ​position in the symbol_table (except of the main script that has no parent), usually 0,  +   "​parent":​ // the parent context the symbol_table (except of the main script that has no parent)  
-   "​type":​ // the type of the  +   "​type":​ // the type of the context ​(script, ​function ​or statements)
-   "​function":​ // the function name if this is a function ​context +
-   "​struct":​ // the struct name if the context is in a function ​that is in a struct +
-   "​return_value":​ // the return type of the function if this is a function context+
 } }
 </​code>​ </​code>​
-=== Exemple ​===+ 
 +==== Context names ==== 
 +  * ''​script''​ - script 
 +  * ''​function''​ - 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 new AST ===== 
 +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. 
 <code javascript>​ <code javascript>​
-{ +[ 
-   "​variables":​ { +  // the script 
-      "s": { +  "script": { 
-         "​type"​"​school",​ +    ​statements[ 
-         "​line":​ 8 +      ​... 
-      ​} +    ] 
-   }, +  }, 
-   "​functions":​ {}, +  // a function 
-   "​types":​ { +  "function_title": { 
-      "school": { +     statements: [ 
-         "​type":​ "​class",​ +       ... 
-         "​line":​ 6, +     ] 
-         "​elements"​: [ +  
-            { +]
-               "​type":​ "​int",​ +
-               "​id":​ "​type",​ +
-               "​line":​ 5 +
-            ​}, +
-            { +
-               "​type":​ "​logic",​ +
-               "​id":​ "​private",​ +
-               "​line":​ 4 +
-            }, +
-            { +
-               "​type":​ "​string",​ +
-               "​id":​ "​name",​ +
-               "​line":​ 3 +
-            } +
-         ] +
-      } +
-   } +
-}+
 </​code>​ </​code>​
 +
 +==== Variable definitions ====
 +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;''​.
 +
 +==== Type definitions ====
 +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 [[https://​github.com/​UPB-FILS/​alf/​blob/​master/​Devoir/​semantic/​verify/​semantic/​4_struct/​definition_with_values_and_variable.alf|example]] in the repository.
  
 ===== Verify Types in the AST ===== ===== Verify Types in the AST =====
Line 177: Line 225:
 ==== Expression return type ==== ==== Expression return type ====
 For each of the following nodes, determine the return type For each of the following nodes, determine the return type
-  * exp+  * expr
   * value   * value
   * identifier   * identifier
   * return   * return
-  * element+  * element_of_vector
   * property   * property
-  * dispatch+  * function_call 
 + 
 +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. Set type the by adding a parameter type in the node.
Line 189: Line 239:
 <​note>​ <​note>​
 When searching for a variable, the algorithm is: When searching for a variable, the algorithm is:
-  * if it is a function context, ​search the local variables +  * search the local context 
-  * if not found, search the parameters +  * if not found, search the parent ​context
-  * if not found, search the struct ​context ​local variables +
- +
-  * if it is the module context, search the global variables+
 </​note>​ </​note>​
  
 === Example === === Example ===
 <code javascript>​ <code javascript>​
-  ​ +
-   ​"​id":​ "exp", +    "​id":​ "expr", 
-   ​"​op":​ "=", +    "​op":​ "+", 
-   ​"​left":​ { +    "​left":​ { 
-      "​id": ​"​exp",​ +       ​"​id":​ "​value",​ 
-      "​op":​ "​mod",​ +       ​"​type":​ "​int",​ 
-      "​left":​ { +       ​"​value": ​2
-         "​id":​ "​id",​ +       ​"​line": ​3
-         "value": "n", +       ​"symbol_table": "script
-         "​line":​ 8, +    }, 
-         "​symbol":​ 1, +    "​right":​ { 
-         "​type":​ "​int"​ +       ​"​id":​ "​value",​ 
-      }+       ​"​type":​ "​int",​ 
-      "​right":​ { +       ​"​value": ​3
-         "​id":​ "​id",​ +       ​"​line": ​3
-         "​value": ​"​i"​+       ​"symbol_table": ​"​script"​ 
-         ​"​line": ​8+    }, 
-         ​"symbol": ​1, +    "​line": ​3
-         "type": "​int"​ +    "symbol_table": ​"​script"​
-      }, +    "​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"+
 } }
 </​code>​ </​code>​
Line 239: Line 272:
   * attributions work   * attributions work
   * expressions can be calculated ​   * expressions can be calculated ​
-  * the if/​loop/​loop when aslongas ​expression is a logic value+  * the if/loop-go/loop-when expression is a logic value
   * the for variable is a number   * the for variable is a number
   * that variables are defined before being used   * that variables are defined before being used
Line 245: Line 278:
   * array indexes are numbers   * array indexes are numbers
   * struct properties exist   * struct properties exist
-  * the variable for element_of_array ​is an array+  * the variable for element_of_vector ​is an array
   * the variable for a property is a struct   * the variable for a property is a struct
   * variables are not redefined ​   * variables are not redefined ​
Line 265: Line 298:
 { {
     type: //  string with the error type     type: //  string with the error type
-    ​line: // the line number in the source (starting at 1) +    elements: ​
-    ​elements: // items for the error, each type of error has different items+       // items for the error, each type of error has different items 
 +       line: // the line where the error is 
 +    },
     text: // the error text message     text: // the error text message
 } }
 </​code>​ </​code>​
 +
 ==== Error type ==== ==== Error type ====
  
Line 280: Line 316:
 <code javascript>​ <code javascript>​
 { {
-    variable: // variable name+    variable: // variable name,
 } }
 </​code>​ </​code>​
Line 304: Line 340:
 </​code>​ </​code>​
  
-=== STRUCT_ELEMENT_ALREADY_DEFINED ​===+=== STRUCT_PROPERTY_ALREADY_DEFINED ​===
 The error occurs when a struct element definition is repeated. The error occurs when a struct element definition is repeated.
  
 == Elements == == Elements ==
 { {
-    ​struct: // struct type name +    ​type: // struct type title 
-    ​element: // element name+    ​title: // property title
 } }
  
Line 320: Line 356:
 { {
     array: // array type name     array: // array type name
-    ​low_index: // the lower index value +    ​length: // the negative length
-    high_index: // the higher index value+
 } }
 </​code>​ </​code>​
Line 334: Line 369:
     variable: // the name of the variable with the unresolved type     variable: // the name of the variable with the unresolved type
 } }
-// struct ​element+// struct ​property
 { {
     struct: // name of struct type     struct: // name of struct type
-    ​element: // name of struct element with the unresolved type+    ​property: // name of struct element with the unresolved type
 } }
  
 </​code>​ </​code>​
  
-=== UNDEFINED_MESSAGE ​=== +=== UNDEFINED_FUNCTION ​=== 
-The error occurs when a function call is made to a function that is not defned.+The error occurs when a function call is made to a function that is not defined.
  
 == Elements == == Elements ==
 <code javascript>​ <code javascript>​
 { {
-   id: // message name+   title: // function title
 } }
 </​code>​ </​code>​
Line 358: Line 393:
 <code javascript>​ <code javascript>​
 { {
-   ​variable:​ // variable ​name+   ​variable:​ // variable ​title
 } }
 </​code>​ </​code>​
Line 367: Line 402:
 == Elements == == Elements ==
 { {
-    ​variable: // the variable that has that type +    ​value: // the type that is undefined
-    type: // the type that is undefined+
 } }
  
Line 377: Line 411:
 <code javascript>​ <code javascript>​
 { {
-   struct: // struct ​name +   type: // struct ​title 
-   property: // element name+   title: // property title
 } }
 </​code>​ </​code>​
Line 402: Line 436:
 </​code>​ </​code>​
 === ARRAY_INDEX_TYPE === === ARRAY_INDEX_TYPE ===
-The error occurs when an index for an array is not a number or symbol+The error occurs when an index for an array is not an int
  
 == Elements == == Elements ==
 <code javascript>​ <code javascript>​
 { {
-   array: // array type +   type: // the index type
-   index: // supplied ​index type+
 } }
 </​code>​ </​code>​
Line 438: Line 471:
     op:     op:
 } }
-// if, while or repeat ​aslongas+// if, loop-go, loop-when
 { {
-    ​expression: // expression type+    ​exp: // expression type
     op: // if, while, repeat     op: // if, while, repeat
 } }
-// for+// attribution (including ​for variable)
 { {
-    ​expression: // expression ​type +    ​to: // to type, 
-    op: "for+    op: "<-", 
-    ​element: // variable, ​from, to or step+    ​from: // from type
 } }
-// value_of_function+// return
 { {
-    op: "value"+    op: "return"
     to: // return type     to: // return type
     from: // provided type     from: // provided type
 } }
-// is+// iteration (for i in exp go)
 { {
-    op: "is+    op: "iteration
-    ​to: // to type +    ​value: // the exp type
-    from: // from type+
 } }
-// struct element type is undefined+// typecast
 { {
-    ​struct: // struct ​type, +    ​op: "​typecast",​ 
-    ​element: // name of struct element+    to: // to type, 
 +    ​from: // from type
 } }
-// variable type is undefined 
-{ 
-    variable: // name of the variable 
-} 
-</​code>​ 
  
 === LEXICAL === === LEXICAL ===
Line 575: Line 603:
   - Create a zip (not rar, ace, 7zip or anything else) archive containing:   - Create a zip (not rar, ace, 7zip or anything else) archive containing:
     * your main file        * your main file   
-    * your grammar.jison file  
     * your javascript files (*.js)     * your javascript files (*.js)
     * the package.json file     * the package.json file
alf/teme/tema4_en.1556532799.txt.gz · Last modified: 2019/04/29 13:13 by teodor.deaconu
CC Attribution-Share Alike 3.0 Unported
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0