main.cc
author Edouard TISSERANT <edouard.tisserant@gmail.com>
Sun, 29 Nov 2009 19:09:56 +0100
changeset 218 413842f6152f
parent 202 da1a8186f86f
child 261 db2ad6541d92
permissions -rwxr-xr-x
added files to ignore in hgignore
/*
 * (c) 2003 Mario de Sousa
 *
 * Offered to the public under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2 of the
 * License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
 * Public License for more details.
 *
 * This code is made available on the understanding that it will not be
 * used in safety-critical situations without a full and competent review.
 */

/*
 * An IEC 61131-3 IL and ST compiler.
 *
 * Based on the
 * FINAL DRAFT - IEC 61131-3, 2nd Ed. (2001-12-10)
 *
 */

/*
 ****************************************************************
 ****************************************************************
 ****************************************************************
 *********                                              *********
 *********                                              *********
 *********   O V E R A L L    A R C H I T E C T U R E   *********
 *********                                              *********
 *********                                              *********
 ****************************************************************
 ****************************************************************
 ****************************************************************

 The compiler works in 4(+1) stages:
 Stage 1   - Lexical analyser      - implemented with flex (iec.flex)
 Stage 2   - Syntax parser         - implemented with bison (iec.y)
 Stage 3   - Semantics analyser    - not yet implemented
 Stage 4   - Code generator        - implemented in C++
 Stage 4+1 - Binary code generator - gcc, javac, etc...


 Data structures passed between stages, in global variables:
 1->2   : tokens (int), and token values (char *)
 2->1   : symbol tables (defined in symtable.hh)
 2->3   : abstract syntax tree (tree of C++ classes, in absyntax.hh file)
 3->4   : Same as 2->3
 4->4+1 : file with program in c, java, etc...


 The compiler works in several passes:
 Pass 1: executes stages 1 and 2 simultaneously
 Pass 2: executes stage 3
 Pass 3: executes stage 4
 Pass 4: executes stage 4+1
*/



//#include <stdio.h>   // printf()
#include <getopt.h>
#include <string.h>
#include <stdlib.h>  // EXIT_FAILURE
#include "absyntax/absyntax.hh"  // symbol_c type

/* A macro for printing out internal parser errors... */
#include <iostream> // required for std::cerr
#define ERROR error_exit(__FILE__,__LINE__)
void error_exit(const char *file_name, int line_no) {
  std::cerr << "\nInternal program error in file " << file_name
            << " at line " << line_no << "\n\n\n";
  exit(EXIT_FAILURE);
}




#include "stage1_2/stage1_2.hh"
#include "absyntax_utils/absyntax_utils.hh"

int stage3(symbol_c *tree_root);
int stage4(symbol_c *tree_root, const char *builddir);


static void printusage(const char *cmd) {
  printf("syntax: %s [-h] [-f] [-s] [-I <include_directory>] [-T <target_directory>] <input_file>\n", cmd);
  printf("  h : show this help message\n");
  printf("  f : full token location on error messages\n");
      /******************************************************/
      /* whether we are suporting safe extensions           */
      /* as defined in PLCopen - Technical Committee 5      */
      /* Safety Software Technical Specification,           */
      /* Part 1: Concepts and Function Blocks,              */
      /* Version 1.0 – Official Release                     */
      /******************************************************/
  printf("  s : allow use of safe extensions\n");
}



int main(int argc, char **argv) {
  symbol_c *tree_root;
  char * builddir = NULL;
  stage1_2_options_t stage1_2_options = {false, false, NULL};
  int optres, errflg = 0;
/*
  extern char *optarg;
  extern int optind, optopt;
*/

  /******************************************/
  /*   Parse command line options...        */
  /******************************************/
  while ((optres = getopt(argc, argv, ":hfsI:T:")) != -1) {
    switch(optres) {
    case 'h':
      printusage(argv[0]);
      return 0;
      break;
    case 'f':
      stage1_2_options.full_token_loc = true;
      break;
    case 's':
      stage1_2_options.safe_extensions = true;
      break;
    case 'I':
      stage1_2_options.includedir = optarg;
      break;
    case 'T':
      builddir = optarg;
      break;
    case ':':       /* -I or -T without operand */
      fprintf(stderr, "Option -%c requires an operand\n", optopt);
      errflg++;
      break;
    case '?':
      fprintf(stderr, "Unrecognized option: -%c\n", optopt);
      errflg++;
      break;
    default:
      fprintf(stderr, "Unknown error while parsing command line options.");
      errflg++;
      break;
    }
  }

  if (optind == argc) {
    fprintf(stderr, "Missing input file\n");
    errflg++;
  }

  if (optind > argc) {
    fprintf(stderr, "Too many input files\n");
    errflg++;
  }

  if (errflg) {
      printusage(argv[0]);
      return EXIT_FAILURE;
  }


  /***************************/
  /*   Run the compiler...   */
  /***************************/
  /* 1st Pass */
  if (stage1_2(argv[optind], &tree_root, stage1_2_options) < 0)
    return EXIT_FAILURE;

  /* 2nd Pass */
  absyntax_utils_init(tree_root);
  add_en_eno_param_decl_c::add_to(tree_root);

  /* not yet implemented... */
  if (stage3(tree_root) < 0)
    return EXIT_FAILURE;
  

  /* 3rd Pass */
  if (stage4(tree_root, builddir) < 0)
    return EXIT_FAILURE;

  /* 4th Pass */
  /* Currently implemented in the Makefile! */

  return 0;
}