Coverage for /var/srv/projects/api.amasfac.comuna18.com/tmp/venv/lib/python3.9/site-packages/xlwt/antlr.py: 25%
1675 statements
« prev ^ index » next coverage.py v6.4.4, created at 2023-07-17 14:22 -0600
« prev ^ index » next coverage.py v6.4.4, created at 2023-07-17 14:22 -0600
1from __future__ import print_function
2## This file is part of PyANTLR. See LICENSE.txt for license
3## details..........Copyright (C) Wolfgang Haefelinger, 2004.
5## This file was copied for use with xlwt from the 2.7.7 ANTLR distribution. Yes, it
6## says 2.7.5 below. The 2.7.5 distribution version didn't have a
7## version in it.
9## Here is the contents of the ANTLR 2.7.7 LICENSE.txt referred to above.
11# SOFTWARE RIGHTS
12#
13# ANTLR 1989-2006 Developed by Terence Parr
14# Partially supported by University of San Francisco & jGuru.com
15#
16# We reserve no legal rights to the ANTLR--it is fully in the
17# public domain. An individual or company may do whatever
18# they wish with source code distributed with ANTLR or the
19# code generated by ANTLR, including the incorporation of
20# ANTLR, or its output, into commerical software.
21#
22# We encourage users to develop software with ANTLR. However,
23# we do ask that credit is given to us for developing
24# ANTLR. By "credit", we mean that if you use ANTLR or
25# incorporate any source code into one of your programs
26# (commercial product, research project, or otherwise) that
27# you acknowledge this fact somewhere in the documentation,
28# research report, etc... If you like ANTLR and have
29# developed a nice tool with the output, please mention that
30# you developed it using ANTLR. In addition, we ask that the
31# headers remain intact in our source code. As long as these
32# guidelines are kept, we expect to continue enhancing this
33# system and expect to make other tools available as they are
34# completed.
35#
36# The primary ANTLR guy:
37#
38# Terence Parr
39# parrt@cs.usfca.edu
40# parrt@antlr.org
42## End of contents of the ANTLR 2.7.7 LICENSE.txt ########################
44## get sys module
45import sys
47from .compat import long, basestring, int_types, xrange
49###xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx###
50### global symbols ###
51###xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx###
53### ANTLR Standard Tokens
54SKIP = -1
55INVALID_TYPE = 0
56EOF_TYPE = 1
57EOF = 1
58NULL_TREE_LOOKAHEAD = 3
59MIN_USER_TYPE = 4
61### ANTLR's EOF Symbol
62EOF_CHAR = ''
64###xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx###
65### general functions ###
66###xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx###
68## Version should be automatically derived from configure.in. For now,
69## we need to bump it ourselfs. Don't remove the <version> tags.
70## <version>
71def version():
72 r = {
73 'major' : '2',
74 'minor' : '7',
75 'micro' : '5',
76 'patch' : '' ,
77 'version': '2.7.5'
78 }
79 return r
80## </version>
82def error(fmt,*args):
83 if fmt:
84 print("error: ", fmt % tuple(args))
86def ifelse(cond,_then,_else):
87 if cond :
88 r = _then
89 else:
90 r = _else
91 return r
93def is_string_type(x):
94 # return (isinstance(x,str) or isinstance(x,unicode))
95 # Simplify; xlwt doesn't support Python < 2.3
96 return isinstance(basestring)
98def assert_string_type(x):
99 assert is_string_type(x)
100 pass
102###xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx###
103### ANTLR Exceptions ###
104###xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx###
106class ANTLRException(Exception):
108 def __init__(self, *args):
109 Exception.__init__(self, *args)
112class RecognitionException(ANTLRException):
114 def __init__(self, *args):
115 ANTLRException.__init__(self, *args)
116 self.fileName = None
117 self.line = -1
118 self.column = -1
119 if len(args) >= 2:
120 self.fileName = args[1]
121 if len(args) >= 3:
122 self.line = args[2]
123 if len(args) >= 4:
124 self.column = args[3]
126 def __str__(self):
127 buf = ['']
128 if self.fileName:
129 buf.append(self.fileName + ":")
130 if self.line != -1:
131 if not self.fileName:
132 buf.append("line ")
133 buf.append(str(self.line))
134 if self.column != -1:
135 buf.append(":" + str(self.column))
136 buf.append(":")
137 buf.append(" ")
138 return str('').join(buf)
140 __repr__ = __str__
143class NoViableAltException(RecognitionException):
145 def __init__(self, *args):
146 RecognitionException.__init__(self, *args)
147 self.token = None
148 self.node = None
149 if isinstance(args[0],AST):
150 self.node = args[0]
151 elif isinstance(args[0],Token):
152 self.token = args[0]
153 else:
154 raise TypeError("NoViableAltException requires Token or AST argument")
156 def __str__(self):
157 if self.token:
158 line = self.token.getLine()
159 col = self.token.getColumn()
160 text = self.token.getText()
161 return "unexpected symbol at line %s (column %s): \"%s\"" % (line,col,text)
162 if self.node == ASTNULL:
163 return "unexpected end of subtree"
164 assert self.node
165 ### hackish, we assume that an AST contains method getText
166 return "unexpected node: %s" % (self.node.getText())
168 __repr__ = __str__
171class NoViableAltForCharException(RecognitionException):
173 def __init__(self, *args):
174 self.foundChar = None
175 if len(args) == 2:
176 self.foundChar = args[0]
177 scanner = args[1]
178 RecognitionException.__init__(self, "NoViableAlt",
179 scanner.getFilename(),
180 scanner.getLine(),
181 scanner.getColumn())
182 elif len(args) == 4:
183 self.foundChar = args[0]
184 fileName = args[1]
185 line = args[2]
186 column = args[3]
187 RecognitionException.__init__(self, "NoViableAlt",
188 fileName, line, column)
189 else:
190 RecognitionException.__init__(self, "NoViableAlt",
191 '', -1, -1)
193 def __str__(self):
194 mesg = "unexpected char: "
195 if self.foundChar >= ' ' and self.foundChar <= '~':
196 mesg += "'" + self.foundChar + "'"
197 elif self.foundChar:
198 mesg += "0x" + hex(ord(self.foundChar)).upper()[2:]
199 else:
200 mesg += "<None>"
201 return mesg
203 __repr__ = __str__
206class SemanticException(RecognitionException):
208 def __init__(self, *args):
209 RecognitionException.__init__(self, *args)
212class MismatchedCharException(RecognitionException):
214 NONE = 0
215 CHAR = 1
216 NOT_CHAR = 2
217 RANGE = 3
218 NOT_RANGE = 4
219 SET = 5
220 NOT_SET = 6
222 def __init__(self, *args):
223 self.args = args
224 if len(args) == 5:
225 # Expected range / not range
226 if args[3]:
227 self.mismatchType = MismatchedCharException.NOT_RANGE
228 else:
229 self.mismatchType = MismatchedCharException.RANGE
230 self.foundChar = args[0]
231 self.expecting = args[1]
232 self.upper = args[2]
233 self.scanner = args[4]
234 RecognitionException.__init__(self, "Mismatched char range",
235 self.scanner.getFilename(),
236 self.scanner.getLine(),
237 self.scanner.getColumn())
238 elif len(args) == 4 and is_string_type(args[1]):
239 # Expected char / not char
240 if args[2]:
241 self.mismatchType = MismatchedCharException.NOT_CHAR
242 else:
243 self.mismatchType = MismatchedCharException.CHAR
244 self.foundChar = args[0]
245 self.expecting = args[1]
246 self.scanner = args[3]
247 RecognitionException.__init__(self, "Mismatched char",
248 self.scanner.getFilename(),
249 self.scanner.getLine(),
250 self.scanner.getColumn())
251 elif len(args) == 4 and isinstance(args[1], BitSet):
252 # Expected BitSet / not BitSet
253 if args[2]:
254 self.mismatchType = MismatchedCharException.NOT_SET
255 else:
256 self.mismatchType = MismatchedCharException.SET
257 self.foundChar = args[0]
258 self.set = args[1]
259 self.scanner = args[3]
260 RecognitionException.__init__(self, "Mismatched char set",
261 self.scanner.getFilename(),
262 self.scanner.getLine(),
263 self.scanner.getColumn())
264 else:
265 self.mismatchType = MismatchedCharException.NONE
266 RecognitionException.__init__(self, "Mismatched char")
268 ## Append a char to the msg buffer. If special,
269 # then show escaped version
270 #
271 def appendCharName(self, sb, c):
272 if not c or c == 65535:
273 # 65535 = (char) -1 = EOF
274 sb.append("'<EOF>'")
275 elif c == '\n':
276 sb.append("'\\n'")
277 elif c == '\r':
278 sb.append("'\\r'");
279 elif c == '\t':
280 sb.append("'\\t'")
281 else:
282 sb.append('\'' + c + '\'')
284 ##
285 # Returns an error message with line number/column information
286 #
287 def __str__(self):
288 sb = ['']
289 sb.append(RecognitionException.__str__(self))
291 if self.mismatchType == MismatchedCharException.CHAR:
292 sb.append("expecting ")
293 self.appendCharName(sb, self.expecting)
294 sb.append(", found ")
295 self.appendCharName(sb, self.foundChar)
296 elif self.mismatchType == MismatchedCharException.NOT_CHAR:
297 sb.append("expecting anything but '")
298 self.appendCharName(sb, self.expecting)
299 sb.append("'; got it anyway")
300 elif self.mismatchType in [MismatchedCharException.RANGE, MismatchedCharException.NOT_RANGE]:
301 sb.append("expecting char ")
302 if self.mismatchType == MismatchedCharException.NOT_RANGE:
303 sb.append("NOT ")
304 sb.append("in range: ")
305 self.appendCharName(sb, self.expecting)
306 sb.append("..")
307 self.appendCharName(sb, self.upper)
308 sb.append(", found ")
309 self.appendCharName(sb, self.foundChar)
310 elif self.mismatchType in [MismatchedCharException.SET, MismatchedCharException.NOT_SET]:
311 sb.append("expecting ")
312 if self.mismatchType == MismatchedCharException.NOT_SET:
313 sb.append("NOT ")
314 sb.append("one of (")
315 for i in range(len(self.set)):
316 self.appendCharName(sb, self.set[i])
317 sb.append("), found ")
318 self.appendCharName(sb, self.foundChar)
320 return str().join(sb).strip()
322 __repr__ = __str__
325class MismatchedTokenException(RecognitionException):
327 NONE = 0
328 TOKEN = 1
329 NOT_TOKEN = 2
330 RANGE = 3
331 NOT_RANGE = 4
332 SET = 5
333 NOT_SET = 6
335 def __init__(self, *args):
336 self.args = args
337 self.tokenNames = []
338 self.token = None
339 self.tokenText = ''
340 self.node = None
341 if len(args) == 6:
342 # Expected range / not range
343 if args[3]:
344 self.mismatchType = MismatchedTokenException.NOT_RANGE
345 else:
346 self.mismatchType = MismatchedTokenException.RANGE
347 self.tokenNames = args[0]
348 self.expecting = args[2]
349 self.upper = args[3]
350 self.fileName = args[5]
352 elif len(args) == 4 and isinstance(args[2], int):
353 # Expected token / not token
354 if args[3]:
355 self.mismatchType = MismatchedTokenException.NOT_TOKEN
356 else:
357 self.mismatchType = MismatchedTokenException.TOKEN
358 self.tokenNames = args[0]
359 self.expecting = args[2]
361 elif len(args) == 4 and isinstance(args[2], BitSet):
362 # Expected BitSet / not BitSet
363 if args[3]:
364 self.mismatchType = MismatchedTokenException.NOT_SET
365 else:
366 self.mismatchType = MismatchedTokenException.SET
367 self.tokenNames = args[0]
368 self.set = args[2]
370 else:
371 self.mismatchType = MismatchedTokenException.NONE
372 RecognitionException.__init__(self, "Mismatched Token: expecting any AST node", "<AST>", -1, -1)
374 if len(args) >= 2:
375 if isinstance(args[1],Token):
376 self.token = args[1]
377 self.tokenText = self.token.getText()
378 RecognitionException.__init__(self, "Mismatched Token",
379 self.fileName,
380 self.token.getLine(),
381 self.token.getColumn())
382 elif isinstance(args[1],AST):
383 self.node = args[1]
384 self.tokenText = str(self.node)
385 RecognitionException.__init__(self, "Mismatched Token",
386 "<AST>",
387 self.node.getLine(),
388 self.node.getColumn())
389 else:
390 self.tokenText = "<empty tree>"
391 RecognitionException.__init__(self, "Mismatched Token",
392 "<AST>", -1, -1)
394 def appendTokenName(self, sb, tokenType):
395 if tokenType == INVALID_TYPE:
396 sb.append("<Set of tokens>")
397 elif tokenType < 0 or tokenType >= len(self.tokenNames):
398 sb.append("<" + str(tokenType) + ">")
399 else:
400 sb.append(self.tokenNames[tokenType])
402 ##
403 # Returns an error message with line number/column information
404 #
405 def __str__(self):
406 sb = ['']
407 sb.append(RecognitionException.__str__(self))
409 if self.mismatchType == MismatchedTokenException.TOKEN:
410 sb.append("expecting ")
411 self.appendTokenName(sb, self.expecting)
412 sb.append(", found " + self.tokenText)
413 elif self.mismatchType == MismatchedTokenException.NOT_TOKEN:
414 sb.append("expecting anything but '")
415 self.appendTokenName(sb, self.expecting)
416 sb.append("'; got it anyway")
417 elif self.mismatchType in [MismatchedTokenException.RANGE, MismatchedTokenException.NOT_RANGE]:
418 sb.append("expecting token ")
419 if self.mismatchType == MismatchedTokenException.NOT_RANGE:
420 sb.append("NOT ")
421 sb.append("in range: ")
422 self.appendTokenName(sb, self.expecting)
423 sb.append("..")
424 self.appendTokenName(sb, self.upper)
425 sb.append(", found " + self.tokenText)
426 elif self.mismatchType in [MismatchedTokenException.SET, MismatchedTokenException.NOT_SET]:
427 sb.append("expecting ")
428 if self.mismatchType == MismatchedTokenException.NOT_SET:
429 sb.append("NOT ")
430 sb.append("one of (")
431 for i in range(len(self.set)):
432 self.appendTokenName(sb, self.set[i])
433 sb.append("), found " + self.tokenText)
435 return str().join(sb).strip()
437 __repr__ = __str__
440class TokenStreamException(ANTLRException):
442 def __init__(self, *args):
443 ANTLRException.__init__(self, *args)
446# Wraps an Exception in a TokenStreamException
447class TokenStreamIOException(TokenStreamException):
449 def __init__(self, *args):
450 if args and isinstance(args[0], Exception):
451 io = args[0]
452 TokenStreamException.__init__(self, str(io))
453 self.io = io
454 else:
455 TokenStreamException.__init__(self, *args)
456 self.io = self
459# Wraps a RecognitionException in a TokenStreamException
460class TokenStreamRecognitionException(TokenStreamException):
462 def __init__(self, *args):
463 if args and isinstance(args[0], RecognitionException):
464 recog = args[0]
465 TokenStreamException.__init__(self, str(recog))
466 self.recog = recog
467 else:
468 raise TypeError("TokenStreamRecognitionException requires RecognitionException argument")
470 def __str__(self):
471 return str(self.recog)
473 __repr__ = __str__
476class TokenStreamRetryException(TokenStreamException):
478 def __init__(self, *args):
479 TokenStreamException.__init__(self, *args)
482class CharStreamException(ANTLRException):
484 def __init__(self, *args):
485 ANTLRException.__init__(self, *args)
488# Wraps an Exception in a CharStreamException
489class CharStreamIOException(CharStreamException):
491 def __init__(self, *args):
492 if args and isinstance(args[0], Exception):
493 io = args[0]
494 CharStreamException.__init__(self, str(io))
495 self.io = io
496 else:
497 CharStreamException.__init__(self, *args)
498 self.io = self
501class TryAgain(Exception):
502 pass
505###xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx###
506### Token ###
507###xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx###
509class Token(object):
510 SKIP = -1
511 INVALID_TYPE = 0
512 EOF_TYPE = 1
513 EOF = 1
514 NULL_TREE_LOOKAHEAD = 3
515 MIN_USER_TYPE = 4
517 def __init__(self,**argv):
518 try:
519 self.type = argv['type']
520 except:
521 self.type = INVALID_TYPE
522 try:
523 self.text = argv['text']
524 except:
525 self.text = "<no text>"
527 def isEOF(self):
528 return (self.type == EOF_TYPE)
530 def getColumn(self):
531 return 0
533 def getLine(self):
534 return 0
536 def getFilename(self):
537 return None
539 def setFilename(self,name):
540 return self
542 def getText(self):
543 return "<no text>"
545 def setText(self,text):
546 if is_string_type(text):
547 pass
548 else:
549 raise TypeError("Token.setText requires string argument")
550 return self
552 def setColumn(self,column):
553 return self
555 def setLine(self,line):
556 return self
558 def getType(self):
559 return self.type
561 def setType(self,type):
562 if isinstance(type,int):
563 self.type = type
564 else:
565 raise TypeError("Token.setType requires integer argument")
566 return self
568 def toString(self):
569 ## not optimal
570 type_ = self.type
571 if type_ == 3:
572 tval = 'NULL_TREE_LOOKAHEAD'
573 elif type_ == 1:
574 tval = 'EOF_TYPE'
575 elif type_ == 0:
576 tval = 'INVALID_TYPE'
577 elif type_ == -1:
578 tval = 'SKIP'
579 else:
580 tval = type_
581 return '["%s",<%s>]' % (self.getText(),tval)
583 __str__ = toString
584 __repr__ = toString
586### static attribute ..
587Token.badToken = Token( type=INVALID_TYPE, text="<no text>")
589if __name__ == "__main__": 589 ↛ 590line 589 didn't jump to line 590, because the condition on line 589 was never true
590 print("testing ..")
591 T = Token.badToken
592 print(T)
594###xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx###
595### CommonToken ###
596###xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx###
598class CommonToken(Token):
600 def __init__(self,**argv):
601 Token.__init__(self,**argv)
602 self.line = 0
603 self.col = 0
604 try:
605 self.line = argv['line']
606 except:
607 pass
608 try:
609 self.col = argv['col']
610 except:
611 pass
613 def getLine(self):
614 return self.line
616 def getText(self):
617 return self.text
619 def getColumn(self):
620 return self.col
622 def setLine(self,line):
623 self.line = line
624 return self
626 def setText(self,text):
627 self.text = text
628 return self
630 def setColumn(self,col):
631 self.col = col
632 return self
634 def toString(self):
635 ## not optimal
636 type_ = self.type
637 if type_ == 3:
638 tval = 'NULL_TREE_LOOKAHEAD'
639 elif type_ == 1:
640 tval = 'EOF_TYPE'
641 elif type_ == 0:
642 tval = 'INVALID_TYPE'
643 elif type_ == -1:
644 tval = 'SKIP'
645 else:
646 tval = type_
647 d = {
648 'text' : self.text,
649 'type' : tval,
650 'line' : self.line,
651 'colm' : self.col
652 }
654 fmt = '["%(text)s",<%(type)s>,line=%(line)s,col=%(colm)s]'
655 return fmt % d
657 __str__ = toString
658 __repr__ = toString
661if __name__ == '__main__' : 661 ↛ 662line 661 didn't jump to line 662, because the condition on line 661 was never true
662 T = CommonToken()
663 print(T)
664 T = CommonToken(col=15,line=1,text="some text", type=5)
665 print(T)
666 T = CommonToken()
667 T.setLine(1).setColumn(15).setText("some text").setType(5)
668 print(T)
669 print(T.getLine())
670 print(T.getColumn())
671 print(T.getText())
672 print(T.getType())
674###xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx###
675### CommonHiddenStreamToken ###
676###xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx###
678class CommonHiddenStreamToken(CommonToken):
679 def __init__(self,*args):
680 CommonToken.__init__(self,*args)
681 self.hiddenBefore = None
682 self.hiddenAfter = None
684 def getHiddenAfter(self):
685 return self.hiddenAfter
687 def getHiddenBefore(self):
688 return self.hiddenBefore
690 def setHiddenAfter(self,t):
691 self.hiddenAfter = t
693 def setHiddenBefore(self, t):
694 self.hiddenBefore = t
696###xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx###
697### Queue ###
698###xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx###
700## Shall be a circular buffer on tokens ..
701class Queue(object):
703 def __init__(self):
704 self.buffer = [] # empty list
706 def append(self,item):
707 self.buffer.append(item)
709 def elementAt(self,index):
710 return self.buffer[index]
712 def reset(self):
713 self.buffer = []
715 def removeFirst(self):
716 self.buffer.pop(0)
718 def length(self):
719 return len(self.buffer)
721 def __str__(self):
722 return str(self.buffer)
724###xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx###
725### InputBuffer ###
726###xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx###
728class InputBuffer(object):
729 def __init__(self):
730 self.nMarkers = 0
731 self.markerOffset = 0
732 self.numToConsume = 0
733 self.queue = Queue()
735 def __str__(self):
736 return "(%s,%s,%s,%s)" % (
737 self.nMarkers,
738 self.markerOffset,
739 self.numToConsume,
740 self.queue)
742 def __repr__(self):
743 return str(self)
745 def commit(self):
746 self.nMarkers -= 1
748 def consume(self) :
749 self.numToConsume += 1
751 ## probably better to return a list of items
752 ## because of unicode. Or return a unicode
753 ## string ..
754 def getLAChars(self) :
755 i = self.markerOffset
756 n = self.queue.length()
757 s = ''
758 while i<n:
759 s += self.queue.elementAt(i)
760 return s
762 ## probably better to return a list of items
763 ## because of unicode chars
764 def getMarkedChars(self) :
765 s = ''
766 i = 0
767 n = self.markerOffset
768 while i<n:
769 s += self.queue.elementAt(i)
770 return s
772 def isMarked(self) :
773 return self.nMarkers != 0
775 def fill(self,k):
776 ### abstract method
777 raise NotImplementedError()
779 def LA(self,k) :
780 self.fill(k)
781 return self.queue.elementAt(self.markerOffset + k - 1)
783 def mark(self) :
784 self.syncConsume()
785 self.nMarkers += 1
786 return self.markerOffset
788 def rewind(self,mark) :
789 self.syncConsume()
790 self.markerOffset = mark
791 self.nMarkers -= 1
793 def reset(self) :
794 self.nMarkers = 0
795 self.markerOffset = 0
796 self.numToConsume = 0
797 self.queue.reset()
799 def syncConsume(self) :
800 while self.numToConsume > 0:
801 if self.nMarkers > 0:
802 # guess mode -- leave leading characters and bump offset.
803 self.markerOffset += 1
804 else:
805 # normal mode -- remove first character
806 self.queue.removeFirst()
807 self.numToConsume -= 1
809###xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx###
810### CharBuffer ###
811###xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx###
813class CharBuffer(InputBuffer):
814 def __init__(self,reader):
815 ##assert isinstance(reader,file)
816 super(CharBuffer,self).__init__()
817 ## a reader is supposed to be anything that has
818 ## a method 'read(int)'.
819 self.input = reader
821 def __str__(self):
822 base = super(CharBuffer,self).__str__()
823 return "CharBuffer{%s,%s" % (base,str(input))
825 def fill(self,amount):
826 try:
827 self.syncConsume()
828 while self.queue.length() < (amount + self.markerOffset) :
829 ## retrieve just one char - what happend at end
830 ## of input?
831 c = self.input.read(1)
832 ### python's behaviour is to return the empty string on
833 ### EOF, ie. no exception whatsoever is thrown. An empty
834 ### python string has the nice feature that it is of
835 ### type 'str' and "not ''" would return true. Contrary,
836 ### one can't do this: '' in 'abc'. This should return
837 ### false, but all we get is then a TypeError as an
838 ### empty string is not a character.
840 ### Let's assure then that we have either seen a
841 ### character or an empty string (EOF).
842 assert len(c) == 0 or len(c) == 1
844 ### And it shall be of type string (ASCII or UNICODE).
845 assert is_string_type(c)
847 ### Just append EOF char to buffer. Note that buffer may
848 ### contain then just more than one EOF char ..
850 ### use unicode chars instead of ASCII ..
851 self.queue.append(c)
852 except Exception as e:
853 raise CharStreamIOException(e)
854 ##except: # (mk) Cannot happen ...
855 ##error ("unexpected exception caught ..")
856 ##assert 0
858###xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx###
859### LexerSharedInputState ###
860###xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx###
862class LexerSharedInputState(object):
863 def __init__(self,ibuf):
864 assert isinstance(ibuf,InputBuffer)
865 self.input = ibuf
866 self.column = 1
867 self.line = 1
868 self.tokenStartColumn = 1
869 self.tokenStartLine = 1
870 self.guessing = 0
871 self.filename = None
873 def reset(self):
874 self.column = 1
875 self.line = 1
876 self.tokenStartColumn = 1
877 self.tokenStartLine = 1
878 self.guessing = 0
879 self.filename = None
880 self.input.reset()
882 def LA(self,k):
883 return self.input.LA(k)
885###xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx###
886### TokenStream ###
887###xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx###
889class TokenStream(object):
890 def nextToken(self):
891 pass
893 def __iter__(self):
894 return TokenStreamIterator(self)
896###xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx###
897### TokenStreamIterator ###
898###xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx###
900class TokenStreamIterator(object):
901 def __init__(self,inst):
902 if isinstance(inst,TokenStream):
903 self.inst = inst
904 return
905 raise TypeError("TokenStreamIterator requires TokenStream object")
907 def next(self):
908 assert self.inst
909 item = self.inst.nextToken()
910 if not item or item.isEOF():
911 raise StopIteration()
912 return item
914###xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx###
915### TokenStreamSelector ###
916###xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx###
918class TokenStreamSelector(TokenStream):
920 def __init__(self):
921 self._input = None
922 self._stmap = {}
923 self._stack = []
925 def addInputStream(self,stream,key):
926 self._stmap[key] = stream
928 def getCurrentStream(self):
929 return self._input
931 def getStream(self,sname):
932 try:
933 stream = self._stmap[sname]
934 except:
935 raise ValueError("TokenStream " + sname + " not found");
936 return stream;
938 def nextToken(self):
939 while 1:
940 try:
941 return self._input.nextToken()
942 except TokenStreamRetryException:
943 ### just retry "forever"
944 pass
946 def pop(self):
947 stream = self._stack.pop();
948 self.select(stream);
949 return stream;
951 def push(self,arg):
952 self._stack.append(self._input);
953 self.select(arg)
955 def retry(self):
956 raise TokenStreamRetryException()
958 def select(self,arg):
959 if isinstance(arg,TokenStream):
960 self._input = arg
961 return
962 if is_string_type(arg):
963 self._input = self.getStream(arg)
964 return
965 raise TypeError("TokenStreamSelector.select requires " +
966 "TokenStream or string argument")
968###xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx###
969### TokenStreamBasicFilter ###
970###xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx###
972class TokenStreamBasicFilter(TokenStream):
974 def __init__(self,input):
976 self.input = input;
977 self.discardMask = BitSet()
979 def discard(self,arg):
980 if isinstance(arg,int):
981 self.discardMask.add(arg)
982 return
983 if isinstance(arg,BitSet):
984 self.discardMark = arg
985 return
986 raise TypeError("TokenStreamBasicFilter.discard requires" +
987 "integer or BitSet argument")
989 def nextToken(self):
990 tok = self.input.nextToken()
991 while tok and self.discardMask.member(tok.getType()):
992 tok = self.input.nextToken()
993 return tok
995###xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx###
996### TokenStreamHiddenTokenFilter ###
997###xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx###
999class TokenStreamHiddenTokenFilter(TokenStreamBasicFilter):
1001 def __init__(self,input):
1002 TokenStreamBasicFilter.__init__(self,input)
1003 self.hideMask = BitSet()
1004 self.nextMonitoredToken = None
1005 self.lastHiddenToken = None
1006 self.firstHidden = None
1008 def consume(self):
1009 self.nextMonitoredToken = self.input.nextToken()
1011 def consumeFirst(self):
1012 self.consume()
1014 p = None;
1015 while self.hideMask.member(self.LA(1).getType()) or \
1016 self.discardMask.member(self.LA(1).getType()):
1017 if self.hideMask.member(self.LA(1).getType()):
1018 if not p:
1019 p = self.LA(1)
1020 else:
1021 p.setHiddenAfter(self.LA(1))
1022 self.LA(1).setHiddenBefore(p)
1023 p = self.LA(1)
1024 self.lastHiddenToken = p
1025 if not self.firstHidden:
1026 self.firstHidden = p
1027 self.consume()
1029 def getDiscardMask(self):
1030 return self.discardMask
1032 def getHiddenAfter(self,t):
1033 return t.getHiddenAfter()
1035 def getHiddenBefore(self,t):
1036 return t.getHiddenBefore()
1038 def getHideMask(self):
1039 return self.hideMask
1041 def getInitialHiddenToken(self):
1042 return self.firstHidden
1044 def hide(self,m):
1045 if isinstance(m,int):
1046 self.hideMask.add(m)
1047 return
1048 if isinstance(m.BitMask):
1049 self.hideMask = m
1050 return
1052 def LA(self,i):
1053 return self.nextMonitoredToken
1055 def nextToken(self):
1056 if not self.LA(1):
1057 self.consumeFirst()
1059 monitored = self.LA(1)
1061 monitored.setHiddenBefore(self.lastHiddenToken)
1062 self.lastHiddenToken = None
1064 self.consume()
1065 p = monitored
1067 while self.hideMask.member(self.LA(1).getType()) or \
1068 self.discardMask.member(self.LA(1).getType()):
1069 if self.hideMask.member(self.LA(1).getType()):
1070 p.setHiddenAfter(self.LA(1))
1071 if p != monitored:
1072 self.LA(1).setHiddenBefore(p)
1073 p = self.lastHiddenToken = self.LA(1)
1074 self.consume()
1075 return monitored
1077###xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx###
1078### StringBuffer ###
1079###xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx###
1081class StringBuffer:
1082 def __init__(self,string=None):
1083 if string:
1084 self.text = list(string)
1085 else:
1086 self.text = []
1088 def setLength(self,sz):
1089 if not sz :
1090 self.text = []
1091 return
1092 assert sz>0
1093 if sz >= self.length():
1094 return
1095 ### just reset to empty buffer
1096 self.text = self.text[0:sz]
1098 def length(self):
1099 return len(self.text)
1101 def append(self,c):
1102 self.text.append(c)
1104 ### return buffer as string. Arg 'a' is used as index
1105 ## into the buffer and 2nd argument shall be the length.
1106 ## If 2nd args is absent, we return chars till end of
1107 ## buffer starting with 'a'.
1108 def getString(self,a=None,length=None):
1109 if not a :
1110 a = 0
1111 assert a>=0
1112 if a>= len(self.text) :
1113 return ""
1115 if not length:
1116 ## no second argument
1117 L = self.text[a:]
1118 else:
1119 assert (a+length) <= len(self.text)
1120 b = a + length
1121 L = self.text[a:b]
1122 s = ""
1123 for x in L : s += x
1124 return s
1126 toString = getString ## alias
1128 def __str__(self):
1129 return str(self.text)
1131###xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx###
1132### Reader ###
1133###xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx###
1135## When reading Japanese chars, it happens that a stream returns a
1136## 'char' of length 2. This looks like a bug in the appropriate
1137## codecs - but I'm rather unsure about this. Anyway, if this is
1138## the case, I'm going to split this string into a list of chars
1139## and put them on hold, ie. on a buffer. Next time when called
1140## we read from buffer until buffer is empty.
1141## wh: nov, 25th -> problem does not appear in Python 2.4.0.c1.
1143class Reader(object):
1144 def __init__(self,stream):
1145 self.cin = stream
1146 self.buf = []
1148 def read(self,num):
1149 assert num==1
1151 if len(self.buf):
1152 return self.buf.pop()
1154 ## Read a char - this may return a string.
1155 ## Is this a bug in codecs/Python?
1156 c = self.cin.read(1)
1158 if not c or len(c)==1:
1159 return c
1161 L = list(c)
1162 L.reverse()
1163 for x in L:
1164 self.buf.append(x)
1166 ## read one char ..
1167 return self.read(1)
1169###xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx###
1170### CharScanner ###
1171###xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx###
1173class CharScanner(TokenStream):
1174 ## class members
1175 NO_CHAR = 0
1176 EOF_CHAR = '' ### EOF shall be the empty string.
1178 def __init__(self, *argv, **kwargs):
1179 super(CharScanner, self).__init__()
1180 self.saveConsumedInput = True
1181 self.tokenClass = None
1182 self.caseSensitive = True
1183 self.caseSensitiveLiterals = True
1184 self.literals = None
1185 self.tabsize = 8
1186 self._returnToken = None
1187 self.commitToPath = False
1188 self.traceDepth = 0
1189 self.text = StringBuffer()
1190 self.hashString = hash(self)
1191 self.setTokenObjectClass(CommonToken)
1192 self.setInput(*argv)
1194 def __iter__(self):
1195 return CharScannerIterator(self)
1197 def setInput(self,*argv):
1198 ## case 1:
1199 ## if there's no arg we default to read from
1200 ## standard input
1201 if not argv:
1202 import sys
1203 self.setInput(sys.stdin)
1204 return
1206 ## get 1st argument
1207 arg1 = argv[0]
1209 ## case 2:
1210 ## if arg1 is a string, we assume it's a file name
1211 ## and open a stream using 2nd argument as open
1212 ## mode. If there's no 2nd argument we fall back to
1213 ## mode '+rb'.
1214 if is_string_type(arg1):
1215 f = open(arg1,"rb")
1216 self.setInput(f)
1217 self.setFilename(arg1)
1218 return
1220 ## case 3:
1221 ## if arg1 is a file we wrap it by a char buffer (
1222 ## some additional checks?? No, can't do this in
1223 ## general).
1224 if isinstance(arg1,file):
1225 self.setInput(CharBuffer(arg1))
1226 return
1228 ## case 4:
1229 ## if arg1 is of type SharedLexerInputState we use
1230 ## argument as is.
1231 if isinstance(arg1,LexerSharedInputState):
1232 self.inputState = arg1
1233 return
1235 ## case 5:
1236 ## check whether argument type is of type input
1237 ## buffer. If so create a SharedLexerInputState and
1238 ## go ahead.
1239 if isinstance(arg1,InputBuffer):
1240 self.setInput(LexerSharedInputState(arg1))
1241 return
1243 ## case 6:
1244 ## check whether argument type has a method read(int)
1245 ## If so create CharBuffer ...
1246 try:
1247 if arg1.read:
1248 rd = Reader(arg1)
1249 cb = CharBuffer(rd)
1250 ss = LexerSharedInputState(cb)
1251 self.inputState = ss
1252 return
1253 except:
1254 pass
1256 ## case 7:
1257 ## raise wrong argument exception
1258 raise TypeError(argv)
1260 def setTabSize(self,size) :
1261 self.tabsize = size
1263 def getTabSize(self) :
1264 return self.tabsize
1266 def setCaseSensitive(self,t) :
1267 self.caseSensitive = t
1269 def setCommitToPath(self,commit) :
1270 self.commitToPath = commit
1272 def setFilename(self,f) :
1273 self.inputState.filename = f
1275 def setLine(self,line) :
1276 self.inputState.line = line
1278 def setText(self,s) :
1279 self.resetText()
1280 self.text.append(s)
1282 def getCaseSensitive(self) :
1283 return self.caseSensitive
1285 def getCaseSensitiveLiterals(self) :
1286 return self.caseSensitiveLiterals
1288 def getColumn(self) :
1289 return self.inputState.column
1291 def setColumn(self,c) :
1292 self.inputState.column = c
1294 def getCommitToPath(self) :
1295 return self.commitToPath
1297 def getFilename(self) :
1298 return self.inputState.filename
1300 def getInputBuffer(self) :
1301 return self.inputState.input
1303 def getInputState(self) :
1304 return self.inputState
1306 def setInputState(self,state) :
1307 assert isinstance(state,LexerSharedInputState)
1308 self.inputState = state
1310 def getLine(self) :
1311 return self.inputState.line
1313 def getText(self) :
1314 return str(self.text)
1316 def getTokenObject(self) :
1317 return self._returnToken
1319 def LA(self,i) :
1320 c = self.inputState.input.LA(i)
1321 if not self.caseSensitive:
1322 ### E0006
1323 c = c.__class__.lower(c)
1324 return c
1326 def makeToken(self,type) :
1327 try:
1328 ## dynamically load a class
1329 assert self.tokenClass
1330 tok = self.tokenClass()
1331 tok.setType(type)
1332 tok.setColumn(self.inputState.tokenStartColumn)
1333 tok.setLine(self.inputState.tokenStartLine)
1334 return tok
1335 except:
1336 self.panic("unable to create new token")
1337 return Token.badToken
1339 def mark(self) :
1340 return self.inputState.input.mark()
1342 def _match_bitset(self,b) :
1343 if b.member(self.LA(1)):
1344 self.consume()
1345 else:
1346 raise MismatchedCharException(self.LA(1), b, False, self)
1348 def _match_string(self,s) :
1349 for c in s:
1350 if self.LA(1) == c:
1351 self.consume()
1352 else:
1353 raise MismatchedCharException(self.LA(1), c, False, self)
1355 def match(self,item):
1356 if is_string_type(item):
1357 return self._match_string(item)
1358 else:
1359 return self._match_bitset(item)
1361 def matchNot(self,c) :
1362 if self.LA(1) != c:
1363 self.consume()
1364 else:
1365 raise MismatchedCharException(self.LA(1), c, True, self)
1367 def matchRange(self,c1,c2) :
1368 if self.LA(1) < c1 or self.LA(1) > c2 :
1369 raise MismatchedCharException(self.LA(1), c1, c2, False, self)
1370 else:
1371 self.consume()
1373 def newline(self) :
1374 self.inputState.line += 1
1375 self.inputState.column = 1
1377 def tab(self) :
1378 c = self.getColumn()
1379 nc = ( ((c-1)/self.tabsize) + 1) * self.tabsize + 1
1380 self.setColumn(nc)
1382 def panic(self,s='') :
1383 print("CharScanner: panic: " + s)
1384 sys.exit(1)
1386 def reportError(self,s) :
1387 if not self.getFilename():
1388 print("error: " + str(s))
1389 else:
1390 print(self.getFilename() + ": error: " + str(s))
1392 def reportWarning(self,s) :
1393 if not self.getFilename():
1394 print("warning: " + str(s))
1395 else:
1396 print(self.getFilename() + ": warning: " + str(s))
1398 def resetText(self) :
1399 self.text.setLength(0)
1400 self.inputState.tokenStartColumn = self.inputState.column
1401 self.inputState.tokenStartLine = self.inputState.line
1403 def rewind(self,pos) :
1404 self.inputState.input.rewind(pos)
1406 def setTokenObjectClass(self,cl):
1407 self.tokenClass = cl
1409 def testForLiteral(self,token):
1410 if not token:
1411 return
1412 assert isinstance(token,Token)
1414 _type = token.getType()
1416 ## special tokens can't be literals
1417 if _type in [SKIP,INVALID_TYPE,EOF_TYPE,NULL_TREE_LOOKAHEAD] :
1418 return
1420 _text = token.getText()
1421 if not _text:
1422 return
1424 assert is_string_type(_text)
1425 _type = self.testLiteralsTable(_text,_type)
1426 token.setType(_type)
1427 return _type
1429 def testLiteralsTable(self,*args):
1430 if is_string_type(args[0]):
1431 s = args[0]
1432 i = args[1]
1433 else:
1434 s = self.text.getString()
1435 i = args[0]
1437 ## check whether integer has been given
1438 if not isinstance(i,int):
1439 assert isinstance(i,int)
1441 ## check whether we have a dict
1442 assert isinstance(self.literals,dict)
1443 try:
1444 ## E0010
1445 if not self.caseSensitiveLiterals:
1446 s = s.__class__.lower(s)
1447 i = self.literals[s]
1448 except:
1449 pass
1450 return i
1452 def toLower(self,c):
1453 return c.__class__.lower()
1455 def traceIndent(self):
1456 print(' ' * self.traceDepth)
1458 def traceIn(self,rname):
1459 self.traceDepth += 1
1460 self.traceIndent()
1461 print("> lexer %s c== %s" % (rname,self.LA(1)))
1463 def traceOut(self,rname):
1464 self.traceIndent()
1465 print("< lexer %s c== %s" % (rname,self.LA(1)))
1466 self.traceDepth -= 1
1468 def uponEOF(self):
1469 pass
1471 def append(self,c):
1472 if self.saveConsumedInput :
1473 self.text.append(c)
1475 def commit(self):
1476 self.inputState.input.commit()
1478 def consume(self):
1479 if not self.inputState.guessing:
1480 c = self.LA(1)
1481 if self.caseSensitive:
1482 self.append(c)
1483 else:
1484 # use input.LA(), not LA(), to get original case
1485 # CharScanner.LA() would toLower it.
1486 c = self.inputState.input.LA(1)
1487 self.append(c)
1489 if c and c in "\t":
1490 self.tab()
1491 else:
1492 self.inputState.column += 1
1493 self.inputState.input.consume()
1495 ## Consume chars until one matches the given char
1496 def consumeUntil_char(self,c):
1497 while self.LA(1) != EOF_CHAR and self.LA(1) != c:
1498 self.consume()
1500 ## Consume chars until one matches the given set
1501 def consumeUntil_bitset(self,bitset):
1502 while self.LA(1) != EOF_CHAR and not self.set.member(self.LA(1)):
1503 self.consume()
1505 ### If symbol seen is EOF then generate and set token, otherwise
1506 ### throw exception.
1507 def default(self,la1):
1508 if not la1 :
1509 self.uponEOF()
1510 self._returnToken = self.makeToken(EOF_TYPE)
1511 else:
1512 self.raise_NoViableAlt(la1)
1514 def filterdefault(self,la1,*args):
1515 if not la1:
1516 self.uponEOF()
1517 self._returnToken = self.makeToken(EOF_TYPE)
1518 return
1520 if not args:
1521 self.consume()
1522 raise TryAgain()
1523 else:
1524 ### apply filter object
1525 self.commit();
1526 try:
1527 func=args[0]
1528 func(*args[1:])
1529 except RecognitionException as e:
1530 ## catastrophic failure
1531 self.reportError(e);
1532 self.consume();
1533 raise TryAgain()
1535 def raise_NoViableAlt(self,la1=None):
1536 if not la1: la1 = self.LA(1)
1537 fname = self.getFilename()
1538 line = self.getLine()
1539 col = self.getColumn()
1540 raise NoViableAltForCharException(la1,fname,line,col)
1542 def set_return_token(self,_create,_token,_ttype,_offset):
1543 if _create and not _token and (not _ttype == SKIP):
1544 string = self.text.getString(_offset)
1545 _token = self.makeToken(_ttype)
1546 _token.setText(string)
1547 self._returnToken = _token
1548 return _token
1550###xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx###
1551### CharScannerIterator ###
1552###xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx###
1554class CharScannerIterator:
1556 def __init__(self,inst):
1557 if isinstance(inst,CharScanner):
1558 self.inst = inst
1559 return
1560 raise TypeError("CharScannerIterator requires CharScanner object")
1562 def next(self):
1563 assert self.inst
1564 item = self.inst.nextToken()
1565 if not item or item.isEOF():
1566 raise StopIteration()
1567 return item
1569###xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx###
1570### BitSet ###
1571###xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx###
1573### I'm assuming here that a long is 64bits. It appears however, that
1574### a long is of any size. That means we can use a single long as the
1575### bitset (!), ie. Python would do almost all the work (TBD).
1577class BitSet(object):
1578 BITS = 64
1579 NIBBLE = 4
1580 LOG_BITS = 6
1581 MOD_MASK = BITS -1
1583 def __init__(self,data=None):
1584 if not data: 1584 ↛ 1585line 1584 didn't jump to line 1585, because the condition on line 1584 was never true
1585 BitSet.__init__(self,[long(0)])
1586 return
1587 if isinstance(data,int): 1587 ↛ 1588line 1587 didn't jump to line 1588, because the condition on line 1587 was never true
1588 BitSet.__init__(self,[long(data)])
1589 return
1590 if isinstance(data,long): 1590 ↛ 1591line 1590 didn't jump to line 1591, because the condition on line 1590 was never true
1591 BitSet.__init__(self,[data])
1592 return
1593 if not isinstance(data,list): 1593 ↛ 1594line 1593 didn't jump to line 1594, because the condition on line 1593 was never true
1594 raise TypeError("BitSet requires integer, long, or " +
1595 "list argument")
1596 for x in data:
1597 if not isinstance(x, int_types): 1597 ↛ 1598line 1597 didn't jump to line 1598, because the condition on line 1597 was never true
1598 raise TypeError(self,"List argument item is " +
1599 "not a long: %s" % (x))
1600 self.data = data
1602 def __str__(self):
1603 bits = len(self.data) * BitSet.BITS
1604 s = ""
1605 for i in xrange(0,bits):
1606 if self.at(i):
1607 s += "1"
1608 else:
1609 s += "o"
1610 if not ((i+1) % 10):
1611 s += '|%s|' % (i+1)
1612 return s
1614 def __repr__(self):
1615 return str(self)
1617 def member(self,item):
1618 if not item:
1619 return False
1621 if isinstance(item,int):
1622 return self.at(item)
1624 if not is_string_type(item):
1625 raise TypeError(self,"char or unichar expected: %s" % (item))
1627 ## char is a (unicode) string with at most lenght 1, ie.
1628 ## a char.
1630 if len(item) != 1:
1631 raise TypeError(self,"char expected: %s" % (item))
1633 ### handle ASCII/UNICODE char
1634 num = ord(item)
1636 ### check whether position num is in bitset
1637 return self.at(num)
1639 def wordNumber(self,bit):
1640 return bit >> BitSet.LOG_BITS
1642 def bitMask(self,bit):
1643 pos = bit & BitSet.MOD_MASK ## bit mod BITS
1644 return (1 << pos)
1646 def set(self,bit,on=True):
1647 # grow bitset as required (use with care!)
1648 i = self.wordNumber(bit)
1649 mask = self.bitMask(bit)
1650 if i>=len(self.data):
1651 d = i - len(self.data) + 1
1652 for x in xrange(0,d):
1653 self.data.append(0)
1654 assert len(self.data) == i+1
1655 if on:
1656 self.data[i] |= mask
1657 else:
1658 self.data[i] &= (~mask)
1660 ### make add an alias for set
1661 add = set
1663 def off(self,bit,off=True):
1664 self.set(bit,not off)
1666 def at(self,bit):
1667 i = self.wordNumber(bit)
1668 v = self.data[i]
1669 m = self.bitMask(bit)
1670 return v & m
1673###xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx###
1674### some further funcs ###
1675###xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx###
1677def illegalarg_ex(func):
1678 raise ValueError(
1679 "%s is only valid if parser is built for debugging" %
1680 (func.func_name))
1682def runtime_ex(func):
1683 raise RuntimeError(
1684 "%s is only valid if parser is built for debugging" %
1685 (func.func_name))
1687###xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx###
1688### TokenBuffer ###
1689###xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx###
1691class TokenBuffer(object):
1692 def __init__(self,stream):
1693 self.input = stream
1694 self.nMarkers = 0
1695 self.markerOffset = 0
1696 self.numToConsume = 0
1697 self.queue = Queue()
1699 def reset(self) :
1700 self.nMarkers = 0
1701 self.markerOffset = 0
1702 self.numToConsume = 0
1703 self.queue.reset()
1705 def consume(self) :
1706 self.numToConsume += 1
1708 def fill(self, amount):
1709 self.syncConsume()
1710 while self.queue.length() < (amount + self.markerOffset):
1711 self.queue.append(self.input.nextToken())
1713 def getInput(self):
1714 return self.input
1716 def LA(self,k) :
1717 self.fill(k)
1718 return self.queue.elementAt(self.markerOffset + k - 1).type
1720 def LT(self,k) :
1721 self.fill(k)
1722 return self.queue.elementAt(self.markerOffset + k - 1)
1724 def mark(self) :
1725 self.syncConsume()
1726 self.nMarkers += 1
1727 return self.markerOffset
1729 def rewind(self,mark) :
1730 self.syncConsume()
1731 self.markerOffset = mark
1732 self.nMarkers -= 1
1734 def syncConsume(self) :
1735 while self.numToConsume > 0:
1736 if self.nMarkers > 0:
1737 # guess mode -- leave leading characters and bump offset.
1738 self.markerOffset += 1
1739 else:
1740 # normal mode -- remove first character
1741 self.queue.removeFirst()
1742 self.numToConsume -= 1
1744 def __str__(self):
1745 return "(%s,%s,%s,%s,%s)" % (
1746 self.input,
1747 self.nMarkers,
1748 self.markerOffset,
1749 self.numToConsume,
1750 self.queue)
1752 def __repr__(self):
1753 return str(self)
1755###xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx###
1756### ParserSharedInputState ###
1757###xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx###
1759class ParserSharedInputState(object):
1761 def __init__(self):
1762 self.input = None
1763 self.reset()
1765 def reset(self):
1766 self.guessing = 0
1767 self.filename = None
1768 if self.input:
1769 self.input.reset()
1771###xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx###
1772### Parser ###
1773###xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx###
1775class Parser(object):
1777 def __init__(self, *args, **kwargs):
1778 self.tokenNames = None
1779 self.returnAST = None
1780 self.astFactory = None
1781 self.tokenTypeToASTClassMap = {}
1782 self.ignoreInvalidDebugCalls = False
1783 self.traceDepth = 0
1784 if not args:
1785 self.inputState = ParserSharedInputState()
1786 return
1787 arg0 = args[0]
1788 assert isinstance(arg0,ParserSharedInputState)
1789 self.inputState = arg0
1790 return
1792 def getTokenTypeToASTClassMap(self):
1793 return self.tokenTypeToASTClassMap
1796 def addMessageListener(self, l):
1797 if not self.ignoreInvalidDebugCalls:
1798 illegalarg_ex(self.addMessageListener)
1800 def addParserListener(self,l) :
1801 if (not self.ignoreInvalidDebugCalls) :
1802 illegalarg_ex(self.addParserListener)
1804 def addParserMatchListener(self, l) :
1805 if (not self.ignoreInvalidDebugCalls) :
1806 illegalarg_ex(self.addParserMatchListener)
1808 def addParserTokenListener(self, l) :
1809 if (not self.ignoreInvalidDebugCalls):
1810 illegalarg_ex(self.addParserTokenListener)
1812 def addSemanticPredicateListener(self, l) :
1813 if (not self.ignoreInvalidDebugCalls):
1814 illegalarg_ex(self.addSemanticPredicateListener)
1816 def addSyntacticPredicateListener(self, l) :
1817 if (not self.ignoreInvalidDebugCalls):
1818 illegalarg_ex(self.addSyntacticPredicateListener)
1820 def addTraceListener(self, l) :
1821 if (not self.ignoreInvalidDebugCalls):
1822 illegalarg_ex(self.addTraceListener)
1824 def consume(self):
1825 raise NotImplementedError()
1827 def _consumeUntil_type(self,tokenType):
1828 while self.LA(1) != EOF_TYPE and self.LA(1) != tokenType:
1829 self.consume()
1831 def _consumeUntil_bitset(self, set):
1832 while self.LA(1) != EOF_TYPE and not set.member(self.LA(1)):
1833 self.consume()
1835 def consumeUntil(self,arg):
1836 if isinstance(arg,int):
1837 self._consumeUntil_type(arg)
1838 else:
1839 self._consumeUntil_bitset(arg)
1841 def defaultDebuggingSetup(self):
1842 pass
1844 def getAST(self) :
1845 return self.returnAST
1847 def getASTFactory(self) :
1848 return self.astFactory
1850 def getFilename(self) :
1851 return self.inputState.filename
1853 def getInputState(self) :
1854 return self.inputState
1856 def setInputState(self, state) :
1857 self.inputState = state
1859 def getTokenName(self,num) :
1860 return self.tokenNames[num]
1862 def getTokenNames(self) :
1863 return self.tokenNames
1865 def isDebugMode(self) :
1866 return self.false
1868 def LA(self, i):
1869 raise NotImplementedError()
1871 def LT(self, i):
1872 raise NotImplementedError()
1874 def mark(self):
1875 return self.inputState.input.mark()
1877 def _match_int(self,t):
1878 if (self.LA(1) != t):
1879 raise MismatchedTokenException(
1880 self.tokenNames, self.LT(1), t, False, self.getFilename())
1881 else:
1882 self.consume()
1884 def _match_set(self, b):
1885 if (not b.member(self.LA(1))):
1886 raise MismatchedTokenException(
1887 self.tokenNames,self.LT(1), b, False, self.getFilename())
1888 else:
1889 self.consume()
1891 def match(self,set) :
1892 if isinstance(set,int):
1893 self._match_int(set)
1894 return
1895 if isinstance(set,BitSet):
1896 self._match_set(set)
1897 return
1898 raise TypeError("Parser.match requires integer ot BitSet argument")
1900 def matchNot(self,t):
1901 if self.LA(1) == t:
1902 raise MismatchedTokenException(
1903 self.tokenNames, self.LT(1), t, True, self.getFilename())
1904 else:
1905 self.consume()
1907 def removeMessageListener(self, l) :
1908 if (not self.ignoreInvalidDebugCalls):
1909 runtime_ex(self.removeMessageListener)
1911 def removeParserListener(self, l) :
1912 if (not self.ignoreInvalidDebugCalls):
1913 runtime_ex(self.removeParserListener)
1915 def removeParserMatchListener(self, l) :
1916 if (not self.ignoreInvalidDebugCalls):
1917 runtime_ex(self.removeParserMatchListener)
1919 def removeParserTokenListener(self, l) :
1920 if (not self.ignoreInvalidDebugCalls):
1921 runtime_ex(self.removeParserTokenListener)
1923 def removeSemanticPredicateListener(self, l) :
1924 if (not self.ignoreInvalidDebugCalls):
1925 runtime_ex(self.removeSemanticPredicateListener)
1927 def removeSyntacticPredicateListener(self, l) :
1928 if (not self.ignoreInvalidDebugCalls):
1929 runtime_ex(self.removeSyntacticPredicateListener)
1931 def removeTraceListener(self, l) :
1932 if (not self.ignoreInvalidDebugCalls):
1933 runtime_ex(self.removeTraceListener)
1935 def reportError(self,x) :
1936 fmt = "syntax error:"
1937 f = self.getFilename()
1938 if f:
1939 fmt = ("%s:" % f) + fmt
1940 if isinstance(x,Token):
1941 line = x.getColumn()
1942 col = x.getLine()
1943 text = x.getText()
1944 fmt = fmt + 'unexpected symbol at line %s (column %s) : "%s"'
1945 print(fmt % (line,col,text), file=sys.stderr)
1946 else:
1947 print(fmt,str(x), file=sys.stderr)
1949 def reportWarning(self,s):
1950 f = self.getFilename()
1951 if f:
1952 print("%s:warning: %s" % (f,str(s)))
1953 else:
1954 print("warning: %s" % (str(s)))
1956 def rewind(self, pos) :
1957 self.inputState.input.rewind(pos)
1959 def setASTFactory(self, f) :
1960 self.astFactory = f
1962 def setASTNodeClass(self, cl) :
1963 self.astFactory.setASTNodeType(cl)
1965 def setASTNodeType(self, nodeType) :
1966 self.setASTNodeClass(nodeType)
1968 def setDebugMode(self, debugMode) :
1969 if (not self.ignoreInvalidDebugCalls):
1970 runtime_ex(self.setDebugMode)
1972 def setFilename(self, f) :
1973 self.inputState.filename = f
1975 def setIgnoreInvalidDebugCalls(self, value) :
1976 self.ignoreInvalidDebugCalls = value
1978 def setTokenBuffer(self, t) :
1979 self.inputState.input = t
1981 def traceIndent(self):
1982 print(" " * self.traceDepth)
1984 def traceIn(self,rname):
1985 self.traceDepth += 1
1986 self.trace("> ", rname)
1988 def traceOut(self,rname):
1989 self.trace("< ", rname)
1990 self.traceDepth -= 1
1992 ### wh: moved from ASTFactory to Parser
1993 def addASTChild(self,currentAST, child):
1994 if not child:
1995 return
1996 if not currentAST.root:
1997 currentAST.root = child
1998 elif not currentAST.child:
1999 currentAST.root.setFirstChild(child)
2000 else:
2001 currentAST.child.setNextSibling(child)
2002 currentAST.child = child
2003 currentAST.advanceChildToEnd()
2005 ### wh: moved from ASTFactory to Parser
2006 def makeASTRoot(self,currentAST,root) :
2007 if root:
2008 ### Add the current root as a child of new root
2009 root.addChild(currentAST.root)
2010 ### The new current child is the last sibling of the old root
2011 currentAST.child = currentAST.root
2012 currentAST.advanceChildToEnd()
2013 ### Set the new root
2014 currentAST.root = root
2016###xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx###
2017### LLkParser ###
2018###xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx###
2020class LLkParser(Parser):
2022 def __init__(self, *args, **kwargs):
2023 try:
2024 arg1 = args[0]
2025 except:
2026 arg1 = 1
2028 if isinstance(arg1,int):
2029 super(LLkParser,self).__init__()
2030 self.k = arg1
2031 return
2033 if isinstance(arg1,ParserSharedInputState):
2034 super(LLkParser,self).__init__(arg1)
2035 self.set_k(1,*args)
2036 return
2038 if isinstance(arg1,TokenBuffer):
2039 super(LLkParser,self).__init__()
2040 self.setTokenBuffer(arg1)
2041 self.set_k(1,*args)
2042 return
2044 if isinstance(arg1,TokenStream):
2045 super(LLkParser,self).__init__()
2046 tokenBuf = TokenBuffer(arg1)
2047 self.setTokenBuffer(tokenBuf)
2048 self.set_k(1,*args)
2049 return
2051 ### unknown argument
2052 raise TypeError("LLkParser requires integer, " +
2053 "ParserSharedInputStream or TokenStream argument")
2055 def consume(self):
2056 self.inputState.input.consume()
2058 def LA(self,i):
2059 return self.inputState.input.LA(i)
2061 def LT(self,i):
2062 return self.inputState.input.LT(i)
2064 def set_k(self,index,*args):
2065 try:
2066 self.k = args[index]
2067 except:
2068 self.k = 1
2070 def trace(self,ee,rname):
2071 print(type(self))
2072 self.traceIndent()
2073 guess = ""
2074 if self.inputState.guessing > 0:
2075 guess = " [guessing]"
2076 print((ee + rname + guess))
2077 for i in xrange(1,self.k+1):
2078 if i != 1:
2079 print(", ")
2080 if self.LT(i) :
2081 v = self.LT(i).getText()
2082 else:
2083 v = "null"
2084 print("LA(%s) == %s" % (i,v))
2085 print("\n")
2087 def traceIn(self,rname):
2088 self.traceDepth += 1;
2089 self.trace("> ", rname);
2091 def traceOut(self,rname):
2092 self.trace("< ", rname);
2093 self.traceDepth -= 1;
2095###xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx###
2096### TreeParserSharedInputState ###
2097###xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx###
2099class TreeParserSharedInputState(object):
2100 def __init__(self):
2101 self.guessing = 0
2103###xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx###
2104### TreeParser ###
2105###xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx###
2107class TreeParser(object):
2109 def __init__(self, *args, **kwargs):
2110 self.inputState = TreeParserSharedInputState()
2111 self._retTree = None
2112 self.tokenNames = []
2113 self.returnAST = None
2114 self.astFactory = ASTFactory()
2115 self.traceDepth = 0
2117 def getAST(self):
2118 return self.returnAST
2120 def getASTFactory(self):
2121 return self.astFactory
2123 def getTokenName(self,num) :
2124 return self.tokenNames[num]
2126 def getTokenNames(self):
2127 return self.tokenNames
2129 def match(self,t,set) :
2130 assert isinstance(set,int) or isinstance(set,BitSet)
2131 if not t or t == ASTNULL:
2132 raise MismatchedTokenException(self.getTokenNames(), t,set, False)
2134 if isinstance(set,int) and t.getType() != set:
2135 raise MismatchedTokenException(self.getTokenNames(), t,set, False)
2137 if isinstance(set,BitSet) and not set.member(t.getType):
2138 raise MismatchedTokenException(self.getTokenNames(), t,set, False)
2140 def matchNot(self,t, ttype) :
2141 if not t or (t == ASTNULL) or (t.getType() == ttype):
2142 raise MismatchedTokenException(self.getTokenNames(), t, ttype, True)
2144 def reportError(self,ex):
2145 print("error:",ex, file=sys.stderr)
2147 def reportWarning(self, s):
2148 print("warning:",s)
2150 def setASTFactory(self,f):
2151 self.astFactory = f
2153 def setASTNodeType(self,nodeType):
2154 self.setASTNodeClass(nodeType)
2156 def setASTNodeClass(self,nodeType):
2157 self.astFactory.setASTNodeType(nodeType)
2159 def traceIndent(self):
2160 print(" " * self.traceDepth)
2162 def traceIn(self,rname,t):
2163 self.traceDepth += 1
2164 self.traceIndent()
2165 print(("> " + rname + "(" +
2166 ifelse(t,str(t),"null") + ")" +
2167 ifelse(self.inputState.guessing>0,"[guessing]","")))
2169 def traceOut(self,rname,t):
2170 self.traceIndent()
2171 print(("< " + rname + "(" +
2172 ifelse(t,str(t),"null") + ")" +
2173 ifelse(self.inputState.guessing>0,"[guessing]","")))
2174 self.traceDepth -= 1
2176 ### wh: moved from ASTFactory to TreeParser
2177 def addASTChild(self,currentAST, child):
2178 if not child:
2179 return
2180 if not currentAST.root:
2181 currentAST.root = child
2182 elif not currentAST.child:
2183 currentAST.root.setFirstChild(child)
2184 else:
2185 currentAST.child.setNextSibling(child)
2186 currentAST.child = child
2187 currentAST.advanceChildToEnd()
2189 ### wh: moved from ASTFactory to TreeParser
2190 def makeASTRoot(self,currentAST,root):
2191 if root:
2192 ### Add the current root as a child of new root
2193 root.addChild(currentAST.root)
2194 ### The new current child is the last sibling of the old root
2195 currentAST.child = currentAST.root
2196 currentAST.advanceChildToEnd()
2197 ### Set the new root
2198 currentAST.root = root
2200###xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx###
2201### funcs to work on trees ###
2202###xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx###
2204def rightmost(ast):
2205 if ast:
2206 while(ast.right):
2207 ast = ast.right
2208 return ast
2210def cmptree(s,t,partial):
2211 while(s and t):
2212 ### as a quick optimization, check roots first.
2213 if not s.equals(t):
2214 return False
2216 ### if roots match, do full list match test on children.
2217 if not cmptree(s.getFirstChild(),t.getFirstChild(),partial):
2218 return False
2220 s = s.getNextSibling()
2221 t = t.getNextSibling()
2223 r = ifelse(partial,not t,not s and not t)
2224 return r
2226###xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx###
2227### AST ###
2228###xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx###
2230class AST(object):
2231 def __init__(self):
2232 pass
2234 def addChild(self, c):
2235 pass
2237 def equals(self, t):
2238 return False
2240 def equalsList(self, t):
2241 return False
2243 def equalsListPartial(self, t):
2244 return False
2246 def equalsTree(self, t):
2247 return False
2249 def equalsTreePartial(self, t):
2250 return False
2252 def findAll(self, tree):
2253 return None
2255 def findAllPartial(self, subtree):
2256 return None
2258 def getFirstChild(self):
2259 return self
2261 def getNextSibling(self):
2262 return self
2264 def getText(self):
2265 return ""
2267 def getType(self):
2268 return INVALID_TYPE
2270 def getLine(self):
2271 return 0
2273 def getColumn(self):
2274 return 0
2276 def getNumberOfChildren(self):
2277 return 0
2279 def initialize(self, t):
2280 pass
2282 def setFirstChild(self, c):
2283 pass
2285 def setNextSibling(self, n):
2286 pass
2288 def setText(self, text):
2289 pass
2291 def setType(self, ttype):
2292 pass
2294 def toString(self):
2295 self.getText()
2297 __str__ = toString
2299 def toStringList(self):
2300 return self.getText()
2302 def toStringTree(self):
2303 return self.getText()
2305###xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx###
2306### ASTNULLType ###
2307###xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx###
2309### There is only one instance of this class **/
2310class ASTNULLType(AST):
2311 def __init__(self):
2312 AST.__init__(self)
2313 pass
2315 def getText(self):
2316 return "<ASTNULL>"
2318 def getType(self):
2319 return NULL_TREE_LOOKAHEAD
2322###xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx###
2323### BaseAST ###
2324###xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx###
2326class BaseAST(AST):
2328 verboseStringConversion = False
2329 tokenNames = None
2331 def __init__(self):
2332 self.down = None ## kid
2333 self.right = None ## sibling
2335 def addChild(self,node):
2336 if node:
2337 t = rightmost(self.down)
2338 if t:
2339 t.right = node
2340 else:
2341 assert not self.down
2342 self.down = node
2344 def getNumberOfChildren(self):
2345 t = self.down
2346 n = 0
2347 while t:
2348 n += 1
2349 t = t.right
2350 return n
2352 def doWorkForFindAll(self,v,target,partialMatch):
2353 sibling = self
2355 while sibling:
2356 c1 = partialMatch and sibling.equalsTreePartial(target)
2357 if c1:
2358 v.append(sibling)
2359 else:
2360 c2 = not partialMatch and sibling.equalsTree(target)
2361 if c2:
2362 v.append(sibling)
2364 ### regardless of match or not, check any children for matches
2365 if sibling.getFirstChild():
2366 sibling.getFirstChild().doWorkForFindAll(v,target,partialMatch)
2368 sibling = sibling.getNextSibling()
2370 ### Is node t equal to 'self' in terms of token type and text?
2371 def equals(self,t):
2372 if not t:
2373 return False
2374 return self.getText() == t.getText() and self.getType() == t.getType()
2376 ### Is t an exact structural and equals() match of this tree. The
2377 ### 'self' reference is considered the start of a sibling list.
2378 ###
2379 def equalsList(self, t):
2380 return cmptree(self, t, partial=False)
2382 ### Is 't' a subtree of this list?
2383 ### The siblings of the root are NOT ignored.
2384 ###
2385 def equalsListPartial(self,t):
2386 return cmptree(self,t,partial=True)
2388 ### Is tree rooted at 'self' equal to 't'? The siblings
2389 ### of 'self' are ignored.
2390 ###
2391 def equalsTree(self, t):
2392 return self.equals(t) and \
2393 cmptree(self.getFirstChild(), t.getFirstChild(), partial=False)
2395 ### Is 't' a subtree of the tree rooted at 'self'? The siblings
2396 ### of 'self' are ignored.
2397 ###
2398 def equalsTreePartial(self, t):
2399 if not t:
2400 return True
2401 return self.equals(t) and cmptree(
2402 self.getFirstChild(), t.getFirstChild(), partial=True)
2404 ### Walk the tree looking for all exact subtree matches. Return
2405 ### an ASTEnumerator that lets the caller walk the list
2406 ### of subtree roots found herein.
2407 def findAll(self,target):
2408 roots = []
2410 ### the empty tree cannot result in an enumeration
2411 if not target:
2412 return None
2413 # find all matches recursively
2414 self.doWorkForFindAll(roots, target, False)
2415 return roots
2417 ### Walk the tree looking for all subtrees. Return
2418 ### an ASTEnumerator that lets the caller walk the list
2419 ### of subtree roots found herein.
2420 def findAllPartial(self,sub):
2421 roots = []
2423 ### the empty tree cannot result in an enumeration
2424 if not sub:
2425 return None
2427 self.doWorkForFindAll(roots, sub, True) ### find all matches recursively
2428 return roots
2430 ### Get the first child of this node None if not children
2431 def getFirstChild(self):
2432 return self.down
2434 ### Get the next sibling in line after this one
2435 def getNextSibling(self):
2436 return self.right
2438 ### Get the token text for this node
2439 def getText(self):
2440 return ""
2442 ### Get the token type for this node
2443 def getType(self):
2444 return 0
2446 def getLine(self):
2447 return 0
2449 def getColumn(self):
2450 return 0
2452 ### Remove all children */
2453 def removeChildren(self):
2454 self.down = None
2456 def setFirstChild(self,c):
2457 self.down = c
2459 def setNextSibling(self, n):
2460 self.right = n
2462 ### Set the token text for this node
2463 def setText(self, text):
2464 pass
2466 ### Set the token type for this node
2467 def setType(self, ttype):
2468 pass
2470 ### static
2471 def setVerboseStringConversion(verbose,names):
2472 verboseStringConversion = verbose
2473 tokenNames = names
2474 setVerboseStringConversion = staticmethod(setVerboseStringConversion)
2476 ### Return an array of strings that maps token ID to it's text.
2477 ## @since 2.7.3
2478 def getTokenNames():
2479 return tokenNames
2481 def toString(self):
2482 return self.getText()
2484 ### return tree as lisp string - sibling included
2485 def toStringList(self):
2486 ts = self.toStringTree()
2487 sib = self.getNextSibling()
2488 if sib:
2489 ts += sib.toStringList()
2490 return ts
2492 __str__ = toStringList
2494 ### return tree as string - siblings ignored
2495 def toStringTree(self):
2496 ts = ""
2497 kid = self.getFirstChild()
2498 if kid:
2499 ts += " ("
2500 ts += " " + self.toString()
2501 if kid:
2502 ts += kid.toStringList()
2503 ts += " )"
2504 return ts
2506###xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx###
2507### CommonAST ###
2508###xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx###
2510### Common AST node implementation
2511class CommonAST(BaseAST):
2512 def __init__(self,token=None):
2513 super(CommonAST,self).__init__()
2514 self.ttype = INVALID_TYPE
2515 self.text = "<no text>"
2516 self.line = 0
2517 self.column= 0
2518 self.initialize(token)
2519 #assert self.text
2521 ### Get the token text for this node
2522 def getText(self):
2523 return self.text
2525 ### Get the token type for this node
2526 def getType(self):
2527 return self.ttype
2529 ### Get the line for this node
2530 def getLine(self):
2531 return self.line
2533 ### Get the column for this node
2534 def getColumn(self):
2535 return self.column
2537 def initialize(self,*args):
2538 if not args:
2539 return
2541 arg0 = args[0]
2543 if isinstance(arg0,int):
2544 arg1 = args[1]
2545 self.setType(arg0)
2546 self.setText(arg1)
2547 return
2549 if isinstance(arg0,AST) or isinstance(arg0,Token):
2550 self.setText(arg0.getText())
2551 self.setType(arg0.getType())
2552 self.line = arg0.getLine()
2553 self.column = arg0.getColumn()
2554 return
2556 ### Set the token text for this node
2557 def setText(self,text_):
2558 assert is_string_type(text_)
2559 self.text = text_
2561 ### Set the token type for this node
2562 def setType(self,ttype_):
2563 assert isinstance(ttype_,int)
2564 self.ttype = ttype_
2566###xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx###
2567### CommonASTWithHiddenTokens ###
2568###xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx###
2570class CommonASTWithHiddenTokens(CommonAST):
2572 def __init__(self,*args):
2573 CommonAST.__init__(self,*args)
2574 self.hiddenBefore = None
2575 self.hiddenAfter = None
2577 def getHiddenAfter(self):
2578 return self.hiddenAfter
2580 def getHiddenBefore(self):
2581 return self.hiddenBefore
2583 def initialize(self,*args):
2584 CommonAST.initialize(self,*args)
2585 if args and isinstance(args[0],Token):
2586 assert isinstance(args[0],CommonHiddenStreamToken)
2587 self.hiddenBefore = args[0].getHiddenBefore()
2588 self.hiddenAfter = args[0].getHiddenAfter()
2590###xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx###
2591### ASTPair ###
2592###xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx###
2594class ASTPair(object):
2595 def __init__(self):
2596 self.root = None ### current root of tree
2597 self.child = None ### current child to which siblings are added
2599 ### Make sure that child is the last sibling */
2600 def advanceChildToEnd(self):
2601 if self.child:
2602 while self.child.getNextSibling():
2603 self.child = self.child.getNextSibling()
2605 ### Copy an ASTPair. Don't call it clone() because we want type-safety */
2606 def copy(self):
2607 tmp = ASTPair()
2608 tmp.root = self.root
2609 tmp.child = self.child
2610 return tmp
2612 def toString(self):
2613 r = ifelse(not root,"null",self.root.getText())
2614 c = ifelse(not child,"null",self.child.getText())
2615 return "[%s,%s]" % (r,c)
2617 __str__ = toString
2618 __repr__ = toString
2621###xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx###
2622### ASTFactory ###
2623###xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx###
2625class ASTFactory(object):
2626 def __init__(self,table=None):
2627 self._class = None
2628 self._classmap = ifelse(table,table,None)
2630 def create(self,*args):
2631 if not args:
2632 return self.create(INVALID_TYPE)
2634 arg0 = args[0]
2635 arg1 = None
2636 arg2 = None
2638 try:
2639 arg1 = args[1]
2640 arg2 = args[2]
2641 except:
2642 pass
2644 # ctor(int)
2645 if isinstance(arg0,int) and not arg2:
2646 ### get class for 'self' type
2647 c = self.getASTNodeType(arg0)
2648 t = self.create(c)
2649 if t:
2650 t.initialize(arg0, ifelse(arg1,arg1,""))
2651 return t
2653 # ctor(int,something)
2654 if isinstance(arg0,int) and arg2:
2655 t = self.create(arg2)
2656 if t:
2657 t.initialize(arg0,arg1)
2658 return t
2660 # ctor(AST)
2661 if isinstance(arg0,AST):
2662 t = self.create(arg0.getType())
2663 if t:
2664 t.initialize(arg0)
2665 return t
2667 # ctor(token)
2668 if isinstance(arg0,Token) and not arg1:
2669 ttype = arg0.getType()
2670 assert isinstance(ttype,int)
2671 t = self.create(ttype)
2672 if t:
2673 t.initialize(arg0)
2674 return t
2676 # ctor(token,class)
2677 if isinstance(arg0,Token) and arg1:
2678 assert isinstance(arg1,type)
2679 assert issubclass(arg1,AST)
2680 # this creates instance of 'arg1' using 'arg0' as
2681 # argument. Wow, that's magic!
2682 t = arg1(arg0)
2683 assert t and isinstance(t,AST)
2684 return t
2686 # ctor(class)
2687 if isinstance(arg0,type):
2688 ### next statement creates instance of type (!)
2689 t = arg0()
2690 assert isinstance(t,AST)
2691 return t
2694 def setASTNodeClass(self,className=None):
2695 if not className:
2696 return
2697 assert isinstance(className,type)
2698 assert issubclass(className,AST)
2699 self._class = className
2701 ### kind of misnomer - use setASTNodeClass instead.
2702 setASTNodeType = setASTNodeClass
2704 def getASTNodeClass(self):
2705 return self._class
2709 def getTokenTypeToASTClassMap(self):
2710 return self._classmap
2712 def setTokenTypeToASTClassMap(self,amap):
2713 self._classmap = amap
2715 def error(self, e):
2716 import sys
2717 print(e, file=sys.stderr)
2719 def setTokenTypeASTNodeType(self, tokenType, className):
2720 """
2721 Specify a mapping between a token type and a (AST) class.
2722 """
2723 if not self._classmap:
2724 self._classmap = {}
2726 if not className:
2727 try:
2728 del self._classmap[tokenType]
2729 except:
2730 pass
2731 else:
2732 ### here we should also perform actions to ensure that
2733 ### a. class can be loaded
2734 ### b. class is a subclass of AST
2735 ###
2736 assert isinstance(className,type)
2737 assert issubclass(className,AST) ## a & b
2738 ### enter the class
2739 self._classmap[tokenType] = className
2741 def getASTNodeType(self,tokenType):
2742 """
2743 For a given token type return the AST node type. First we
2744 lookup a mapping table, second we try _class
2745 and finally we resolve to "antlr.CommonAST".
2746 """
2748 # first
2749 if self._classmap:
2750 try:
2751 c = self._classmap[tokenType]
2752 if c:
2753 return c
2754 except:
2755 pass
2756 # second
2757 if self._class:
2758 return self._class
2760 # default
2761 return CommonAST
2763 ### methods that have been moved to file scope - just listed
2764 ### here to be somewhat consistent with original API
2765 def dup(self,t):
2766 return dup(t,self)
2768 def dupList(self,t):
2769 return dupList(t,self)
2771 def dupTree(self,t):
2772 return dupTree(t,self)
2774 ### methods moved to other classes
2775 ### 1. makeASTRoot -> Parser
2776 ### 2. addASTChild -> Parser
2778 ### non-standard: create alias for longish method name
2779 maptype = setTokenTypeASTNodeType
2781###xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx###
2782### ASTVisitor ###
2783###xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx###
2785class ASTVisitor(object):
2786 def __init__(self,*args):
2787 pass
2789 def visit(self,ast):
2790 pass
2792###xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx###
2793### static methods and variables ###
2794###xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx###
2796ASTNULL = ASTNULLType()
2798### wh: moved from ASTFactory as there's nothing ASTFactory-specific
2799### in this method.
2800def make(*nodes):
2801 if not nodes:
2802 return None
2804 for i in xrange(0,len(nodes)):
2805 node = nodes[i]
2806 if node:
2807 assert isinstance(node,AST)
2809 root = nodes[0]
2810 tail = None
2811 if root:
2812 root.setFirstChild(None)
2814 for i in xrange(1,len(nodes)):
2815 if not nodes[i]:
2816 continue
2817 if not root:
2818 root = tail = nodes[i]
2819 elif not tail:
2820 root.setFirstChild(nodes[i])
2821 tail = root.getFirstChild()
2822 else:
2823 tail.setNextSibling(nodes[i])
2824 tail = tail.getNextSibling()
2826 ### Chase tail to last sibling
2827 while tail.getNextSibling():
2828 tail = tail.getNextSibling()
2829 return root
2831def dup(t,factory):
2832 if not t:
2833 return None
2835 if factory:
2836 dup_t = factory.create(t.__class__)
2837 else:
2838 raise TypeError("dup function requires ASTFactory argument")
2839 dup_t.initialize(t)
2840 return dup_t
2842def dupList(t,factory):
2843 result = dupTree(t,factory)
2844 nt = result
2845 while t:
2846 ## for each sibling of the root
2847 t = t.getNextSibling()
2848 nt.setNextSibling(dupTree(t,factory))
2849 nt = nt.getNextSibling()
2850 return result
2852def dupTree(t,factory):
2853 result = dup(t,factory)
2854 if t:
2855 result.setFirstChild(dupList(t.getFirstChild(),factory))
2856 return result
2858###xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
2859### $Id$
2861# Local Variables: ***
2862# mode: python ***
2863# py-indent-offset: 4 ***
2864# End: ***