Commit for work at home
Commit for work at home part 2
Update 14
Rewritten the AST. The structure is now much more coordinates with the
grammar. I have also written most of the constructor functions and most
of the action code for the Bison grammar. At the moment the code is messy
and the AST generation is not quite complete.

A number of minor changes have been made in the process:

- Changed SLEN production: List replaced by AtomExp.
- Changed NE, LTE and GTE to NEQ, LTEQ and GTEQ respectively.
- Added NONE to mark_t enum.
- Changed CmpList to RelExp in grammar and modified RelExp production.
- Made EdgeList production left recursive.
- Removed Graphs: '[' LHS ']'... production and embedded it in RuleDecl.
- Renamed ParamList to VarDecls in grammar.
- Removed IDList: empty production.
- Changed Program: empty to Program: Declaration.
- Renamed MacroDecl, MacroCall, MacroList and MACID to ProcDecl etc.
- Added char* id to Bison's %union, changed action code for PROCID and
  ID
  in lexer accordingly.
- Modified RelExp, Subtype and Type productions to support AST
  generation.
- Removed enum types rel_t and type_t as they are no longer needed.
Update 15 Added symbol types to parser, debugged and tidied up the code.
Now compiles without warnings.

- Created new struct GPProcedure for a procedure declaration.
- Removed redundant rule for generating a new List for declarations;
  no need for a separate rule for GLOBAL_DECL and LOCAL_DECL.
- Modified action code for the topmost six grammar rules.
- Modified action code for Position production
- Renamed newLabel function to addLabel
- Fixed incorrect degree and llength types in struct GPAtomicExp.
- Removed yylval.type assignments from the lexer.
- Removed duplicate lexer regexps for type keywords.
- AST node Label now represented by a new struct GPLabel.
- Renamed Label constructor to newLabel and rewritten the body.
- Changed EdgePred, GPNode and GPEdge to accommodate new GPLabel.
- Added is_root and is_injective integer flags.
- Added RuleCall: RuleID to grammar.
- Replaced RuleSetCall: RuleID with RuleSetCall: RuleCall.
- Added new GPStatement type for command sequences.
- Renamed list_t name COMMAND_SEQUENCE to COMMANDS.
- Added AST structs to %union
- Changed RelExp productions and action code.
- Created new List entry for relational expressions.
- New constructor addRelationalExp; rewritten newRelationalExp.
- Renamed several AST node types as they clashed with lexer tokens.
- Renamed stmt_t OR to PROGRAM_OR to not clash with condexp_t OR.
- Removed #include "gpparser.h" from lexer as it is redundant.
- In GPDeclaration, GPList *main_prog changed to GPStatement
  *main_program.
- Fixed incorrect types of list_type and check_type in %union.
- Added newRuleDecl and newProcedureDecl to action code of last two
  ProcList productions.
- Removed erroneous pair of brackets from action code of first Block
  production.
- Fixed assignments in action code of Type productions.
- Added yylloc to action code of Graph production.
- Redefined yyerror and renamed lyyerror to print_error.
Update 16 AST pretty printer

Created files pretty.h and pretty.c to pretty print the AST.

Renamed gpparserfuncs.c to ast.c and gpparser.h to ast.h;
makefile edited accordingly.

ast.h: Removed extern int yylineno.
ast.h: Removed file_name, is_root and is_injective definitions.
ast.h: Changed node and edge types from symbol* to char* in
       newEdgePred, newDegreeOp, GPNodePair, GPNode, and GPEdge.
gpparser.y: Added file_name, is_root and is_injective definitions.
gpparser.y: Renamed char *filename to file_name and removed extern
              from its declaration.
gpparser.y: Removed all code in %code requires.
gpparser.y: Changed enum type declarations in Bison %union to int.
gpparser.y: Changed %type of NodeID and EdgeID to char*.
gpparser.y: Edited action code of NodeID and EdgeID productions.
gpparser.y: Added struct keyword to %union declarations.
Update 17 Debugging AST construction and AST pretty printer.

pretty.c: Modified functions to check for null pointers before
          accessing structs.
pretty.c: Removed file_name from print_location.
gplexer.l: Added strdup(yytext) to action code of PROCID,
           ID and STR rules.
gpparser.y: Removed name type in %union.
gpparser.y: All symbols of %type<name> are now %type<id>.
gpparser.y: Added a line in main to print the source file name.
gpparser.y: Removed useless RuleCall and ProcCall rules.
gpparser.y: Reorganised Block and SimpleCommand. Block now generates
            SimpleCommand!, SKIP and FAIL while SimpleCommand only
            generates RuleSetCall, RuleID and ProcID
            (formally RuleCall and ProcCall respectively).
            Action code changed accordingly.
