# Copyright (c) 2006-2011 Nathan Binkert <nate@binkert.org>
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met: redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer;
# redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution;
# neither the name of the copyright holders nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

import os

import ply.lex
import ply.yacc


class ParseError(Exception):
    def __init__(self, message, token=None):
        Exception.__init__(self, message)
        self.token = token


class Grammar(object):
    def setupLexerFactory(self, **kwargs):
        if "module" in kwargs:
            raise AttributeError("module is an illegal attribute")
        self.lex_kwargs = kwargs

    def setupParserFactory(self, **kwargs):
        if "module" in kwargs:
            raise AttributeError("module is an illegal attribute")

        if "output" in kwargs:
            dir, tab = os.path.split(output)
            if not tab.endswith(".py"):
                raise AttributeError("The output file must end with .py")
            kwargs["outputdir"] = dir
            kwargs["tabmodule"] = tab[:-3]

        self.yacc_kwargs = kwargs

    def __getattr__(self, attr):
        if attr == "lexers":
            self.lexers = []
            return self.lexers

        if attr == "lex_kwargs":
            self.setupLexerFactory()
            return self.lex_kwargs

        if attr == "yacc_kwargs":
            self.setupParserFactory()
            return self.yacc_kwargs

        if attr == "lex":
            self.lex = ply.lex.lex(module=self, **self.lex_kwargs)
            return self.lex

        if attr == "yacc":
            self.yacc = ply.yacc.yacc(module=self, **self.yacc_kwargs)
            return self.yacc

        if attr == "current_lexer":
            if not self.lexers:
                return None
            return self.lexers[-1][0]

        if attr == "current_source":
            if not self.lexers:
                return "<none>"
            return self.lexers[-1][1]

        if attr == "current_line":
            if not self.lexers:
                return -1
            return self.current_lexer.lineno

        raise AttributeError(
            "'%s' object has no attribute '%s'" % (type(self), attr)
        )

    def parse_string(self, data, source="<string>", debug=None, tracking=0):
        if not isinstance(data, str):
            raise AttributeError(
                "argument must be a string, was '%s'" % type(f)
            )

        lexer = self.lex.clone()
        lexer.input(data)
        self.lexers.append((lexer, source))

        lrtab = ply.yacc.LRTable()
        lrtab.lr_productions = self.yacc.productions
        lrtab.lr_action = self.yacc.action
        lrtab.lr_goto = self.yacc.goto

        parser = ply.yacc.LRParser(lrtab, self.yacc.errorfunc)
        result = parser.parse(lexer=lexer, debug=debug, tracking=tracking)
        self.lexers.pop()
        return result

    def parse_file(self, f, **kwargs):
        if isinstance(f, str):
            source = f
            f = open(f, "r")
        elif isinstance(f, file):
            source = f.name
        else:
            raise AttributeError(
                "argument must be either a string or file, was '%s'" % type(f)
            )

        return self.parse_string(f.read(), source, **kwargs)

    def p_error(self, t):
        if t:
            msg = "Syntax error at %s:%d:%d\n>>%s<<" % (
                self.current_source,
                t.lineno,
                t.lexpos + 1,
                t.value,
            )
        else:
            msg = "Syntax error at end of %s" % (self.current_source,)
        raise ParseError(msg, t)

    def t_error(self, t):
        msg = "Illegal character %s @ %d:%d" % (
            repr(t.value[0]),
            t.lineno,
            t.lexpos,
        )
        raise ParseError(msg, t)
