# 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
from six import string_types

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, string_types):
            raise AttributeError(
                "argument must be a string, was '%s'" % type(f))

        import new
        lexer = self.lex.clone()
        lexer.input(data)
        self.lexers.append((lexer, source))
        dict = {
            'productions' : self.yacc.productions,
            'action'      : self.yacc.action,
            'goto'        : self.yacc.goto,
            'errorfunc'   : self.yacc.errorfunc,
            }
        parser = new.instance(ply.yacc.LRParser, dict)
        result = parser.parse(lexer=lexer, debug=debug, tracking=tracking)
        self.lexers.pop()
        return result

    def parse_file(self, f, **kwargs):
        if isinstance(f, string_types):
            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)