gpparser.y: Changed action code for List: EMPTY to call addAtom with
            two NULL pointers.
gpparser.y: Added new top-level rule GPProgram: Program to correctly
            point gp_program to the root of the AST.
ast.h/ast.c: Changed all occurences of symbol* to char*.
Rewritten the makefile.
Update 18 Formatting and debugging

Added main.c file with project info and main from gpparser.y.
Renamed some AST node types: expanded DECLS to DECLARATIONS and
STMT to STATEMENT.
Renamed print_ast to print_list.
Renamed print_pos to print_position.

ast.h: in definition of GPAtomicExp, changed char *var to char *name.
pretty.c: defined function macro pretty_print for cleaner code.
pretty.c: added case(EQUAL) to print_list.
pretty.c, print_atom, case VARIABLE: prints atom->value.name instead of
          incorrect atom->value.var.
pretty.c: corrected printing of source and target in print_edge:
          printf(...,edge->name) to printf(...,edge->source/target).
Update 19 Rewrote pretty printer to output a DOT file.

Added an explicit AST node for GP's empty list: a struct GPAtomicExp
with type EMPTY_LIST.

ast.c: fixed bug in GPrule where malloc took sizeof GPProcedure instead
of
       sizeof GPRule.
ast.c: changed all if(!pointer) to if(pointer == NULL).
ast.c: in newStringLength, atom->value.str_arg = list_arg was wrong,
       changed to str_arg.
ast.h: assigned first name of all enum type definitions to 0.
pretty.c: default statements in switch now print more informative
messages
          along with the integer of the enum.
pretty.c: in print_atom case STRING_LENGTH, changed print_list to
print_atom.
gplexer.l: created new start state for strings to consume the quote
marks.
main.c: added code to print the ast if -g command line flag is given.
Update 20: GP2 syntax change - Relational expressions

The relational expression has been changed. They can no longer be
chained together, and GP lists can only be compared with = and !=. This has
resulted in changes in the Bison grammar and the AST. Now relational
operators are treated analogously to binary arithmetic operators.

pretty.c: Added detailed comments.
ast.c: Added a List reversal function.
gpparser.y: Added GPProgram nonterminal to %type<list>. This was
            causing a compiler warning in main.c as it thought gp_program
            was an integer.
gpparser.y: Moved EMPTY from List production to AtomExp production as
            the previous syntax forbade empty unless it was at the start
            of a list.
Update 21: Semantic analysis

Wrote a function to create the symbol table and to enter all the rule
and
procedure declarations along with their scope.

ast.c: malloc error messages now output to stderr rather than stdout.
pretty.c: in print_declaration, case MAIN_DECLARATION, removed shape=box
          from the first fprintf call.
gpparser.y: Renamed the nonterminal ProcList to LocalDecls.
Update 22: Debugged declaration_scan in seman.c

ast.h: Added #include<stdio.h> for the extern FILE *yyin declaration.
seman.c: Added #include seman.h, stdio.h, stdlib.h and string.h
seman.c: Fixed assignments to Symbols (e.g. Symbol->...= to
rule_symbol->...)
seman.c: Assignments to Symbols are are now allocated heap memory with
strdup.
seman.c: Added static to main_count declaration.
seman.c: Rewrote the function to take two new arguments to maintain
correct
         state in recursive calls.
seman.h: Changed names for symbol_type_t enums so as not to clash with
other
         enum names.
seman.h: Changed a Symbol's type to a char * for easier printing.
pretty.h: Added declaration for print_dot_ast.
pretty.c: In functions with switch-case statements, I moved the
next_node_id
          code to outside the switch instead of at the start of each
case
          body.
pretty.c/print_atom/case STRING_CONSTANT: Removed unnecessary final
         argument from second fprintf.
main.c, gplexer.l: Added #include <string.h>
makefile: Added warning flags and glib flag to CFLAGS.
Update 23: Added semantic checking to declaration_scan, debugged pretty.c

Extended declaration_scan to check for multiple occurrences of a single
procedure name and for multiple occurrences of the same rule name in the
same scope. This is done while names are added to the symbol table.

The AST pretty printer had a rather large bug in that pretty_print_list
wasn't called to print, for example, parameter lists in rules. This meant
that an empty parameter list was handled incorrectly. To rectify this, I
rewrote the pretty_print_list macro so it can be called in any printing
function, not just print_list, and invoked it in the appropriate places:
- print_procedure for local_decls.
- print_rule for variables, interface and condition (condition handled
  explicitly as opposed to a macro call as print_condition is called
  instead of print_list).
