<s> import os <EOL> def gets ( prompt = None ) : <EOL> prompt = "<STR_LIT>" % ( prompt or "<STR_LIT:%>" ) <EOL> if hasattr ( __builtins__ , "<STR_LIT>" ) : <EOL> return raw_input ( prompt ) <EOL> elif hasattr ( __builtins__ , "<STR_LIT:input>" ) : <EOL> return input ( prompt ) <EOL> else : <EOL> raise NotImplementedError <EOL> class ParserError ( Exception ) : <EOL> pass <EOL> class Stack ( list ) : <EOL> def push ( self , * items ) : <EOL> return self . extend ( items ) <EOL> @ property <EOL> def last ( self ) : <EOL> return self [ - <NUM_LIT:1> ] <EOL> @ last . setter <EOL> def last ( self , value ) : <EOL> self [ - <NUM_LIT:1> ] = value <EOL> def prev ( self , n = <NUM_LIT:1> ) : <EOL> return self [ - <NUM_LIT:1> - n ] <EOL> class Parser ( object ) : <EOL> escapes = { <EOL> "<STR_LIT:e>" : "<STR_LIT>" , <EOL> "<STR_LIT:n>" : "<STR_LIT:\n>" , <EOL> "<STR_LIT:t>" : "<STR_LIT:\t>" , <EOL> } <EOL> parse_bquoted = True <EOL> def __init__ ( self ) : <EOL> self . reset ( ) <EOL> def reset ( self ) : <EOL> self . state = Stack ( [ "<STR_LIT>" ] ) <EOL> self . cur = "<STR_LIT>" <EOL> self . words = [ ] <EOL> self . append = False <EOL> return True <EOL> def feed ( self , line , multiline = True ) : <EOL> i = <NUM_LIT:0> <EOL> append = False <EOL> done = True <EOL> variables = os . environ <EOL> while i <= len ( line ) : <EOL> char = line [ i ] if i < len ( line ) else None <EOL> if self . state . last == "<STR_LIT>" : <EOL> if not char or char . isspace ( ) : <EOL> if self . cur or append : <EOL> self . words . append ( self . cur ) <EOL> self . cur = "<STR_LIT>" <EOL> append = False <EOL> elif char == "<STR_LIT>" : <EOL> self . state . push ( "<STR_LIT>" ) <EOL> elif char == "<STR_LIT:'>" : <EOL> self . state . push ( "<STR_LIT>" ) <EOL> elif char == "<STR_LIT:{>" and self . parse_bquoted : <EOL> self . state . push ( "<STR_LIT>" ) <EOL> elif char == "<STR_LIT:\\>" : <EOL> self . state . push ( "<STR_LIT>" ) <EOL> elif char == "<STR_LIT:$>" and variables is not None : <EOL> token = "<STR_LIT>" <EOL> self . state . push ( "<STR_LIT>" ) <EOL> else : <EOL> self . cur += char <EOL> elif self . state . last == "<STR_LIT>" : <EOL> if not char : <EOL> done = False <EOL> i -= <NUM_LIT:1> <EOL> self . state . pop ( ) <EOL> elif char == "<STR_LIT:x>" : <EOL> token = "<STR_LIT>" <EOL> self . state . last = "<STR_LIT>" <EOL> elif char in "<STR_LIT>" : <EOL> token = char <EOL> self . state . last = "<STR_LIT>" <EOL> elif char in self . escapes : <EOL> self . cur += self . escapes [ char ] <EOL> append = True <EOL> self . state . pop ( ) <EOL> else : <EOL> self . cur += char <EOL> self . state . pop ( ) <EOL> elif self . state . last == "<STR_LIT>" : <EOL> if char and char in "<STR_LIT>" : <EOL> token += char <EOL> if len ( token ) == <NUM_LIT:2> : <EOL> self . cur += chr ( int ( token , <NUM_LIT:16> ) ) <EOL> self . state . pop ( ) <EOL> else : <EOL> raise ParserError ( "<STR_LIT>" % char ) <EOL> elif self . state . last == "<STR_LIT>" : <EOL> if char and char in "<STR_LIT>" and len ( token ) < <NUM_LIT:3> : <EOL> token += char <EOL> else : <EOL> self . cur += chr ( int ( token , <NUM_LIT:8> ) ) <EOL> i -= <NUM_LIT:1> <EOL> self . state . pop ( ) <EOL> elif self . state . last == "<STR_LIT>" : <EOL> if char == "<STR_LIT>" : <EOL> append = True <EOL> self . state . pop ( ) <EOL> elif char == "<STR_LIT:\\>" : <EOL> self . state . push ( "<STR_LIT>" ) <EOL> elif char == "<STR_LIT:$>" and variables is not None : <EOL> token = "<STR_LIT>" <EOL> self . state . push ( "<STR_LIT>" ) <EOL> elif char : <EOL> self . cur += char <EOL> elif multiline : <EOL> done = False <EOL> break <EOL> else : <EOL> raise ParserError ( "<STR_LIT>" ) <EOL> elif self . state . last == "<STR_LIT>" : <EOL> if char == "<STR_LIT:'>" : <EOL> append = True <EOL> self . state . pop ( ) <EOL> elif char : <EOL> self . cur += char <EOL> elif multiline : <EOL> done = False <EOL> break <EOL> else : <EOL> raise ParserError ( "<STR_LIT>" ) <EOL> elif self . state . last == "<STR_LIT>" : <EOL> if char == "<STR_LIT:}>" : <EOL> if self . state . prev ( <NUM_LIT:1> ) == "<STR_LIT>" : <EOL> self . cur += char <EOL> append = True <EOL> self . state . pop ( ) <EOL> elif char == "<STR_LIT:{>" : <EOL> self . cur += char <EOL> state . push ( "<STR_LIT>" ) <EOL> elif char == "<STR_LIT:\\>" : <EOL> state . push ( "<STR_LIT>" ) <EOL> elif char : <EOL> self . cur += char <EOL> else : <EOL> done = False <EOL> break <EOL> elif self . state . last == "<STR_LIT>" : <EOL> var = None <EOL> if char and char in "<STR_LIT>" "<STR_LIT>" "<STR_LIT>" : <EOL> token += char <EOL> elif char == "<STR_LIT:$>" and not token : <EOL> var = str ( os . getpid ( ) ) <EOL> elif char == "<STR_LIT:{>" and not token : <EOL> token += char <EOL> elif token and token [ <NUM_LIT:0> ] == "<STR_LIT:{>" : <EOL> if char == "<STR_LIT:}>" : <EOL> var = variables . get ( token [ <NUM_LIT:1> : ] , "<STR_LIT>" ) <EOL> elif multiline : <EOL> done = False <EOL> break <EOL> else : <EOL> raise ParserError ( "<STR_LIT>" ) <EOL> else : <EOL> i -= <NUM_LIT:1> <EOL> var = variables . get ( token , "<STR_LIT>" ) <EOL> if var is not None : <EOL> if self . state . prev ( ) == "<STR_LIT>" : <EOL> var = ( self . cur + var ) . split ( ) <EOL> if var : <EOL> self . cur = var . pop ( ) <EOL> for token in var : <EOL> if token or append : <EOL> self . words . append ( token ) <EOL> append = False <EOL> else : <EOL> self . cur += var <EOL> self . state . pop ( ) <EOL> i += <NUM_LIT:1> <EOL> if not multiline : <EOL> done = True <EOL> if not done : <EOL> err = None <EOL> elif not self . state or self . state . last == "<STR_LIT>" : <EOL> err = None <EOL> elif self . state . last in ( "<STR_LIT>" , "<STR_LIT>" ) : <EOL> raise ParserError ( "<STR_LIT>" ) <EOL> elif self . state . last == "<STR_LIT>" : <EOL> raise ParserError ( "<STR_LIT>" ) <EOL> elif self . state . last == "<STR_LIT>" : <EOL> raise ParserError ( "<STR_LIT>" ) <EOL> elif self . state . last == "<STR_LIT>" : <EOL> raise ParserError ( "<STR_LIT>" ) <EOL> else : <EOL> raise ParserError ( "<STR_LIT:foo>" ) <EOL> if done : <EOL> return self . words , self . reset ( ) <EOL> else : <EOL> return self . words , False <EOL> line = "<STR_LIT>" <EOL> done = True <EOL> parser = Parser ( ) <EOL> while True : <EOL> if done : <EOL> line = gets ( "<STR_LIT:%>" ) <EOL> else : <EOL> line = "<STR_LIT:\n>" + gets ( "<STR_LIT>" ) <EOL> try : <EOL> words , done = parser . feed ( line ) <EOL> except ParserError as e : <EOL> print ( "<STR_LIT>" , e ) <EOL> else : <EOL> print ( words , done ) </s>
