etisserant@0: /* etisserant@0: * (c) 2003 Mario de Sousa etisserant@0: * etisserant@0: * Offered to the public under the terms of the GNU General Public License etisserant@0: * as published by the Free Software Foundation; either version 2 of the etisserant@0: * License, or (at your option) any later version. etisserant@0: * etisserant@0: * This program is distributed in the hope that it will be useful, but etisserant@0: * WITHOUT ANY WARRANTY; without even the implied warranty of etisserant@0: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General etisserant@0: * Public License for more details. etisserant@0: * etisserant@0: * This code is made available on the understanding that it will not be etisserant@0: * used in safety-critical situations without a full and competent review. etisserant@0: */ etisserant@0: etisserant@0: /* etisserant@0: * An IEC 61131-3 IL and ST compiler. etisserant@0: * etisserant@0: * Based on the etisserant@0: * FINAL DRAFT - IEC 61131-3, 2nd Ed. (2001-12-10) etisserant@0: * etisserant@0: */ etisserant@0: etisserant@0: /* etisserant@0: **************************************************************** etisserant@0: **************************************************************** etisserant@0: **************************************************************** etisserant@0: ********* ********* etisserant@0: ********* ********* etisserant@0: ********* O V E R A L L A R C H I T E C T U R E ********* etisserant@0: ********* ********* etisserant@0: ********* ********* etisserant@0: **************************************************************** etisserant@0: **************************************************************** etisserant@0: **************************************************************** etisserant@0: etisserant@0: The compiler works in 4(+1) stages: etisserant@0: Stage 1 - Lexical analyser - implemented with flex (iec.flex) etisserant@0: Stage 2 - Syntax parser - implemented with bison (iec.y) etisserant@0: Stage 3 - Semantics analyser - not yet implemented etisserant@0: Stage 4 - Code generator - implemented in C++ etisserant@0: Stage 4+1 - Binary code generator - gcc, javac, etc... etisserant@0: etisserant@0: etisserant@0: Data structures passed between stages, in global variables: etisserant@0: 1->2 : tokens (int), and token values (char *) etisserant@0: 2->1 : symbol tables (defined in symtable.hh) etisserant@0: 2->3 : abstract syntax tree (tree of C++ classes, in absyntax.hh file) etisserant@0: 3->4 : Same as 2->3 etisserant@0: 4->4+1 : file with program in c, java, etc... etisserant@0: etisserant@0: etisserant@0: The compiler works in several passes: etisserant@0: Pass 1: executes stages 1 and 2 simultaneously etisserant@0: Pass 2: executes stage 3 etisserant@0: Pass 3: executes stage 4 etisserant@0: Pass 4: executes stage 4+1 etisserant@0: */ etisserant@0: etisserant@0: etisserant@0: etisserant@0: //#include // printf() etisserant@0: etisserant@0: #include // EXIT_FAILURE etisserant@0: #include "absyntax/absyntax.hh" // symbol_c type etisserant@0: etisserant@0: etisserant@0: etisserant@0: etisserant@0: /* A macro for printing out internal parser errors... */ etisserant@0: #include // required for std::cerr etisserant@0: #define ERROR error_exit(__FILE__,__LINE__) etisserant@0: void error_exit(const char *file_name, int line_no) { etisserant@0: std::cerr << "\nInternal program error in file " << file_name etisserant@0: << " at line " << line_no << "\n\n\n"; etisserant@0: exit(EXIT_FAILURE); etisserant@0: } etisserant@0: etisserant@0: etisserant@0: etisserant@0: /* forward declarations... */ etisserant@0: int stage1_2(const char *filename, const char *includedir, symbol_c **tree_root); etisserant@0: //int stage3(symbol_c *tree_root); lbessard@46: int stage4(symbol_c *tree_root, const char *builddir); etisserant@0: etisserant@0: etisserant@0: static void printusage(const char *cmd) { etisserant@0: printf("%s [] [-I ]\n", cmd); etisserant@0: } etisserant@0: etisserant@0: etisserant@0: etisserant@0: int main(int argc, char **argv) { etisserant@0: symbol_c *tree_root; etisserant@0: char * includedir = NULL; lbessard@46: char * builddir = NULL; lbessard@46: lbessard@46: if (argc == 5) { lbessard@46: builddir = argv[4]; lbessard@46: argc = 4; lbessard@46: } etisserant@0: etisserant@0: if (argc == 4) { etisserant@0: if (strcmp(argv[2], "-I") != 0) { etisserant@0: printusage(argv[0]); etisserant@0: return EXIT_FAILURE; etisserant@0: } etisserant@0: includedir = argv[3]; etisserant@0: argc = 2; etisserant@0: } etisserant@0: lbessard@46: if (argc == 3) { lbessard@46: builddir = argv[2]; lbessard@46: argc = 2; lbessard@46: } lbessard@46: etisserant@0: if (argc != 2) { etisserant@0: printusage(argv[0]); etisserant@0: return EXIT_FAILURE; etisserant@0: } etisserant@0: etisserant@0: /* 1st Pass */ etisserant@0: if (stage1_2(argv[1], includedir, &tree_root) < 0) etisserant@0: return EXIT_FAILURE; etisserant@0: etisserant@0: /* 2nd Pass */ etisserant@0: /* not yet implemented... */ etisserant@0: /* etisserant@0: if (stage3(tree_root) < 0) etisserant@0: return EXIT_FAILURE; etisserant@0: */ etisserant@0: etisserant@0: /* 3rd Pass */ lbessard@46: if (stage4(tree_root, builddir) < 0) etisserant@0: return EXIT_FAILURE; etisserant@0: etisserant@0: /* 4th Pass */ etisserant@0: /* Currently implemented in the Makefile! */ etisserant@0: etisserant@0: return 0; etisserant@0: } etisserant@0: etisserant@0: