blob: 5f51f6adbdb6e95828caa292cab409433633723f [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 *
Thomas Wouters23c9e002000-07-22 19:20:54 +000030PyParser_ParseString(char *s, grammar *g, int start, perrdetail *err_ret)
Guido van Rossum3f5da241990-12-20 15:06:42 +000031{
Guido van Rossumbd0389d1994-08-29 12:25:45 +000032 struct tok_state *tok;
33
34 err_ret->error = E_OK;
35 err_ret->filename = NULL;
36 err_ret->lineno = 0;
37 err_ret->offset = 0;
38 err_ret->text = NULL;
Barry Warsaw38aa14a2000-08-18 05:04:08 +000039 err_ret->token = -1;
40 err_ret->expected = -1;
Guido van Rossumbd0389d1994-08-29 12:25:45 +000041
Guido van Rossum86bea461997-04-29 21:03:06 +000042 if ((tok = PyTokenizer_FromString(s)) == NULL) {
Guido van Rossumbd0389d1994-08-29 12:25:45 +000043 err_ret->error = E_NOMEM;
44 return NULL;
Guido van Rossum3f5da241990-12-20 15:06:42 +000045 }
Guido van Rossumbd0389d1994-08-29 12:25:45 +000046
Guido van Rossum89ce4541998-12-21 18:32:40 +000047 if (Py_TabcheckFlag || Py_VerboseFlag) {
48 tok->filename = "<string>";
49 tok->altwarning = (tok->filename != NULL);
50 if (Py_TabcheckFlag >= 2)
51 tok->alterror++;
52 }
53
Guido van Rossumbd0389d1994-08-29 12:25:45 +000054 return parsetok(tok, g, start, err_ret);
Guido van Rossum3f5da241990-12-20 15:06:42 +000055}
56
57
58/* Parse input coming from a file. Return error code, print some errors. */
59
Guido van Rossumbd0389d1994-08-29 12:25:45 +000060node *
Thomas Wouters23c9e002000-07-22 19:20:54 +000061PyParser_ParseFile(FILE *fp, char *filename, grammar *g, int start,
62 char *ps1, char *ps2, perrdetail *err_ret)
Guido van Rossum3f5da241990-12-20 15:06:42 +000063{
Guido van Rossumbd0389d1994-08-29 12:25:45 +000064 struct tok_state *tok;
65
66 err_ret->error = E_OK;
67 err_ret->filename = filename;
68 err_ret->lineno = 0;
69 err_ret->offset = 0;
70 err_ret->text = NULL;
71
Guido van Rossum86bea461997-04-29 21:03:06 +000072 if ((tok = PyTokenizer_FromFile(fp, ps1, ps2)) == NULL) {
Guido van Rossumbd0389d1994-08-29 12:25:45 +000073 err_ret->error = E_NOMEM;
74 return NULL;
Guido van Rossum3f5da241990-12-20 15:06:42 +000075 }
Guido van Rossum6135df61998-04-10 19:35:06 +000076 if (Py_TabcheckFlag || Py_VerboseFlag) {
77 tok->filename = filename;
78 tok->altwarning = (filename != NULL);
79 if (Py_TabcheckFlag >= 2)
80 tok->alterror++;
81 }
Guido van Rossumbd0389d1994-08-29 12:25:45 +000082
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000083
Guido van Rossumbd0389d1994-08-29 12:25:45 +000084 return parsetok(tok, g, start, err_ret);
85}
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000086
87/* Parse input coming from the given tokenizer structure.
88 Return error code. */
89
Guido van Rossumbd0389d1994-08-29 12:25:45 +000090static node *
Thomas Wouters23c9e002000-07-22 19:20:54 +000091parsetok(struct tok_state *tok, grammar *g, int start, perrdetail *err_ret)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000092{
93 parser_state *ps;
Guido van Rossumbd0389d1994-08-29 12:25:45 +000094 node *n;
Guido van Rossumd8b1d371992-03-04 16:40:44 +000095 int started = 0;
Guido van Rossumbd0389d1994-08-29 12:25:45 +000096
Guido van Rossum86bea461997-04-29 21:03:06 +000097 if ((ps = PyParser_New(g, start)) == NULL) {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000098 fprintf(stderr, "no mem for new parser\n");
Guido van Rossumbd0389d1994-08-29 12:25:45 +000099 err_ret->error = E_NOMEM;
100 return NULL;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000101 }
Guido van Rossumbd0389d1994-08-29 12:25:45 +0000102
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000103 for (;;) {
104 char *a, *b;
105 int type;
Guido van Rossum6da34342000-06-28 22:00:02 +0000106 size_t len;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000107 char *str;
Guido van Rossumbd0389d1994-08-29 12:25:45 +0000108
Guido van Rossum86bea461997-04-29 21:03:06 +0000109 type = PyTokenizer_Get(tok, &a, &b);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000110 if (type == ERRORTOKEN) {
Guido van Rossumbd0389d1994-08-29 12:25:45 +0000111 err_ret->error = tok->done;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000112 break;
113 }
Guido van Rossumd8b1d371992-03-04 16:40:44 +0000114 if (type == ENDMARKER && started) {
115 type = NEWLINE; /* Add an extra newline */
116 started = 0;
117 }
118 else
119 started = 1;
Guido van Rossumbd0389d1994-08-29 12:25:45 +0000120 len = b - a; /* XXX this may compute NULL - NULL */
Guido van Rossum86bea461997-04-29 21:03:06 +0000121 str = PyMem_NEW(char, len + 1);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000122 if (str == NULL) {
123 fprintf(stderr, "no mem for next token\n");
Guido van Rossumbd0389d1994-08-29 12:25:45 +0000124 err_ret->error = E_NOMEM;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000125 break;
126 }
Guido van Rossumbd0389d1994-08-29 12:25:45 +0000127 if (len > 0)
128 strncpy(str, a, len);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000129 str[len] = '\0';
Guido van Rossumbd0389d1994-08-29 12:25:45 +0000130 if ((err_ret->error =
Fred Drake85f36392000-07-11 17:53:00 +0000131 PyParser_AddToken(ps, (int)type, str, tok->lineno,
132 &(err_ret->expected))) != E_OK) {
Guido van Rossumff0ec521997-07-27 01:52:50 +0000133 if (err_ret->error != E_DONE)
134 PyMem_DEL(str);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000135 break;
Guido van Rossumff0ec521997-07-27 01:52:50 +0000136 }
Guido van Rossumbd0389d1994-08-29 12:25:45 +0000137 }
138
139 if (err_ret->error == E_DONE) {
140 n = ps->p_tree;
141 ps->p_tree = NULL;
142 }
143 else
144 n = NULL;
145
Guido van Rossum86bea461997-04-29 21:03:06 +0000146 PyParser_Delete(ps);
Guido van Rossumbd0389d1994-08-29 12:25:45 +0000147
148 if (n == NULL) {
149 if (tok->lineno <= 1 && tok->done == E_EOF)
150 err_ret->error = E_EOF;
151 err_ret->lineno = tok->lineno;
152 err_ret->offset = tok->cur - tok->buf;
153 if (tok->buf != NULL) {
Guido van Rossum6da34342000-06-28 22:00:02 +0000154 size_t len = tok->inp - tok->buf;
Guido van Rossumb18618d2000-05-03 23:44:39 +0000155 err_ret->text = PyMem_NEW(char, len + 1);
Guido van Rossumbd0389d1994-08-29 12:25:45 +0000156 if (err_ret->text != NULL) {
Guido van Rossumec498271995-01-20 16:59:12 +0000157 if (len > 0)
158 strncpy(err_ret->text, tok->buf, len);
Guido van Rossumbd0389d1994-08-29 12:25:45 +0000159 err_ret->text[len] = '\0';
160 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000161 }
162 }
Guido van Rossumbd0389d1994-08-29 12:25:45 +0000163
Guido van Rossum86bea461997-04-29 21:03:06 +0000164 PyTokenizer_Free(tok);
Guido van Rossumbd0389d1994-08-29 12:25:45 +0000165
166 return n;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000167}