- print_graph for nodes and edges.

seman.c: Added local string variables proc_name and rule_name to store
         the names of procedures instead of repeating long structure
         accesses.
makefile: Added functionality to call make with an extensionless
          filename which executes gpparse and dot -Tjpeg on the file
          automatically.
Update 24: Main semantic checking function.

Parts of the main semantic checking function have now been written:
- The main procedure semantic_check, which recurses over declaration
  lists.
- A subprocedure statement_scan, which handles struct GPStatement
  nodes.
- An auxiliary function validate_call, which checks any rule or
  procedure calls to see if the rule/procedure name exists in the
  symbol table with a valid scope level.

seman.c: Changed parameter names from current_scope and tmp_scope to
         scope and symbol_scope respectively in declaration_scan.
ast.h: in typedef struct GPStatement, changed type of cmd_seq field from
       *List to the correct *GPStatement. This affected the functions
       newCommandSequence and print_statement.
main.c: Added code to optionally print the AST before or after the call
        to semantic_check.
pretty.c: Moved the definition of next_node_id and added
          next_node_id = 1; inside print_dot_ast to facilitate
          multiple calls to print_dot_ast.
Update 25: Semantic analysis.

Wrote the skeleton for rule_scan, which performs semantic analysis
on a GP2 rule. Also wrote a function that adds all variable
declarations, with their type and scope, to the symbol table.

makefile: Added the command to generate the post-semantic analysis
          AST to default.
seman.c: Added break; to cases ALAP_STATEMENT and PROGRAM_OR in
         statement_scan.
seman.c: Added code in semantic_check to check for empty command
         sequences and local declaration lists.
ast.h: Changed some variable names, also in ast.c and pretty.c
       (List.value) vars->variables, var->variable_name,
                    decl->declaration
       (GPDeclaration.value) proc->procedure
       (GPAtomicExp.value) num->number, str->string
seman.h: Added new field to struct Symbol called containing_rule.
         This is a string that specifies the rule that contains
         the symbol for a variable, node, or edge. pretty.c has been
         updated accordingly.
seman.c: Modified semantic_check to handle scopes correctly in case
         PROCEDURE_DECLARATION. Instead of modifying the parameter
         scope for the recursive call, I create a new char * variable
         to store the new local scope, which is the parameter to the
         recursive calls.
Update 26: More semantic analysis.

Wrote some more semantic analysis functions.

condition_scan and atomic_exp_scan process all conditions and atomic
expressions respectively with a switch case statement. Most of these
cases call auxiliary functions but some perform their own in-house
semantic checking.

gp_list_scan iteratively calls atomic_exp_scan.

variable_check performs semantic checking on variables depending
on their context. This is outdated as it doesn't take into
account my new representation of variable context: a bitfield
in the symbol struct.

Changed the interface syntax to a set of NodeIDs rather than a set of
pairs of NodeIDs. Wrote a function interface_scan to check correctness
in the interface list.

makefile: Added variables for program name and for the list of
          objects.
          Added -g to CFLAGS and removed the gpdebug rule.
seman.c: Added break; to default case in rule_scan.
seman.c: In enter_variables, added code to report repeated variable
         names in the same rule.
seman.c: Added extra string argument to validate_call to report
         whether a rule or a procedure call is incorrect.
ast.h: Removed REL_EXP from condexp_t enum definition and improved
       the general layout of the struct definitions.
seman.c: Removed strdups from expressions that initialise symbols.
         Duplicating strings is unnecessary.
seman.h: Added a context bitfield to struct Symbol as this will
         be necessary for semantic checking.
Update 27: Graph scan function

Wrote a function graph_scan to add nodes and edges to the symbol
table along with some semantic checking. The function also
takes into account which graph (left or right) is being processed.
Update 28: Polished seman.c: compiles successfully!

seman.c: Updated condition_scan and interface_scan to reflect
         changes in the Symbol data structure and the passing of
         characters between functions.
seman.c: In interface_scan, condition_scan case EDGE_PRED and
         atomic_exp_scan case OUTDEGREE, I moved the current_node
         assignment to inside the while loop (*after* the null
         check).
seman.c  In interface_scan, added code to print an error if a node
         ID occurs more than once.
Update 29: Debugged semantic analysis code.

interface_scan: Added a cast to strcmp in g_slist_insert_sorted and to
                iterator->data in the last fprintf call.
gp_list_scan: Created new List* iterator to move through the list
              argument, as opposed to using the function argument
              which was passed by reference.
condition_scan: fixed a bug in case EDGE_PRED: it printed out the
                name of the source node in the error message for the
                target node.
