+++ /dev/null
-\r
-/* Parser generator main program */\r
-\r
-/* This expects a filename containing the grammar as argv[1] (UNIX)\r
- or asks the console for such a file name (THINK C).\r
- It writes its output on two files in the current directory:\r
- - "graminit.c" gets the grammar as a bunch of initialized data\r
- - "graminit.h" gets the grammar's non-terminals as #defines.\r
- Error messages and status info during the generation process are\r
- written to stdout, or sometimes to stderr. */\r
-\r
-/* XXX TO DO:\r
- - check for duplicate definitions of names (instead of fatal err)\r
-*/\r
-\r
-#include "Python.h"\r
-#include "pgenheaders.h"\r
-#include "grammar.h"\r
-#include "node.h"\r
-#include "parsetok.h"\r
-#include "pgen.h"\r
-\r
-int Py_DebugFlag;\r
-int Py_VerboseFlag;\r
-int Py_IgnoreEnvironmentFlag;\r
-\r
-/* Forward */\r
-grammar *getgrammar(char *filename);\r
-\r
-void\r
-Py_Exit(int sts)\r
-{\r
- exit(sts);\r
-}\r
-\r
-int\r
-main(int argc, char **argv)\r
-{\r
- grammar *g;\r
- FILE *fp;\r
- char *filename, *graminit_h, *graminit_c;\r
-\r
- if (argc != 4) {\r
- fprintf(stderr,\r
- "usage: %s grammar graminit.h graminit.c\n", argv[0]);\r
- Py_Exit(2);\r
- }\r
- filename = argv[1];\r
- graminit_h = argv[2];\r
- graminit_c = argv[3];\r
- g = getgrammar(filename);\r
- fp = fopen(graminit_c, "w");\r
- if (fp == NULL) {\r
- perror(graminit_c);\r
- Py_Exit(1);\r
- }\r
- if (Py_DebugFlag)\r
- printf("Writing %s ...\n", graminit_c);\r
- printgrammar(g, fp);\r
- fclose(fp);\r
- fp = fopen(graminit_h, "w");\r
- if (fp == NULL) {\r
- perror(graminit_h);\r
- Py_Exit(1);\r
- }\r
- if (Py_DebugFlag)\r
- printf("Writing %s ...\n", graminit_h);\r
- printnonterminals(g, fp);\r
- fclose(fp);\r
- Py_Exit(0);\r
- return 0; /* Make gcc -Wall happy */\r
-}\r
-\r
-grammar *\r
-getgrammar(char *filename)\r
-{\r
- FILE *fp;\r
- node *n;\r
- grammar *g0, *g;\r
- perrdetail err;\r
-\r
- fp = fopen(filename, "r");\r
- if (fp == NULL) {\r
- perror(filename);\r
- Py_Exit(1);\r
- }\r
- g0 = meta_grammar();\r
- n = PyParser_ParseFile(fp, filename, g0, g0->g_start,\r
- (char *)NULL, (char *)NULL, &err);\r
- fclose(fp);\r
- if (n == NULL) {\r
- fprintf(stderr, "Parsing error %d, line %d.\n",\r
- err.error, err.lineno);\r
- if (err.text != NULL) {\r
- size_t i;\r
- fprintf(stderr, "%s", err.text);\r
- i = strlen(err.text);\r
- if (i == 0 || err.text[i-1] != '\n')\r
- fprintf(stderr, "\n");\r
- for (i = 0; i < err.offset; i++) {\r
- if (err.text[i] == '\t')\r
- putc('\t', stderr);\r
- else\r
- putc(' ', stderr);\r
- }\r
- fprintf(stderr, "^\n");\r
- PyObject_FREE(err.text);\r
- }\r
- Py_Exit(1);\r
- }\r
- g = pgen(n);\r
- if (g == NULL) {\r
- printf("Bad grammar.\n");\r
- Py_Exit(1);\r
- }\r
- return g;\r
-}\r
-\r
-/* Can't happen in pgen */\r
-PyObject*\r
-PyErr_Occurred()\r
-{\r
- return 0;\r
-}\r
-\r
-void\r
-Py_FatalError(const char *msg)\r
-{\r
- fprintf(stderr, "pgen: FATAL ERROR: %s\n", msg);\r
- Py_Exit(1);\r
-}\r
-\r
-/* No-nonsense my_readline() for tokenizer.c */\r
-\r
-char *\r
-PyOS_Readline(FILE *sys_stdin, FILE *sys_stdout, char *prompt)\r
-{\r
- size_t n = 1000;\r
- char *p = (char *)PyMem_MALLOC(n);\r
- char *q;\r
- if (p == NULL)\r
- return NULL;\r
- fprintf(stderr, "%s", prompt);\r
- q = fgets(p, n, sys_stdin);\r
- if (q == NULL) {\r
- *p = '\0';\r
- return p;\r
- }\r
- n = strlen(p);\r
- if (n > 0 && p[n-1] != '\n')\r
- p[n-1] = '\n';\r
- return (char *)PyMem_REALLOC(p, n+1);\r
-}\r
-\r
-/* No-nonsense fgets */\r
-char *\r
-Py_UniversalNewlineFgets(char *buf, int n, FILE *stream, PyObject *fobj)\r
-{\r
- return fgets(buf, n, stream);\r
-}\r
-\r
-\r
-#include <stdarg.h>\r
-\r
-void\r
-PySys_WriteStderr(const char *format, ...)\r
-{\r
- va_list va;\r
-\r
- va_start(va, format);\r
- vfprintf(stderr, format, va);\r
- va_end(va);\r
-}\r