home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 15 / AACD15.ISO / AACD / Programming / Python2 / Python20_source / Parser / pgenmain.c < prev    next >
Encoding:
C/C++ Source or Header  |  2000-10-25  |  3.4 KB  |  189 lines

  1.  
  2. /* Parser generator main program */
  3.  
  4. /* This expects a filename containing the grammar as argv[1] (UNIX)
  5.    or asks the console for such a file name (THINK C).
  6.    It writes its output on two files in the current directory:
  7.    - "graminit.c" gets the grammar as a bunch of initialized data
  8.    - "graminit.h" gets the grammar's non-terminals as #defines.
  9.    Error messages and status info during the generation process are
  10.    written to stdout, or sometimes to stderr. */
  11.  
  12. /* XXX TO DO:
  13.    - check for duplicate definitions of names (instead of fatal err)
  14. */
  15.  
  16. #include "pgenheaders.h"
  17. #include "grammar.h"
  18. #include "node.h"
  19. #include "parsetok.h"
  20. #include "pgen.h"
  21.  
  22. int Py_DebugFlag;
  23. int Py_VerboseFlag;
  24.  
  25. /* Forward */
  26. grammar *getgrammar(char *filename);
  27. #ifdef THINK_C
  28. int main(int, char **);
  29. char *askfile(void);
  30. #endif
  31.  
  32. void
  33. Py_Exit(int sts)
  34. {
  35.     exit(sts);
  36. }
  37.  
  38. int
  39. main(int argc, char **argv)
  40. {
  41.     grammar *g;
  42.     FILE *fp;
  43.     char *filename;
  44.     
  45. #ifdef THINK_C
  46.     filename = askfile();
  47. #else
  48.     if (argc != 2) {
  49.         fprintf(stderr, "usage: %s grammar\n", argv[0]);
  50.         Py_Exit(2);
  51.     }
  52.     filename = argv[1];
  53. #endif
  54.     g = getgrammar(filename);
  55.     fp = fopen("graminit.c", "w");
  56.     if (fp == NULL) {
  57.         perror("graminit.c");
  58.         Py_Exit(1);
  59.     }
  60.     printf("Writing graminit.c ...\n");
  61.     printgrammar(g, fp);
  62.     fclose(fp);
  63.     fp = fopen("graminit.h", "w");
  64.     if (fp == NULL) {
  65.         perror("graminit.h");
  66.         Py_Exit(1);
  67.     }
  68.     printf("Writing graminit.h ...\n");
  69.     printnonterminals(g, fp);
  70.     fclose(fp);
  71.     Py_Exit(0);
  72.     return 0; /* Make gcc -Wall happy */
  73. }
  74.  
  75. grammar *
  76. getgrammar(char *filename)
  77. {
  78.     FILE *fp;
  79.     node *n;
  80.     grammar *g0, *g;
  81.     perrdetail err;
  82.     
  83.     fp = fopen(filename, "r");
  84.     if (fp == NULL) {
  85.         perror(filename);
  86.         Py_Exit(1);
  87.     }
  88.     g0 = meta_grammar();
  89.     n = PyParser_ParseFile(fp, filename, g0, g0->g_start,
  90.               (char *)NULL, (char *)NULL, &err);
  91.     fclose(fp);
  92.     if (n == NULL) {
  93.         fprintf(stderr, "Parsing error %d, line %d.\n",
  94.             err.error, err.lineno);
  95.         if (err.text != NULL) {
  96.             size_t i;
  97.             fprintf(stderr, "%s", err.text);
  98.             i = strlen(err.text);
  99.             if (i == 0 || err.text[i-1] != '\n')
  100.                 fprintf(stderr, "\n");
  101.             for (i = 0; i < err.offset; i++) {
  102.                 if (err.text[i] == '\t')
  103.                     putc('\t', stderr);
  104.                 else
  105.                     putc(' ', stderr);
  106.             }
  107.             fprintf(stderr, "^\n");
  108.             PyMem_DEL(err.text);
  109.         }
  110.         Py_Exit(1);
  111.     }
  112.     g = pgen(n);
  113.     if (g == NULL) {
  114.         printf("Bad grammar.\n");
  115.         Py_Exit(1);
  116.     }
  117.     return g;
  118. }
  119.  
  120. #ifdef THINK_C
  121. char *
  122. askfile(void)
  123. {
  124.     char buf[256];
  125.     static char name[256];
  126.     printf("Input file name: ");
  127.     if (fgets(buf, sizeof buf, stdin) == NULL) {
  128.         printf("EOF\n");
  129.         Py_Exit(1);
  130.     }
  131.     /* XXX The (unsigned char *) case is needed by THINK C 3.0 */
  132.     if (sscanf(/*(unsigned char *)*/buf, " %s ", name) != 1) {
  133.         printf("No file\n");
  134.         Py_Exit(1);
  135.     }
  136.     return name;
  137. }
  138. #endif
  139.  
  140. void
  141. Py_FatalError(char *msg)
  142. {
  143.     fprintf(stderr, "pgen: FATAL ERROR: %s\n", msg);
  144.     Py_Exit(1);
  145. }
  146.  
  147. #ifdef macintosh
  148. /* ARGSUSED */
  149. int
  150. guesstabsize(char *path)
  151. {
  152.     return 4;
  153. }
  154. #endif
  155.  
  156. /* No-nonsense my_readline() for tokenizer.c */
  157.  
  158. char *
  159. PyOS_Readline(char *prompt)
  160. {
  161.     size_t n = 1000;
  162.     char *p = PyMem_MALLOC(n);
  163.     char *q;
  164.     if (p == NULL)
  165.         return NULL;
  166.     fprintf(stderr, "%s", prompt);
  167.     q = fgets(p, n, stdin);
  168.     if (q == NULL) {
  169.         *p = '\0';
  170.         return p;
  171.     }
  172.     n = strlen(p);
  173.     if (n > 0 && p[n-1] != '\n')
  174.         p[n-1] = '\n';
  175.     return PyMem_REALLOC(p, n+1);
  176. }
  177.  
  178. #include <stdarg.h>
  179.  
  180. void
  181. PySys_WriteStderr(const char *format, ...)
  182. {
  183.     va_list va;
  184.  
  185.     va_start(va, format);
  186.     vfprintf(stderr, format, va);
  187.     va_end(va);
  188. }
  189.