atomic_exp_scan: Now called with two bool values int_check and
		 string_check instead of two static variables. This
                 will cause no mix-ups between function calls.
atomic_exp_scan: For arithmetic operators and concatenation, left_exp
                 was being scanned twice. Fixed this so that left_exp
                 and right_exp are scanned.
atomic_exp_scan: code for case STRING_LENGTH was completely wrong. I
                 assumed a STRING_LENGTH pointed to a variable node
                 when it actually points to an arbitrary atomic exp.
                 Hence the body is a call to atomic_exp_scan with
                 the str_exp parameter set to true.
atomic_exp_scan: Added an else to if(!in_rule) statement in case
                 VARIABLE. This prevents redundant error reporting.
atomic_exp_scan: Removed int_exp/string_exp = true statements from
                 the binary operator cases.
pretty.c: Modified print_symbol to account for the new boolean flags
          in struct Symbol.
Update 30: Modifications and bug fixes.

All lists in the AST are now reversed. Hence reversal code has been
added to declaration_scan, to reverse local declaration lists;
rule_scan, to reverse the list of declaration types and the list of
variable names pointed to by each declaration type node; graph_scan,
to reverse node lists and edge lists;

The list reversal code in statement_scan has been modified as it
isn't necessary to explicitly create a double pointer.

If identifier clashes are found at any point, the identifier
currently being inspected is not added to the symbol table.
This was previously not accounted for in the code, so I have
written code in the appropriate places to deal with this.
Updated functions are declaration_scan, enter_variables,
graph_scan.

Added functionality to skip the call to semantic_check if there
are any rule/procedure declaration name clashes. Such clashes
could result in confusing error messages. In particular,
declaration_scan now returns an integer to communicate
with main.

declaration_scan: Rewrote the semantic checking for conflicting
                  procedure and rule names.
                  Minor edits to the error messages.
graph_scan: Fixed a bug caused by the code not checking if the
            symbol list is empty for source and target checks
            in edge declarations.
condition_scan: The call to atomic_exp_scan in cases GREATER-LESS_EQUAL
                now calls with sixth argument (int_exp) true.
gp_list_scan: Added code to remove unnecessary EMPTYs from lists.

main.c: "GP2 parse failed" message now prints to stderr.
gplexer.l: Changed the STRING start state to IN_STRING: It clashed
           with the token STRING which caused the token to not be sent
           to the parser. Also changed COMMENT to IN_COMMENT for
           consistency.
Update 31: Error Handling

The locations generated by Bison in gpparser.y have been fixed,
usually by replacing 'yylloc' with '@$' in the constructor
function calls. I wrote a long comment above the Bison grammar
to explain everything. I also added some grammar rules to catch
potential user errors, and some rules with the 'error' symbol
for error recovery. This necessitated a second error function
(in addition to yyerror) called report_error.

In pretty.c, I added a macro to generate the list of the four components
in the location structure generated by Bison. This has been added
to all the node printing calls to fprintf in pretty.c. There
were also some inconsistencies with the handling of errors of
strings in AST nodes (rule names, for instance). If the string
is for some reason NULL, then the code should write an 'Undefined'
node to the dot file and print an error message to stderr. This
didn't occur in all cases, and has been fixed.

In seman.c, I edited most error messages such that semantic errors
referring to a particular rule display the rule and procedure pair.
In addition, if an error is found that should have been caught by
the parser (e.g. empty command sequences), the error is reported to
log_file. log_file is a file that contains the printout of the symbol
table and any "advanced" errors (beyond normal syntax/semantic errors).
I also added code to handle multiple occurrences of list/string
variables in LHS labels, which is invalid according to GP2's semantics.

I also created two layers of error reporting: users see the errors
output to stderr, whereas more verbose errors are printed to a log file,
along with the symbol table. The log file is intended to be seen only
by developers and possibly advanced users.

The final major change is that I examined the structuring of my code
with respect to header files and global variables. The following
changes were made:
- Moved reverse function from ast module to seman module
- Moved definition of file_name, log_file and gp_program from ast.h
  to main.c
- Added extern List *gp_program to gpparser.y
- Changed some #includes
- Added a second mark_t definition to gplexer.l as it can't see
  the one in ast.h for some reason.
- Added extern char *file_name to gplexerl.
- Added header guards.

Minor changes:

gpparser.y
- Moved the square braces enclosing graphs from RuleDecl
  production to Graph production.
- Removed definition of print_error.

ast.c
- Changed error message for malloc fails.

pretty.c
- Removed print_location.

makefile
- Added gpparser.tab.h dependency to lex.yy.c. Separated CFLAGS
  from library flags (LFLAGS).