18 IS (((u|U)(l|L|ll|LL)?)|((l|L|ll|LL)(u|U)?))
21 ES (\\(['"\?\\abfnrtv]|[0-7]{1,3}|x[a-fA-F0-9]+))
26 #include "structmember.h"
30 #include "yaccmodule.h"
32 PyDoc_STRVAR(lex_doc_string, \
33 "lex is an interface to a flex-generated lexical analyzer.\n");
35 /* filled in at module initialization time */
36 static PyObject *work;
37 static PyObject *work_factory;
42 /* filled in by lex.yylex.__init(), no change during iteration */
43 PyObject *root, *mark, *yychunk_iter;
45 /* filled in by YY_INPUT() each time we go on to a new chunk */
46 PyObject *YY_INPUT_bytes;
47 Py_ssize_t YY_INPUT_bytes_off, YY_INPUT_bytes_len;
50 /* filled in by lex.yylex.__next__() each time iterator invoked */
51 static lex_yylexObject *yylex_self;
52 static jmp_buf yylex_abort;
53 static Py_ssize_t yytext_pos, yytext_off, yytext_len;
55 static void yyerror(const char *); /* prints grammar violation message */
56 static bool get_cursor(lex_yylexObject *self, Py_ssize_t i, Py_ssize_t *pos, Py_ssize_t *off);
57 static bool set_cursor(lex_yylexObject *self, Py_ssize_t i, Py_ssize_t pos, Py_ssize_t off);
58 static bool new_cursor(lex_yylexObject *self, Py_ssize_t i, Py_ssize_t pos, Py_ssize_t off);
59 static bool pop_cursors(lex_yylexObject *self, Py_ssize_t i);
60 static bool apply_markup(const char *format, ...);
61 static bool next_YY_INPUT_chunk(lex_yylexObject *self);
62 static bool next_yytext_chunk(lex_yylexObject *self);
63 /*static bool skip_yytext_byte(lex_yylexObject *self, int c);*/ /* NO PROTOTYPE, IT'S A MACRO */
64 static bool skip_yytext(lex_yylexObject *self);
65 static bool skip_comment(lex_yylexObject *self);
67 #define YY_INPUT(buf, result, max_size) \
69 /*printf("YY_INPUT()\n");*/ \
70 if (yylex_self->YY_INPUT_bytes_off >= yylex_self->YY_INPUT_bytes_len && !next_YY_INPUT_chunk(yylex_self)) \
71 longjmp(yylex_abort, 1); \
72 Py_ssize_t len = yylex_self->YY_INPUT_bytes_len - yylex_self->YY_INPUT_bytes_off; \
75 /* note: don't call PyBytes_AS_STRING on Py_None (possible if len == 0) */ \
77 memcpy(buf, PyBytes_AS_STRING(yylex_self->YY_INPUT_bytes) + yylex_self->YY_INPUT_bytes_off, len); \
78 yylex_self->YY_INPUT_bytes_off += len; \
81 /*printf("YY_INPUT() returns \""); fwrite(buf, result, 1, stdout); printf("\"\n");*/ \
86 if (!skip_yytext(yylex_self)) \
93 if (!new_cursor(yylex_self, -1, yytext_pos, yytext_off)) \
100 Py_ssize_t len = PyObject_Length(yylex_self->mark); \
117 #define sym_type(self, identifier) IDENTIFIER /* with no symbol table, fake it */
121 "/*" { SKIP(); if (!skip_comment(yylex_self)) return -1; }
122 "//".* { SKIP(); /* consume //-comment */ }
124 "auto" { MARK(); SKIP(); MARK(); return AUTO; }
125 "break" { MARK(); SKIP(); MARK(); return BREAK; }
126 "case" { MARK(); SKIP(); MARK(); return CASE; }
127 "char" { MARK(); SKIP(); MARK(); return CHAR; }
128 "const" { MARK(); SKIP(); MARK(); return CONST; }
129 "continue" { MARK(); SKIP(); MARK(); return CONTINUE; }
130 "default" { MARK(); SKIP(); MARK(); return DEFAULT; }
131 "do" { MARK(); SKIP(); MARK(); return DO; }
132 "double" { MARK(); SKIP(); MARK(); return DOUBLE; }
133 "else" { MARK(); SKIP(); MARK(); return ELSE; }
134 "enum" { MARK(); SKIP(); MARK(); return ENUM; }
135 "extern" { MARK(); SKIP(); MARK(); return EXTERN; }
136 "float" { MARK(); SKIP(); MARK(); return FLOAT; }
137 "for" { MARK(); SKIP(); MARK(); return FOR; }
138 "goto" { MARK(); SKIP(); MARK(); return GOTO; }
139 "if" { MARK(); SKIP(); MARK(); return IF; }
140 "inline" { MARK(); SKIP(); MARK(); return INLINE; }
141 "int" { MARK(); SKIP(); MARK(); return INT; }
142 "long" { MARK(); SKIP(); MARK(); return LONG; }
143 "register" { MARK(); SKIP(); MARK(); return REGISTER; }
144 "restrict" { MARK(); SKIP(); MARK(); return RESTRICT; }
145 "return" { MARK(); SKIP(); MARK(); return RETURN; }
146 "short" { MARK(); SKIP(); MARK(); return SHORT; }
147 "signed" { MARK(); SKIP(); MARK(); return SIGNED; }
148 "sizeof" { MARK(); SKIP(); MARK(); return SIZEOF; }
149 "static" { MARK(); SKIP(); MARK(); return STATIC; }
150 "struct" { MARK(); SKIP(); MARK(); return STRUCT; }
151 "switch" { MARK(); SKIP(); MARK(); return SWITCH; }
152 "typedef" { MARK(); SKIP(); MARK(); return TYPEDEF; }
153 "union" { MARK(); SKIP(); MARK(); return UNION; }
154 "unsigned" { MARK(); SKIP(); MARK(); return UNSIGNED; }
155 "void" { MARK(); SKIP(); MARK(); return VOID; }
156 "volatile" { MARK(); SKIP(); MARK(); return VOLATILE; }
157 "while" { MARK(); SKIP(); MARK(); return WHILE; }
158 "_Alignas" { MARK(); SKIP(); MARK(); return ALIGNAS; }
159 "_Alignof" { MARK(); SKIP(); MARK(); return ALIGNOF; }
160 "_Atomic" { MARK(); SKIP(); MARK(); return ATOMIC; }
161 "_Bool" { MARK(); SKIP(); MARK(); return BOOL; }
162 "_Complex" { MARK(); SKIP(); MARK(); return COMPLEX; }
163 "_Generic" { MARK(); SKIP(); MARK(); return GENERIC; }
164 "_Imaginary" { MARK(); SKIP(); MARK(); return IMAGINARY; }
165 "_Noreturn" { MARK(); SKIP(); MARK(); return NORETURN; }
166 "_Static_assert" { MARK(); SKIP(); MARK(); return STATIC_ASSERT; }
167 "_Thread_local" { MARK(); SKIP(); MARK(); return THREAD_LOCAL; }
168 "__func__" { MARK(); SKIP(); MARK(); return FUNC_NAME; }
169 "size_t" { MARK(); SKIP(); MARK(); return TYPEDEF_NAME; /* THIS IS A HACK FOR NOW */ }
171 (?<Identifier>{L}{A}*) {
175 switch (sym_type(self, yytext))
177 case TYPEDEF_NAME: /* previously defined */
178 APPLY("TypedefName");
180 case ENUMERATION_CONSTANT: /* previously defined */
181 APPLY("EnumerationConstant");
182 return ENUMERATION_CONSTANT;
183 default: /* includes undefined */
189 (?<ExpressionIntLiteral>{HP}{H}+{IS}?) { MARK(); SKIP(); MARK(); APPLY("ExpressionIntLiteral"); return I_CONSTANT; }
190 (?<ExpressionIntLiteral>{NZ}{D}*{IS}?) { MARK(); SKIP(); MARK(); APPLY("ExpressionIntLiteral"); return I_CONSTANT; }
191 (?<ExpressionIntLiteral>"0"{O}*{IS}?) { MARK(); SKIP(); MARK(); APPLY("ExpressionIntLiteral"); return I_CONSTANT; }
192 (?<ExpressionIntLiteral>{CP}?"'"([^'\\\n]|{ES})+"'") { MARK(); SKIP(); MARK(); APPLY("ExpressionIntLiteral"); return I_CONSTANT; }
194 (?<ExpressionFloatLiteral>{D}+{E}{FS}?) { MARK(); SKIP(); MARK(); APPLY("ExpressionFloatLiteral"); return F_CONSTANT; }
195 (?<ExpressionFloatLiteral>{D}*"."{D}+{E}?{FS}?) { MARK(); SKIP(); MARK(); APPLY("ExpressionFloatLiteral"); return F_CONSTANT; }
196 (?<ExpressionFloatLiteral>{D}+"."{E}?{FS}?) { MARK(); SKIP(); MARK(); APPLY("ExpressionFloatLiteral"); return F_CONSTANT; }
197 (?<ExpressionFloatLiteral>{HP}{H}+{P}{FS}?) { MARK(); SKIP(); MARK(); APPLY("ExpressionFloatLiteral"); return F_CONSTANT; }
198 (?<ExpressionFloatLiteral>{HP}{H}*"."{H}+{P}{FS}?) { MARK(); SKIP(); MARK(); APPLY("ExpressionFloatLiteral"); return F_CONSTANT; }
199 (?<ExpressionFloatLiteral>{HP}{H}+"."{P}{FS}?) { MARK(); SKIP(); MARK(); APPLY("ExpressionFloatLiteral"); return F_CONSTANT; }
201 ({SP}?\"([^"\\\n]|{ES})*\"{WS}*)+ { MARK(); SKIP(); MARK(); APPLY("ExpressionStringLiteral"); return STRING_LITERAL;; }
203 "..." { MARK(); SKIP(); MARK(); return ELLIPSIS; }
204 ">>=" { MARK(); SKIP(); MARK(); return RIGHT_ASSIGN; }
205 "<<=" { MARK(); SKIP(); MARK(); return LEFT_ASSIGN; }
206 "+=" { MARK(); SKIP(); MARK(); return ADD_ASSIGN; }
207 "-=" { MARK(); SKIP(); MARK(); return SUB_ASSIGN; }
208 "*=" { MARK(); SKIP(); MARK(); return MUL_ASSIGN; }
209 "/=" { MARK(); SKIP(); MARK(); return DIV_ASSIGN; }
210 "%=" { MARK(); SKIP(); MARK(); return MOD_ASSIGN; }
211 "&=" { MARK(); SKIP(); MARK(); return AND_ASSIGN; }
212 "^=" { MARK(); SKIP(); MARK(); return XOR_ASSIGN; }
213 "|=" { MARK(); SKIP(); MARK(); return OR_ASSIGN; }
214 ">>" { MARK(); SKIP(); MARK(); return RIGHT_OP; }
215 "<<" { MARK(); SKIP(); MARK(); return LEFT_OP; }
216 "++" { MARK(); SKIP(); MARK(); return INC_OP; }
217 "--" { MARK(); SKIP(); MARK(); return DEC_OP; }
218 "->" { MARK(); SKIP(); MARK(); return PTR_OP; }
219 "&&" { MARK(); SKIP(); MARK(); return AND_OP; }
220 "||" { MARK(); SKIP(); MARK(); return OR_OP; }
221 "<=" { MARK(); SKIP(); MARK(); return LE_OP; }
222 ">=" { MARK(); SKIP(); MARK(); return GE_OP; }
223 "==" { MARK(); SKIP(); MARK(); return EQ_OP; }
224 "!=" { MARK(); SKIP(); MARK(); return NE_OP; }
225 ";" { MARK(); SKIP(); MARK(); return ';'; }
226 ("{"|"<%") { MARK(); SKIP(); MARK(); return '{'; }
227 ("}"|"%>") { MARK(); SKIP(); MARK(); return '}'; }
228 "," { MARK(); SKIP(); MARK(); return ','; }
229 ":" { MARK(); SKIP(); MARK(); return ':'; }
230 "=" { MARK(); SKIP(); MARK(); return '='; }
231 "(" { MARK(); SKIP(); MARK(); return '('; }
232 ")" { MARK(); SKIP(); MARK(); return ')'; }
233 ("["|"<:") { MARK(); SKIP(); MARK(); return '['; }
234 ("]"|":>") { MARK(); SKIP(); MARK(); return ']'; }
235 "." { MARK(); SKIP(); MARK(); return '.'; }
236 "&" { MARK(); SKIP(); MARK(); return '&'; }
237 "!" { MARK(); SKIP(); MARK(); return '!'; }
238 "~" { MARK(); SKIP(); MARK(); return '~'; }
239 "-" { MARK(); SKIP(); MARK(); return '-'; }
240 "+" { MARK(); SKIP(); MARK(); return '+'; }
241 "*" { MARK(); SKIP(); MARK(); return '*'; }
242 "/" { MARK(); SKIP(); MARK(); return '/'; }
243 "%" { MARK(); SKIP(); MARK(); return '%'; }
244 "<" { MARK(); SKIP(); MARK(); return '<'; }
245 ">" { MARK(); SKIP(); MARK(); return '>'; }
246 "^" { MARK(); SKIP(); MARK(); return '^'; }
247 "|" { MARK(); SKIP(); MARK(); return '|'; }
248 "?" { MARK(); SKIP(); MARK(); return '?'; }
250 {WS}+ { SKIP(); /* whitespace separates tokens */ }
251 . { SKIP(); /* discard bad characters */ }
252 <<EOF>> { MARK(); return 0; }
256 int yywrap(void) /* called at end of input */
258 /*printf("yywrap()\n");*/
259 return 1; /* terminate now */
262 static void yyerror(const char *s) {
264 fprintf(stderr, "*** %s\n", s);
267 static bool get_cursor(lex_yylexObject *self, Py_ssize_t i, Py_ssize_t *pos, Py_ssize_t *off) {
268 /*printf("get_cursor() %zd\n", i);*/
269 /* (pos, off) = self->mark[index] */
270 PyObject *index = PyLong_FromSsize_t(i);
273 PyObject *cursor = PyObject_GetItem(self->mark, index);
276 if (!PyArg_ParseTuple(cursor, "nn", pos, off)) {
285 /*printf("get_cursor() returns %zd %zd\n", *pos, *off);*/
289 static bool set_cursor(lex_yylexObject *self, Py_ssize_t i, Py_ssize_t pos, Py_ssize_t off) {
290 /*printf("set_cursor() %zd %zd %zd\n", i, pos, off);*/
291 /* self->mark[index] = (pos, off) */
292 PyObject *index = PyLong_FromSsize_t(i);
295 PyObject *cursor = Py_BuildValue("nn", pos, off);
298 if (PyObject_SetItem(self->mark, index, cursor)) {
310 static bool new_cursor(lex_yylexObject *self, Py_ssize_t i, Py_ssize_t pos, Py_ssize_t off) {
311 /*printf("new_cursor() %zd %zd %zd\n", i, pos, off);*/
312 /* self->mark[i:i] = [(pos, off)] */
313 PyObject *index = PyLong_FromSsize_t(i);
316 PyObject *slice = PySlice_New(index, index, NULL);
319 PyObject *list = PyList_New(1);
322 PyObject *cursor = Py_BuildValue("nn", pos, off);
325 PyList_SET_ITEM(list, 0, cursor);
326 if (PyObject_SetItem(self->mark, slice, list)) {
342 static bool pop_cursors(lex_yylexObject *self, Py_ssize_t i) {
343 /*printf("pop_cursors() %zd\n", i);*/
344 /* del self->mark[i:] */
345 PyObject *start = PyLong_FromSsize_t(i);
348 PyObject *slice = PySlice_New(start, NULL, NULL);
351 if (PyObject_DelItem(self->mark, slice)) {
363 static bool apply_markup(const char *format, ...) {
364 PyObject *apply_markup = PyObject_GetAttrString(work, "apply_markup");
365 if (apply_markup == NULL)
369 va_start(argp, format);
370 PyObject *args = Py_VaBuildValue(format, argp);
375 PyObject *result = PyObject_CallObject(apply_markup, args);
376 if (result == NULL) {
379 Py_DECREF(apply_markup);
386 Py_DECREF(apply_markup);
390 static bool next_YY_INPUT_chunk(lex_yylexObject *self) {
391 /*printf("next_YY_INPUT_chunk()\n");*/
392 /* cursor is not cached, since we'd have to re-cache every time we enter */
393 /* iterator, whereas we are only supposed to read new chunks occasionally */
394 Py_ssize_t pos, off, len;
395 if (!get_cursor(self, -1, &pos, &off))
400 /* re-check the length, as tail could have got longer in the meantime */
401 tail = PyObject_CallMethod(work, "get_tail", "On", self->root, pos);
404 len = PyObject_Length(tail);
408 /* see if now need to do more data from the same chunk */
413 /* if last chunk try to extend it, otherwise go on to next */
414 Py_ssize_t root_len = PyObject_Length(self->root);
417 if (pos + 1 >= root_len) {
418 if (self->yychunk_iter != Py_None){
419 PyObject *result = PyObject_CallMethod(self->yychunk_iter, "__next__", "");
420 if (result != NULL) {
422 continue; /* re-check current chunk, in case extended */
424 if (!PyErr_ExceptionMatches(PyExc_StopIteration))
429 /* it is not an error to run out of data, empty return indicates EOF */
431 Py_DECREF(self->YY_INPUT_bytes);
432 self->YY_INPUT_bytes = Py_None;
433 self->YY_INPUT_bytes_off = 0;
434 self->YY_INPUT_bytes_len = 0;
441 /* got something we can return, advance cursor by unicode length of data */
442 if (!set_cursor(self, -1, pos, off + len))
445 /* check for less efficient case when caller has appended to the chunk, */
446 /* requires a large copy that caller can avoid by only adding new chunks */
448 PyObject *index = PyLong_FromSsize_t(off);
451 PyObject *slice = PySlice_New(index, NULL, NULL);
454 PyObject *item = PyObject_GetItem(tail, slice);
467 /* convert entire chunk to UTF-8, then use for multiple YY_INPUT() calls */
468 PyObject *bytes = PyUnicode_AsUTF8String(tail);
471 len = PyObject_Length(bytes);
479 Py_DECREF(self->YY_INPUT_bytes);
480 self->YY_INPUT_bytes = bytes;
481 self->YY_INPUT_bytes_off = 0;
482 self->YY_INPUT_bytes_len = len;
488 static bool next_yytext_chunk(lex_yylexObject *self) {
490 /* re-cache the length, as tail could have got longer in the meantime */
491 PyObject *tail = PyObject_CallMethod(work, "get_tail", "On", self->root, yytext_pos);
494 yytext_len = PyObject_Length(tail);
495 if (yytext_len < 0) {
502 /* see if now need to do more data from the same chunk */
503 if (yytext_off < yytext_len)
506 /* go on to next chunk (note: it can't go past YY_INPUT cursor) */
513 #define skip_yytext_byte(self, c) \
515 if ((c & 0xc0) != 0x80) { \
516 /*printf("'%c' %ld %ld\n", c, yytext_off, yytext_len);*/ \
517 if (yytext_off >= yytext_len && !next_yytext_chunk(self)) \
523 static bool skip_yytext(lex_yylexObject *self) {
525 for (char *p = yytext; (c = *p) != 0; ++p)
526 skip_yytext_byte(self, c);
530 static bool skip_comment(lex_yylexObject *self) {
532 while ((c = input()) != 0) {
534 skip_yytext_byte(self, '*');
535 while ((c = input()) == '*')
536 skip_yytext_byte(self, '*');
539 skip_yytext_byte(self, '/');
546 skip_yytext_byte(self, c);
548 yyerror("unterminated comment");
552 static PyObject *lex_yylex_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) {
553 lex_yylexObject *self;
555 self = (lex_yylexObject *)type->tp_alloc(type, 0);
557 self->root = Py_None;
559 self->mark = Py_None;
561 self->yychunk_iter = Py_None;
563 self->YY_INPUT_bytes = Py_None;
564 return (PyObject *)self;
567 static void lex_yylex_dealloc(lex_yylexObject *self) {
568 Py_DECREF(self->root);
569 Py_DECREF(self->mark);
570 Py_DECREF(self->yychunk_iter);
571 Py_DECREF(self->YY_INPUT_bytes);
572 Py_TYPE(self)->tp_free((PyObject *)self);
575 static int lex_yylex_init(lex_yylexObject *self, PyObject *args, PyObject *kwargs) {
576 PyObject *root, *mark, *yychunk_iter = Py_None;
577 if (!PyArg_ParseTuple(args, "OO|O", &root, &mark, &yychunk_iter))
581 Py_DECREF(self->root);
585 Py_DECREF(self->mark);
588 if (yychunk_iter == Py_None)
591 yychunk_iter = PyObject_GetIter(yychunk_iter);
592 if (yychunk_iter == NULL)
595 Py_DECREF(self->yychunk_iter);
596 self->yychunk_iter = yychunk_iter;
598 /* mark[:] = [(-1, 0), (-1, 0)] */
599 /* the first is the yytext cursor, it will be advanced one unicode code */
600 /* point for each UTF-8 non-continuation character scanned in yytext; */
601 /* the second is the YY_INPUT cursor, it will be advanced by the chunk */
602 /* length in unicode code points each time we convert a chunk to UTF-8; */
603 /* each cursor consists of (pos, off) referring to root[pos].tail[off:], */
604 /* chunks accessed using work.get_tail(), so pos == -1 for root[pos].text */
605 if (!pop_cursors(self, 0) || !new_cursor(self, 0, -1, 0) || !new_cursor(self, 1, -1, 0)) {
607 /* don't keep useless references to user data structures after error */
609 Py_DECREF(self->root);
610 self->root = Py_None;
612 Py_DECREF(self->mark);
613 self->mark = Py_None;
615 Py_DECREF(self->yychunk_iter);
616 self->yychunk_iter = Py_None;
622 Py_DECREF(self->YY_INPUT_bytes);
623 self->YY_INPUT_bytes = Py_None;
624 self->YY_INPUT_bytes_off = 0;
625 self->YY_INPUT_bytes_len = 0;
630 static PyObject *lex_yylex_iter(PyObject *self) {
635 static PyObject *lex_yylex_iternext(lex_yylexObject *self) {
636 /*printf("lex_yylex_iternext()\n");*/
637 if (self->root == Py_None || self->mark == Py_None) {
638 PyErr_SetNone(PyExc_StopIteration);
642 /* cache yytext_pos, yytext_off, yytext_len for quickly scanning yytext */
643 if (!get_cursor(self, -2, &yytext_pos, &yytext_off))
645 PyObject *tail = PyObject_CallMethod(work, "get_tail", "On", self->root, yytext_pos);
648 yytext_len = PyObject_Length(tail);
649 if (yytext_len < 0) {
656 if (setjmp(yylex_abort))
659 (void)yyunput; /* fix defined but not used warning */
665 /* finished, automatically delete YY_INPUT cursor and drop references */
666 if (!pop_cursors(self, -1)) {
668 /* don't keep useless references to user data structures after error */
670 Py_DECREF(self->root);
671 self->root = Py_None;
673 Py_DECREF(self->mark);
674 self->mark = Py_None;
676 Py_DECREF(self->yychunk_iter);
677 self->yychunk_iter = Py_None;
681 /* don't keep useless references to user data structures after EOF */
683 Py_DECREF(self->root);
684 self->root = Py_None;
686 Py_DECREF(self->mark);
687 self->mark = Py_None;
689 Py_DECREF(self->yychunk_iter);
690 self->yychunk_iter = Py_None;
693 /*printf("lex_yylex_iternext() returns %d\n", token);*/
694 return PyLong_FromLong((long)token);
697 static int lex_yylex_traverse(lex_yylexObject *self, visitproc visit, void *arg)
699 Py_VISIT(self->root);
700 Py_VISIT(self->mark);
701 Py_VISIT(self->yychunk_iter);
702 Py_VISIT(self->YY_INPUT_bytes);
706 static int lex_yylex_clear(lex_yylexObject *self)
708 Py_CLEAR(self->root);
709 Py_CLEAR(self->mark);
710 Py_CLEAR(self->yychunk_iter);
711 Py_CLEAR(self->YY_INPUT_bytes);
715 static PyMemberDef lex_yylex_members[] = {
719 offsetof(lex_yylexObject,
722 "root element, stack of sub-elements (treated as characters) and text"
727 offsetof(lex_yylexObject,
730 "list containing cursors, -2 current position, -1 next read position"
735 offsetof(lex_yylexObject,
738 "iterator for new input chunks (or None)"
743 offsetof(lex_yylexObject,
746 "UTF-8 encoding of current chunk to scan"
749 "YY_INPUT_bytes_off",
751 offsetof(lex_yylexObject,
754 "current offset in UTF-8 text"
757 "YY_INPUT_bytes_len",
759 offsetof(lex_yylexObject,
762 "maximum offset in UTF-8 text (inclusive)"
767 static PyTypeObject lex_yylexType = {
768 PyVarObject_HEAD_INIT(NULL, 0)
769 "lex.yylex", /* tp_name */
770 sizeof(lex_yylexObject), /* tp_basicsize */
772 (destructor)lex_yylex_dealloc, /* tp_dealloc */
778 0, /* tp_as_number */
779 0, /* tp_as_sequence */
780 0, /* tp_as_mapping */
786 0, /* tp_as_buffer */
787 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, /* tp_flags */
788 "Lexical token iterator", /* tp_doc */
789 (traverseproc)lex_yylex_traverse, /* tp_traverse */
790 (inquiry)lex_yylex_clear, /* tp_clear */
791 0, /* tp_richcompare */
792 0, /* tp_weaklistoffset */
793 (getiterfunc)lex_yylex_iter, /* tp_iter */
794 (iternextfunc)lex_yylex_iternext, /* tp_iternext */
796 lex_yylex_members, /* tp_members */
800 0, /* tp_descr_get */
801 0, /* tp_descr_set */
802 0, /* tp_dictoffset */
803 (initproc)lex_yylex_init, /* tp_init */
805 lex_yylex_new /* tp_new */
808 static int lex_traverse(PyObject *self, visitproc visit, void *arg)
811 Py_VISIT(work_factory);
815 static int lex_clear(PyObject *self)
818 Py_CLEAR(work_factory);
822 static struct PyModuleDef lexmodule = {
823 PyModuleDef_HEAD_INIT,
833 PyMODINIT_FUNC PyInit_lex(void)
838 "lex module cannot be re-imported or sub-interpreted\n"
843 PyObject *module = PyModule_Create(&lexmodule);
848 PyType_Ready(&lex_yylexType) ||
849 PyModule_AddObject(module, "yylex", (PyObject *)&lex_yylexType)
852 Py_INCREF(&lex_yylexType);
854 work = PyImport_ImportModule("work");
857 work_factory = PyObject_GetAttrString(work, "factory");
858 if (work_factory == NULL) {