blob: b68fbd701a1ca0870b08b49e8559d95c3281fe26 [file] [log] [blame]
Guido van Rossumf70e43a1991-02-19 12:39:46 +00001
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002/* Parser-tokenizer link implementation */
3
Guido van Rossum3f5da241990-12-20 15:06:42 +00004#include "pgenheaders.h"
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005#include "tokenizer.h"
6#include "node.h"
7#include "grammar.h"
8#include "parser.h"
Guido van Rossum3f5da241990-12-20 15:06:42 +00009#include "parsetok.h"
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000010#include "errcode.h"
11
Guido van Rossum6135df61998-04-10 19:35:06 +000012int Py_TabcheckFlag;
13
Guido van Rossum3f5da241990-12-20 15:06:42 +000014
15/* Forward */
Tim Petersdbd9ba62000-07-09 03:09:57 +000016static node *parsetok(struct tok_state *, grammar *, int, perrdetail *);
Guido van Rossum3f5da241990-12-20 15:06:42 +000017
18/* Parse input coming from a string. Return error code, print some errors. */
19
Guido van Rossumbd0389d1994-08-29 12:25:45 +000020node *
Thomas Wouters23c9e002000-07-22 19:20:54 +000021PyParser_ParseString(char *s, grammar *g, int start, perrdetail *err_ret)
Guido van Rossum3f5da241990-12-20 15:06:42 +000022{
Guido van Rossumbd0389d1994-08-29 12:25:45 +000023 struct tok_state *tok;
24
25 err_ret->error = E_OK;
26 err_ret->filename = NULL;
27 err_ret->lineno = 0;
28 err_ret->offset = 0;
29 err_ret->text = NULL;
Barry Warsaw38aa14a2000-08-18 05:04:08 +000030 err_ret->token = -1;
31 err_ret->expected = -1;
Guido van Rossumbd0389d1994-08-29 12:25:45 +000032
Guido van Rossum86bea461997-04-29 21:03:06 +000033 if ((tok = PyTokenizer_FromString(s)) == NULL) {
Guido van Rossumbd0389d1994-08-29 12:25:45 +000034 err_ret->error = E_NOMEM;
35 return NULL;
Guido van Rossum3f5da241990-12-20 15:06:42 +000036 }
Guido van Rossumbd0389d1994-08-29 12:25:45 +000037
Guido van Rossum89ce4541998-12-21 18:32:40 +000038 if (Py_TabcheckFlag || Py_VerboseFlag) {
39 tok->filename = "<string>";
40 tok->altwarning = (tok->filename != NULL);
41 if (Py_TabcheckFlag >= 2)
42 tok->alterror++;
43 }
44
Guido van Rossumbd0389d1994-08-29 12:25:45 +000045 return parsetok(tok, g, start, err_ret);
Guido van Rossum3f5da241990-12-20 15:06:42 +000046}
47
48
49/* Parse input coming from a file. Return error code, print some errors. */
50
Guido van Rossumbd0389d1994-08-29 12:25:45 +000051node *
Thomas Wouters23c9e002000-07-22 19:20:54 +000052PyParser_ParseFile(FILE *fp, char *filename, grammar *g, int start,
53 char *ps1, char *ps2, perrdetail *err_ret)
Guido van Rossum3f5da241990-12-20 15:06:42 +000054{
Guido van Rossumbd0389d1994-08-29 12:25:45 +000055 struct tok_state *tok;
56
57 err_ret->error = E_OK;
58 err_ret->filename = filename;
59 err_ret->lineno = 0;
60 err_ret->offset = 0;
61 err_ret->text = NULL;
62
Guido van Rossum86bea461997-04-29 21:03:06 +000063 if ((tok = PyTokenizer_FromFile(fp, ps1, ps2)) == NULL) {
Guido van Rossumbd0389d1994-08-29 12:25:45 +000064 err_ret->error = E_NOMEM;
65 return NULL;
Guido van Rossum3f5da241990-12-20 15:06:42 +000066 }
Guido van Rossum6135df61998-04-10 19:35:06 +000067 if (Py_TabcheckFlag || Py_VerboseFlag) {
68 tok->filename = filename;
69 tok->altwarning = (filename != NULL);
70 if (Py_TabcheckFlag >= 2)
71 tok->alterror++;
72 }
Guido van Rossumbd0389d1994-08-29 12:25:45 +000073
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000074
Guido van Rossumbd0389d1994-08-29 12:25:45 +000075 return parsetok(tok, g, start, err_ret);
76}
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000077
78/* Parse input coming from the given tokenizer structure.
79 Return error code. */
80
Guido van Rossumbd0389d1994-08-29 12:25:45 +000081static node *
Thomas Wouters23c9e002000-07-22 19:20:54 +000082parsetok(struct tok_state *tok, grammar *g, int start, perrdetail *err_ret)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000083{
84 parser_state *ps;
Guido van Rossumbd0389d1994-08-29 12:25:45 +000085 node *n;
Guido van Rossumd8b1d371992-03-04 16:40:44 +000086 int started = 0;
Guido van Rossumbd0389d1994-08-29 12:25:45 +000087
Guido van Rossum86bea461997-04-29 21:03:06 +000088 if ((ps = PyParser_New(g, start)) == NULL) {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000089 fprintf(stderr, "no mem for new parser\n");
Guido van Rossumbd0389d1994-08-29 12:25:45 +000090 err_ret->error = E_NOMEM;
91 return NULL;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000092 }
Guido van Rossumbd0389d1994-08-29 12:25:45 +000093
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000094 for (;;) {
95 char *a, *b;
96 int type;
Guido van Rossum6da34342000-06-28 22:00:02 +000097 size_t len;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000098 char *str;
Guido van Rossumbd0389d1994-08-29 12:25:45 +000099
Guido van Rossum86bea461997-04-29 21:03:06 +0000100 type = PyTokenizer_Get(tok, &a, &b);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000101 if (type == ERRORTOKEN) {
Guido van Rossumbd0389d1994-08-29 12:25:45 +0000102 err_ret->error = tok->done;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000103 break;
104 }
Guido van Rossumd8b1d371992-03-04 16:40:44 +0000105 if (type == ENDMARKER && started) {
106 type = NEWLINE; /* Add an extra newline */
107 started = 0;
108 }
109 else
110 started = 1;
Guido van Rossumbd0389d1994-08-29 12:25:45 +0000111 len = b - a; /* XXX this may compute NULL - NULL */
Guido van Rossum86bea461997-04-29 21:03:06 +0000112 str = PyMem_NEW(char, len + 1);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000113 if (str == NULL) {
114 fprintf(stderr, "no mem for next token\n");
Guido van Rossumbd0389d1994-08-29 12:25:45 +0000115 err_ret->error = E_NOMEM;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000116 break;
117 }
Guido van Rossumbd0389d1994-08-29 12:25:45 +0000118 if (len > 0)
119 strncpy(str, a, len);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000120 str[len] = '\0';
Guido van Rossumbd0389d1994-08-29 12:25:45 +0000121 if ((err_ret->error =
Fred Drake85f36392000-07-11 17:53:00 +0000122 PyParser_AddToken(ps, (int)type, str, tok->lineno,
123 &(err_ret->expected))) != E_OK) {
Guido van Rossumff0ec521997-07-27 01:52:50 +0000124 if (err_ret->error != E_DONE)
125 PyMem_DEL(str);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000126 break;
Guido van Rossumff0ec521997-07-27 01:52:50 +0000127 }
Guido van Rossumbd0389d1994-08-29 12:25:45 +0000128 }
129
130 if (err_ret->error == E_DONE) {
131 n = ps->p_tree;
132 ps->p_tree = NULL;
133 }
134 else
135 n = NULL;
136
Guido van Rossum86bea461997-04-29 21:03:06 +0000137 PyParser_Delete(ps);
Guido van Rossumbd0389d1994-08-29 12:25:45 +0000138
139 if (n == NULL) {
140 if (tok->lineno <= 1 && tok->done == E_EOF)
141 err_ret->error = E_EOF;
142 err_ret->lineno = tok->lineno;
143 err_ret->offset = tok->cur - tok->buf;
144 if (tok->buf != NULL) {
Guido van Rossum6da34342000-06-28 22:00:02 +0000145 size_t len = tok->inp - tok->buf;
Guido van Rossumb18618d2000-05-03 23:44:39 +0000146 err_ret->text = PyMem_NEW(char, len + 1);
Guido van Rossumbd0389d1994-08-29 12:25:45 +0000147 if (err_ret->text != NULL) {
Guido van Rossumec498271995-01-20 16:59:12 +0000148 if (len > 0)
149 strncpy(err_ret->text, tok->buf, len);
Guido van Rossumbd0389d1994-08-29 12:25:45 +0000150 err_ret->text[len] = '\0';
151 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000152 }
153 }
Guido van Rossumbd0389d1994-08-29 12:25:45 +0000154
Guido van Rossum86bea461997-04-29 21:03:06 +0000155 PyTokenizer_Free(tok);
Guido van Rossumbd0389d1994-08-29 12:25:45 +0000156
157 return n;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000158}