Beispiel #1
0
    def __init__(self,
                 print_table=False,
                 table_logfile='log_symbol_table.txt',
                 print_tokens=False, print_source_scanner=True,
                 scanner_logfile='log_scanner_tokens.txt',
                 print_productions=False, print_source_parser=False, print_info=False,
                 parser_logfile=sys.stdout,
                 print_warnings=False,
                 **kwargs):

        # Initialize variables
        self.source_code = None
        self.source_lines = None

        # Initialize table
        self.symbol_table = SymbolTable()

        # Initialize symbol table logger
        if table_logfile in {sys.stdout, sys.stderr}:
            self.symbol_table_logger = Logger(table_logfile)
        else:
            self.symbol_table_logger = Logger(open(table_logfile, 'w'))

        if print_table:
            self.symbol_table_logger.add_switch(Logger.SYMBOL_TABLE)

        # Initialize token/lexer logger
        if scanner_logfile in {sys.stdout, sys.stderr}:
            self.token_logger = Logger(scanner_logfile)
        else:
            self.token_logger = Logger(open(scanner_logfile, 'w'))

        if print_source_scanner:
            self.token_logger.add_switch(Logger.SOURCE)

        if print_tokens:
            self.token_logger.add_switch(Logger.TOKEN)

        # Initialize parser logger
        if parser_logfile in {sys.stdout, sys.stderr}:
            self.parser_logger = Logger(parser_logfile)
        else:
            self.parser_logger = Logger(open(parser_logfile, 'w'))

        if print_source_parser:
            self.parser_logger.add_switch(Logger.SOURCE)

        if print_productions:
            self.parser_logger.add_switch(Logger.PRODUCTION)

        if print_info:
            self.parser_logger.add_switch(Logger.INFO)

        # Initialize warning logger
        self.warning_logger = Logger(sys.stdout)

        if print_warnings:
            self.warning_logger.add_switch(Logger.WARNING)

        # Other stuff
        self.function_scope_entered = False

        self.insert_mode = True

        # for debugging purposes
        self.clone_symbol_table_on_next_scope_exit = False
        self.cloned_tables = []

        # Create JSTLexer and the lexer object
        self.jst_lexer = JSTLexer(self)
        self.lexer = lex.lex(module=self.jst_lexer)

        # Create JSTParser and the parser object
        self.jst_parser = JSTParser(self)
        self.parser = yacc.yacc(module=self.jst_parser, start='program')

        # we will need a reference to the symbol for the main function
        self.main_function = None
Beispiel #2
0
class CompilerState:
    def __init__(self,
                 print_table=False,
                 table_logfile='log_symbol_table.txt',
                 print_tokens=False, print_source_scanner=True,
                 scanner_logfile='log_scanner_tokens.txt',
                 print_productions=False, print_source_parser=False, print_info=False,
                 parser_logfile=sys.stdout,
                 print_warnings=False,
                 **kwargs):

        # Initialize variables
        self.source_code = None
        self.source_lines = None

        # Initialize table
        self.symbol_table = SymbolTable()

        # Initialize symbol table logger
        if table_logfile in {sys.stdout, sys.stderr}:
            self.symbol_table_logger = Logger(table_logfile)
        else:
            self.symbol_table_logger = Logger(open(table_logfile, 'w'))

        if print_table:
            self.symbol_table_logger.add_switch(Logger.SYMBOL_TABLE)

        # Initialize token/lexer logger
        if scanner_logfile in {sys.stdout, sys.stderr}:
            self.token_logger = Logger(scanner_logfile)
        else:
            self.token_logger = Logger(open(scanner_logfile, 'w'))

        if print_source_scanner:
            self.token_logger.add_switch(Logger.SOURCE)

        if print_tokens:
            self.token_logger.add_switch(Logger.TOKEN)

        # Initialize parser logger
        if parser_logfile in {sys.stdout, sys.stderr}:
            self.parser_logger = Logger(parser_logfile)
        else:
            self.parser_logger = Logger(open(parser_logfile, 'w'))

        if print_source_parser:
            self.parser_logger.add_switch(Logger.SOURCE)

        if print_productions:
            self.parser_logger.add_switch(Logger.PRODUCTION)

        if print_info:
            self.parser_logger.add_switch(Logger.INFO)

        # Initialize warning logger
        self.warning_logger = Logger(sys.stdout)

        if print_warnings:
            self.warning_logger.add_switch(Logger.WARNING)

        # Other stuff
        self.function_scope_entered = False

        self.insert_mode = True

        # for debugging purposes
        self.clone_symbol_table_on_next_scope_exit = False
        self.cloned_tables = []

        # Create JSTLexer and the lexer object
        self.jst_lexer = JSTLexer(self)
        self.lexer = lex.lex(module=self.jst_lexer)

        # Create JSTParser and the parser object
        self.jst_parser = JSTParser(self)
        self.parser = yacc.yacc(module=self.jst_parser, start='program')

        # we will need a reference to the symbol for the main function
        self.main_function = None

    def parse(self, source_code):
        # Lex uses 1 based indexing for line numbers.
        # We are using 0 based for source_code.
        if source_code is not None:
            self.source_code = source_code
            self.source_lines = source_code.split('\n')
        else:
            self.source_code = None
            self.source_lines = None

        # Parse using the parser object
        return self.parser.parse(input=self.source_code, lexer=self.lexer, tracking=True)

    def teardown(self):
        self.jst_lexer.teardown()
        self.jst_parser.teardown()

    def get_symbol_table_logger(self):
        return self.symbol_table_logger

    def get_token_logger(self):
        return self.token_logger

    def get_parser_logger(self):
        return self.parser_logger

    def get_warning_logger(self):
        return self.warning_logger

    def get_line_col(self, production, index):
        lexpos = production.lexpos(index)
        last_newline = self.source_code.rfind('\n', 0, lexpos)
        return production.lineno(index), max(0, lexpos - last_newline)

    def get_line_col_source(self, lineno, lexpos):
        last_newline = self.source_code.rfind('\n', 0, lexpos)
        return (
            lineno,
            max(0, lexpos - last_newline),
            self.source_lines[lineno - 1]
        )