blob: 9d090f1af9f2f9b98e155f51f2c9098d1ea494ce [file] [log] [blame]
Guido van Rossumf70e43a1991-02-19 12:39:46 +00001/***********************************************************
Guido van Rossumfd71b9e2000-06-30 23:50:40 +00002Copyright (c) 2000, BeOpen.com.
3Copyright (c) 1995-2000, Corporation for National Research Initiatives.
4Copyright (c) 1990-1995, Stichting Mathematisch Centrum.
5All rights reserved.
Guido van Rossumf70e43a1991-02-19 12:39:46 +00006
Guido van Rossumfd71b9e2000-06-30 23:50:40 +00007See the file "Misc/COPYRIGHT" for information on usage and
8redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES.
Guido van Rossumf70e43a1991-02-19 12:39:46 +00009******************************************************************/
10
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000011/* Parser-tokenizer link implementation */
12
Guido van Rossum3f5da241990-12-20 15:06:42 +000013#include "pgenheaders.h"
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000014#include "tokenizer.h"
15#include "node.h"
16#include "grammar.h"
17#include "parser.h"
Guido van Rossum3f5da241990-12-20 15:06:42 +000018#include "parsetok.h"
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000019#include "errcode.h"
20
Guido van Rossum6135df61998-04-10 19:35:06 +000021int Py_TabcheckFlag;
22
Guido van Rossum3f5da241990-12-20 15:06:42 +000023
24/* Forward */
Tim Petersdbd9ba62000-07-09 03:09:57 +000025static node *parsetok(struct tok_state *, grammar *, int, perrdetail *);
Guido van Rossum3f5da241990-12-20 15:06:42 +000026
27/* Parse input coming from a string. Return error code, print some errors. */
28
Guido van Rossumbd0389d1994-08-29 12:25:45 +000029node *
Guido van Rossum86bea461997-04-29 21:03:06 +000030PyParser_ParseString(s, g, start, err_ret)
Guido van Rossum3f5da241990-12-20 15:06:42 +000031 char *s;
32 grammar *g;
33 int start;
Guido van Rossumbd0389d1994-08-29 12:25:45 +000034 perrdetail *err_ret;
Guido van Rossum3f5da241990-12-20 15:06:42 +000035{
Guido van Rossumbd0389d1994-08-29 12:25:45 +000036 struct tok_state *tok;
37
38 err_ret->error = E_OK;
39 err_ret->filename = NULL;
40 err_ret->lineno = 0;
41 err_ret->offset = 0;
42 err_ret->text = NULL;
43
Guido van Rossum86bea461997-04-29 21:03:06 +000044 if ((tok = PyTokenizer_FromString(s)) == NULL) {
Guido van Rossumbd0389d1994-08-29 12:25:45 +000045 err_ret->error = E_NOMEM;
46 return NULL;
Guido van Rossum3f5da241990-12-20 15:06:42 +000047 }
Guido van Rossumbd0389d1994-08-29 12:25:45 +000048
Guido van Rossum89ce4541998-12-21 18:32:40 +000049 if (Py_TabcheckFlag || Py_VerboseFlag) {
50 tok->filename = "<string>";
51 tok->altwarning = (tok->filename != NULL);
52 if (Py_TabcheckFlag >= 2)
53 tok->alterror++;
54 }
55
Guido van Rossumbd0389d1994-08-29 12:25:45 +000056 return parsetok(tok, g, start, err_ret);
Guido van Rossum3f5da241990-12-20 15:06:42 +000057}
58
59
60/* Parse input coming from a file. Return error code, print some errors. */
61
Guido van Rossumbd0389d1994-08-29 12:25:45 +000062node *
Guido van Rossum86bea461997-04-29 21:03:06 +000063PyParser_ParseFile(fp, filename, g, start, ps1, ps2, err_ret)
Guido van Rossum3f5da241990-12-20 15:06:42 +000064 FILE *fp;
65 char *filename;
66 grammar *g;
67 int start;
68 char *ps1, *ps2;
Guido van Rossumbd0389d1994-08-29 12:25:45 +000069 perrdetail *err_ret;
Guido van Rossum3f5da241990-12-20 15:06:42 +000070{
Guido van Rossumbd0389d1994-08-29 12:25:45 +000071 struct tok_state *tok;
72
73 err_ret->error = E_OK;
74 err_ret->filename = filename;
75 err_ret->lineno = 0;
76 err_ret->offset = 0;
77 err_ret->text = NULL;
78
Guido van Rossum86bea461997-04-29 21:03:06 +000079 if ((tok = PyTokenizer_FromFile(fp, ps1, ps2)) == NULL) {
Guido van Rossumbd0389d1994-08-29 12:25:45 +000080 err_ret->error = E_NOMEM;
81 return NULL;
Guido van Rossum3f5da241990-12-20 15:06:42 +000082 }
Guido van Rossum6135df61998-04-10 19:35:06 +000083 if (Py_TabcheckFlag || Py_VerboseFlag) {
84 tok->filename = filename;
85 tok->altwarning = (filename != NULL);
86 if (Py_TabcheckFlag >= 2)
87 tok->alterror++;
88 }
Guido van Rossumbd0389d1994-08-29 12:25:45 +000089
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000090
Guido van Rossumbd0389d1994-08-29 12:25:45 +000091 return parsetok(tok, g, start, err_ret);
92}
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000093
94/* Parse input coming from the given tokenizer structure.
95 Return error code. */
96
Guido van Rossumbd0389d1994-08-29 12:25:45 +000097static node *
98parsetok(tok, g, start, err_ret)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000099 struct tok_state *tok;
100 grammar *g;
101 int start;
Guido van Rossumbd0389d1994-08-29 12:25:45 +0000102 perrdetail *err_ret;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000103{
104 parser_state *ps;
Guido van Rossumbd0389d1994-08-29 12:25:45 +0000105 node *n;
Guido van Rossumd8b1d371992-03-04 16:40:44 +0000106 int started = 0;
Guido van Rossumbd0389d1994-08-29 12:25:45 +0000107
Guido van Rossum86bea461997-04-29 21:03:06 +0000108 if ((ps = PyParser_New(g, start)) == NULL) {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000109 fprintf(stderr, "no mem for new parser\n");
Guido van Rossumbd0389d1994-08-29 12:25:45 +0000110 err_ret->error = E_NOMEM;
111 return NULL;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000112 }
Guido van Rossumbd0389d1994-08-29 12:25:45 +0000113
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000114 for (;;) {
115 char *a, *b;
116 int type;
Guido van Rossum6da34342000-06-28 22:00:02 +0000117 size_t len;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000118 char *str;
Guido van Rossumbd0389d1994-08-29 12:25:45 +0000119
Guido van Rossum86bea461997-04-29 21:03:06 +0000120 type = PyTokenizer_Get(tok, &a, &b);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000121 if (type == ERRORTOKEN) {
Guido van Rossumbd0389d1994-08-29 12:25:45 +0000122 err_ret->error = tok->done;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000123 break;
124 }
Guido van Rossumd8b1d371992-03-04 16:40:44 +0000125 if (type == ENDMARKER && started) {
126 type = NEWLINE; /* Add an extra newline */
127 started = 0;
128 }
129 else
130 started = 1;
Guido van Rossumbd0389d1994-08-29 12:25:45 +0000131 len = b - a; /* XXX this may compute NULL - NULL */
Guido van Rossum86bea461997-04-29 21:03:06 +0000132 str = PyMem_NEW(char, len + 1);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000133 if (str == NULL) {
134 fprintf(stderr, "no mem for next token\n");
Guido van Rossumbd0389d1994-08-29 12:25:45 +0000135 err_ret->error = E_NOMEM;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000136 break;
137 }
Guido van Rossumbd0389d1994-08-29 12:25:45 +0000138 if (len > 0)
139 strncpy(str, a, len);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000140 str[len] = '\0';
Guido van Rossumbd0389d1994-08-29 12:25:45 +0000141 if ((err_ret->error =
Fred Drake85f36392000-07-11 17:53:00 +0000142 PyParser_AddToken(ps, (int)type, str, tok->lineno,
143 &(err_ret->expected))) != E_OK) {
Guido van Rossumff0ec521997-07-27 01:52:50 +0000144 if (err_ret->error != E_DONE)
145 PyMem_DEL(str);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000146 break;
Guido van Rossumff0ec521997-07-27 01:52:50 +0000147 }
Guido van Rossumbd0389d1994-08-29 12:25:45 +0000148 }
149
150 if (err_ret->error == E_DONE) {
151 n = ps->p_tree;
152 ps->p_tree = NULL;
153 }
154 else
155 n = NULL;
156
Guido van Rossum86bea461997-04-29 21:03:06 +0000157 PyParser_Delete(ps);
Guido van Rossumbd0389d1994-08-29 12:25:45 +0000158
159 if (n == NULL) {
160 if (tok->lineno <= 1 && tok->done == E_EOF)
161 err_ret->error = E_EOF;
162 err_ret->lineno = tok->lineno;
163 err_ret->offset = tok->cur - tok->buf;
164 if (tok->buf != NULL) {
Guido van Rossum6da34342000-06-28 22:00:02 +0000165 size_t len = tok->inp - tok->buf;
Guido van Rossumb18618d2000-05-03 23:44:39 +0000166 err_ret->text = PyMem_NEW(char, len + 1);
Guido van Rossumbd0389d1994-08-29 12:25:45 +0000167 if (err_ret->text != NULL) {
Guido van Rossumec498271995-01-20 16:59:12 +0000168 if (len > 0)
169 strncpy(err_ret->text, tok->buf, len);
Guido van Rossumbd0389d1994-08-29 12:25:45 +0000170 err_ret->text[len] = '\0';
171 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000172 }
173 }
Guido van Rossumbd0389d1994-08-29 12:25:45 +0000174
Guido van Rossum86bea461997-04-29 21:03:06 +0000175 PyTokenizer_Free(tok);
Guido van Rossumbd0389d1994-08-29 12:25:45 +0000176
177 return n;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000178}