예제 #1
0
 def __init__(self, filename):
     self.scanner = Scanner(filename)
     self.current_token = None
     self.current_word = None
예제 #2
0
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")