home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / py2s152.zip / Parser / pgenmain.c < prev    next >
C/C++ Source or Header  |  1999-06-27  |  6KB  |  241 lines

  1. /***********************************************************
  2. Copyright 1991-1995 by Stichting Mathematisch Centrum, Amsterdam,
  3. The Netherlands.
  4.  
  5.                         All Rights Reserved
  6.  
  7. Permission to use, copy, modify, and distribute this software and its
  8. documentation for any purpose and without fee is hereby granted,
  9. provided that the above copyright notice appear in all copies and that
  10. both that copyright notice and this permission notice appear in
  11. supporting documentation, and that the names of Stichting Mathematisch
  12. Centrum or CWI or Corporation for National Research Initiatives or
  13. CNRI not be used in advertising or publicity pertaining to
  14. distribution of the software without specific, written prior
  15. permission.
  16.  
  17. While CWI is the initial source for this software, a modified version
  18. is made available by the Corporation for National Research Initiatives
  19. (CNRI) at the Internet address ftp://ftp.python.org.
  20.  
  21. STICHTING MATHEMATISCH CENTRUM AND CNRI DISCLAIM ALL WARRANTIES WITH
  22. REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
  23. MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH
  24. CENTRUM OR CNRI BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
  25. DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
  26. PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
  27. TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
  28. PERFORMANCE OF THIS SOFTWARE.
  29.  
  30. ******************************************************************/
  31.  
  32. /* Parser generator main program */
  33.  
  34. /* This expects a filename containing the grammar as argv[1] (UNIX)
  35.    or asks the console for such a file name (THINK C).
  36.    It writes its output on two files in the current directory:
  37.    - "graminit.c" gets the grammar as a bunch of initialized data
  38.    - "graminit.h" gets the grammar's non-terminals as #defines.
  39.    Error messages and status info during the generation process are
  40.    written to stdout, or sometimes to stderr. */
  41.  
  42. /* XXX TO DO:
  43.    - check for duplicate definitions of names (instead of fatal err)
  44. */
  45.  
  46. #include "pgenheaders.h"
  47. #include "grammar.h"
  48. #include "node.h"
  49. #include "parsetok.h"
  50. #include "pgen.h"
  51.  
  52. int Py_DebugFlag;
  53. int Py_VerboseFlag;
  54.  
  55. /* Forward */
  56. grammar *getgrammar Py_PROTO((char *filename));
  57. #ifdef THINK_C
  58. int main Py_PROTO((int, char **));
  59. char *askfile Py_PROTO((void));
  60. #endif
  61.  
  62. void
  63. Py_Exit(sts)
  64.     int sts;
  65. {
  66.     exit(sts);
  67. }
  68.  
  69. int
  70. main(argc, argv)
  71.     int argc;
  72.     char **argv;
  73. {
  74.     grammar *g;
  75.     FILE *fp;
  76.     char *filename;
  77.     
  78. #ifdef THINK_C
  79.     filename = askfile();
  80. #else
  81.     if (argc != 2) {
  82.         fprintf(stderr, "usage: %s grammar\n", argv[0]);
  83.         Py_Exit(2);
  84.     }
  85.     filename = argv[1];
  86. #endif
  87.     g = getgrammar(filename);
  88.     fp = fopen("graminit.c", "w");
  89.     if (fp == NULL) {
  90.         perror("graminit.c");
  91.         Py_Exit(1);
  92.     }
  93.     printf("Writing graminit.c ...\n");
  94.     printgrammar(g, fp);
  95.     fclose(fp);
  96.     fp = fopen("graminit.h", "w");
  97.     if (fp == NULL) {
  98.         perror("graminit.h");
  99.         Py_Exit(1);
  100.     }
  101.     printf("Writing graminit.h ...\n");
  102.     printnonterminals(g, fp);
  103.     fclose(fp);
  104.     Py_Exit(0);
  105.     return 0; /* Make gcc -Wall happy */
  106. }
  107.  
  108. grammar *
  109. getgrammar(filename)
  110.     char *filename;
  111. {
  112.     FILE *fp;
  113.     node *n;
  114.     grammar *g0, *g;
  115.     perrdetail err;
  116.     
  117.     fp = fopen(filename, "r");
  118.     if (fp == NULL) {
  119.         perror(filename);
  120.         Py_Exit(1);
  121.     }
  122.     g0 = meta_grammar();
  123.     n = PyParser_ParseFile(fp, filename, g0, g0->g_start,
  124.               (char *)NULL, (char *)NULL, &err);
  125.     fclose(fp);
  126.     if (n == NULL) {
  127.         fprintf(stderr, "Parsing error %d, line %d.\n",
  128.             err.error, err.lineno);
  129.         if (err.text != NULL) {
  130.             int i;
  131.             fprintf(stderr, "%s", err.text);
  132.             i = strlen(err.text);
  133.             if (i == 0 || err.text[i-1] != '\n')
  134.                 fprintf(stderr, "\n");
  135.             for (i = 0; i < err.offset; i++) {
  136.                 if (err.text[i] == '\t')
  137.                     putc('\t', stderr);
  138.                 else
  139.                     putc(' ', stderr);
  140.             }
  141.             fprintf(stderr, "^\n");
  142.             free(err.text);
  143.         }
  144.         Py_Exit(1);
  145.     }
  146.     g = pgen(n);
  147.     if (g == NULL) {
  148.         printf("Bad grammar.\n");
  149.         Py_Exit(1);
  150.     }
  151.     return g;
  152. }
  153.  
  154. #ifdef THINK_C
  155. char *
  156. askfile()
  157. {
  158.     char buf[256];
  159.     static char name[256];
  160.     printf("Input file name: ");
  161.     if (fgets(buf, sizeof buf, stdin) == NULL) {
  162.         printf("EOF\n");
  163.         Py_Exit(1);
  164.     }
  165.     /* XXX The (unsigned char *) case is needed by THINK C 3.0 */
  166.     if (sscanf(/*(unsigned char *)*/buf, " %s ", name) != 1) {
  167.         printf("No file\n");
  168.         Py_Exit(1);
  169.     }
  170.     return name;
  171. }
  172. #endif
  173.  
  174. void
  175. Py_FatalError(msg)
  176.     char *msg;
  177. {
  178.     fprintf(stderr, "pgen: FATAL ERROR: %s\n", msg);
  179.     Py_Exit(1);
  180. }
  181.  
  182. #ifdef macintosh
  183. /* ARGSUSED */
  184. int
  185. guesstabsize(path)
  186.     char *path;
  187. {
  188.     return 4;
  189. }
  190. #endif
  191.  
  192. /* No-nonsense my_readline() for tokenizer.c */
  193.  
  194. char *
  195. PyOS_Readline(prompt)
  196.     char *prompt;
  197. {
  198.     int n = 1000;
  199.     char *p = malloc(n);
  200.     char *q;
  201.     if (p == NULL)
  202.         return NULL;
  203.     fprintf(stderr, "%s", prompt);
  204.     q = fgets(p, n, stdin);
  205.     if (q == NULL) {
  206.         *p = '\0';
  207.         return p;
  208.     }
  209.     n = strlen(p);
  210.     if (n > 0 && p[n-1] != '\n')
  211.         p[n-1] = '\n';
  212.     return realloc(p, n+1);
  213. }
  214.  
  215. #ifdef HAVE_STDARG_PROTOTYPES
  216. #include <stdarg.h>
  217. #else
  218. #include <varargs.h>
  219. #endif
  220.  
  221. void
  222. #ifdef HAVE_STDARG_PROTOTYPES
  223. PySys_WriteStderr(const char *format, ...)
  224. #else
  225. PySys_WriteStderr(va_alist)
  226.     va_dcl
  227. #endif
  228. {
  229.     va_list va;
  230.  
  231. #ifdef HAVE_STDARG_PROTOTYPES
  232.     va_start(va, format);
  233. #else
  234.     char *format;
  235.     va_start(va);
  236.     format = va_arg(va, char *);
  237. #endif
  238.     vfprintf(stderr, format, va);
  239.     va_end(va);
  240. }
  241.