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