blob: 1d6e024ae0e3770b008afc9b5493e4182ba8cea8 [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 */
Guido van Rossum86bea461997-04-29 21:03:06 +000025static node *parsetok Py_PROTO((struct tok_state *, grammar *, int,
Guido van Rossumbd0389d1994-08-29 12:25:45 +000026 perrdetail *));
Guido van Rossum3f5da241990-12-20 15:06:42 +000027
28/* Parse input coming from a string. Return error code, print some errors. */
29
Guido van Rossumbd0389d1994-08-29 12:25:45 +000030node *
Guido van Rossum86bea461997-04-29 21:03:06 +000031PyParser_ParseString(s, g, start, err_ret)
Guido van Rossum3f5da241990-12-20 15:06:42 +000032 char *s;
33 grammar *g;
34 int start;
Guido van Rossumbd0389d1994-08-29 12:25:45 +000035 perrdetail *err_ret;
Guido van Rossum3f5da241990-12-20 15:06:42 +000036{
Guido van Rossumbd0389d1994-08-29 12:25:45 +000037 struct tok_state *tok;
38
39 err_ret->error = E_OK;
40 err_ret->filename = NULL;
41 err_ret->lineno = 0;
42 err_ret->offset = 0;
43 err_ret->text = NULL;
44
Guido van Rossum86bea461997-04-29 21:03:06 +000045 if ((tok = PyTokenizer_FromString(s)) == NULL) {
Guido van Rossumbd0389d1994-08-29 12:25:45 +000046 err_ret->error = E_NOMEM;
47 return NULL;
Guido van Rossum3f5da241990-12-20 15:06:42 +000048 }
Guido van Rossumbd0389d1994-08-29 12:25:45 +000049
Guido van Rossum89ce4541998-12-21 18:32:40 +000050 if (Py_TabcheckFlag || Py_VerboseFlag) {
51 tok->filename = "<string>";
52 tok->altwarning = (tok->filename != NULL);
53 if (Py_TabcheckFlag >= 2)
54 tok->alterror++;
55 }
56
Guido van Rossumbd0389d1994-08-29 12:25:45 +000057 return parsetok(tok, g, start, err_ret);
Guido van Rossum3f5da241990-12-20 15:06:42 +000058}
59
60
61/* Parse input coming from a file. Return error code, print some errors. */
62
Guido van Rossumbd0389d1994-08-29 12:25:45 +000063node *
Guido van Rossum86bea461997-04-29 21:03:06 +000064PyParser_ParseFile(fp, filename, g, start, ps1, ps2, err_ret)
Guido van Rossum3f5da241990-12-20 15:06:42 +000065 FILE *fp;
66 char *filename;
67 grammar *g;
68 int start;
69 char *ps1, *ps2;
Guido van Rossumbd0389d1994-08-29 12:25:45 +000070 perrdetail *err_ret;
Guido van Rossum3f5da241990-12-20 15:06:42 +000071{
Guido van Rossumbd0389d1994-08-29 12:25:45 +000072 struct tok_state *tok;
73
74 err_ret->error = E_OK;
75 err_ret->filename = filename;
76 err_ret->lineno = 0;
77 err_ret->offset = 0;
78 err_ret->text = NULL;
79
Guido van Rossum86bea461997-04-29 21:03:06 +000080 if ((tok = PyTokenizer_FromFile(fp, ps1, ps2)) == NULL) {
Guido van Rossumbd0389d1994-08-29 12:25:45 +000081 err_ret->error = E_NOMEM;
82 return NULL;
Guido van Rossum3f5da241990-12-20 15:06:42 +000083 }
Guido van Rossum6135df61998-04-10 19:35:06 +000084 if (Py_TabcheckFlag || Py_VerboseFlag) {
85 tok->filename = filename;
86 tok->altwarning = (filename != NULL);
87 if (Py_TabcheckFlag >= 2)
88 tok->alterror++;
89 }
Guido van Rossumbd0389d1994-08-29 12:25:45 +000090
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000091
Guido van Rossumbd0389d1994-08-29 12:25:45 +000092 return parsetok(tok, g, start, err_ret);
93}
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000094
95/* Parse input coming from the given tokenizer structure.
96 Return error code. */
97
Guido van Rossumbd0389d1994-08-29 12:25:45 +000098static node *
99parsetok(tok, g, start, err_ret)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000100 struct tok_state *tok;
101 grammar *g;
102 int start;
Guido van Rossumbd0389d1994-08-29 12:25:45 +0000103 perrdetail *err_ret;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000104{
105 parser_state *ps;
Guido van Rossumbd0389d1994-08-29 12:25:45 +0000106 node *n;
Guido van Rossumd8b1d371992-03-04 16:40:44 +0000107 int started = 0;
Guido van Rossumbd0389d1994-08-29 12:25:45 +0000108
Guido van Rossum86bea461997-04-29 21:03:06 +0000109 if ((ps = PyParser_New(g, start)) == NULL) {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000110 fprintf(stderr, "no mem for new parser\n");
Guido van Rossumbd0389d1994-08-29 12:25:45 +0000111 err_ret->error = E_NOMEM;
112 return NULL;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000113 }
Guido van Rossumbd0389d1994-08-29 12:25:45 +0000114
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000115 for (;;) {
116 char *a, *b;
117 int type;
Guido van Rossum6da34342000-06-28 22:00:02 +0000118 size_t len;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000119 char *str;
Guido van Rossumbd0389d1994-08-29 12:25:45 +0000120
Guido van Rossum86bea461997-04-29 21:03:06 +0000121 type = PyTokenizer_Get(tok, &a, &b);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000122 if (type == ERRORTOKEN) {
Guido van Rossumbd0389d1994-08-29 12:25:45 +0000123 err_ret->error = tok->done;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000124 break;
125 }
Guido van Rossumd8b1d371992-03-04 16:40:44 +0000126 if (type == ENDMARKER && started) {
127 type = NEWLINE; /* Add an extra newline */
128 started = 0;
129 }
130 else
131 started = 1;
Guido van Rossumbd0389d1994-08-29 12:25:45 +0000132 len = b - a; /* XXX this may compute NULL - NULL */
Guido van Rossum86bea461997-04-29 21:03:06 +0000133 str = PyMem_NEW(char, len + 1);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000134 if (str == NULL) {
135 fprintf(stderr, "no mem for next token\n");
Guido van Rossumbd0389d1994-08-29 12:25:45 +0000136 err_ret->error = E_NOMEM;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000137 break;
138 }
Guido van Rossumbd0389d1994-08-29 12:25:45 +0000139 if (len > 0)
140 strncpy(str, a, len);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000141 str[len] = '\0';
Guido van Rossumbd0389d1994-08-29 12:25:45 +0000142 if ((err_ret->error =
Guido van Rossum86bea461997-04-29 21:03:06 +0000143 PyParser_AddToken(ps, (int)type, str,
Guido van Rossumff0ec521997-07-27 01:52:50 +0000144 tok->lineno)) != E_OK) {
145 if (err_ret->error != E_DONE)
146 PyMem_DEL(str);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000147 break;
Guido van Rossumff0ec521997-07-27 01:52:50 +0000148 }
Guido van Rossumbd0389d1994-08-29 12:25:45 +0000149 }
150
151 if (err_ret->error == E_DONE) {
152 n = ps->p_tree;
153 ps->p_tree = NULL;
154 }
155 else
156 n = NULL;
157
Guido van Rossum86bea461997-04-29 21:03:06 +0000158 PyParser_Delete(ps);
Guido van Rossumbd0389d1994-08-29 12:25:45 +0000159
160 if (n == NULL) {
161 if (tok->lineno <= 1 && tok->done == E_EOF)
162 err_ret->error = E_EOF;
163 err_ret->lineno = tok->lineno;
164 err_ret->offset = tok->cur - tok->buf;
165 if (tok->buf != NULL) {
Guido van Rossum6da34342000-06-28 22:00:02 +0000166 size_t len = tok->inp - tok->buf;
Guido van Rossumb18618d2000-05-03 23:44:39 +0000167 err_ret->text = PyMem_NEW(char, len + 1);
Guido van Rossumbd0389d1994-08-29 12:25:45 +0000168 if (err_ret->text != NULL) {
Guido van Rossumec498271995-01-20 16:59:12 +0000169 if (len > 0)
170 strncpy(err_ret->text, tok->buf, len);
Guido van Rossumbd0389d1994-08-29 12:25:45 +0000171 err_ret->text[len] = '\0';
172 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000173 }
174 }
Guido van Rossumbd0389d1994-08-29 12:25:45 +0000175
Guido van Rossum86bea461997-04-29 21:03:06 +0000176 PyTokenizer_Free(tok);
Guido van Rossumbd0389d1994-08-29 12:25:45 +0000177
178 return n;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000179}