def __init__(self, filename): self.scanner = Scanner(filename) self.current_token = None self.current_word = None
class Parser(object): _symbols = dict(SYMBOLS) _reserved_words = dict(reserved_words) def __init__(self, filename): self.scanner = Scanner(filename) self.current_token = None self.current_word = None @staticmethod def _is_valid_identifier(var_name): if not var_name: return False return var_name[0].isalpha() and var_name.isalnum() def get_next_token(self): self.current_word = self.scanner.get_word().lower() self.current_token = self._lookup_token(self.current_word) return self.current_token def _lookup_token(self, word): if not word: return None token = self._get_double_symbol(word) if token: return token token = self._symbols.get(word, None) or self._reserved_words.get(word, None) if token: return token if word.isdigit(): return TK_A_DIGIT if word in ['true', 'false']: return TK_A_BOOL if self._is_valid_identifier(word): return TK_IDENTIFIER return '' def _get_double_symbol(self, word): if word in double_symbol: peek = self.scanner.peek_char() new_word = str(word+peek) if new_word in self._symbols: self.scanner.get_word() self.current_word = new_word return self._symbols.get(new_word) else: return self._symbols.get(word) return None def is_done(self): return self.scanner.eof def is_real(self): if self.current_token != TK_A_DIGIT: return False number = self.current_word if self.scanner.peek_char() == ".": if not self.get_next_token() == TK_DOT: raise ValueError("Invalid Digit: '%s'" % str(number)+self.current_word) self.get_next_token() if self.current_token != TK_A_DIGIT: raise ValueError("Invalid Digit: '%s'" % str(number)+self.current_word) self.current_word = number+'.'+self.current_word self.current_token = TK_A_REAL return True else: self.current_token = TK_AN_INTEGER return False def print_token(self, token=None): if not token: token = self.current_token return token_map.get(token, "Unknown")