##
## BenchmarkFileParser_BENCH.py
##      - parser class for the BENCH format
##

# $Id: BenchmarkFileParser_BENCH.py,v 1.13 2007/01/18 22:20:59 jarda Exp $


# import of required modules {{{
from Plex import *

from BenchmarkFileParser import BenchmarkFileParser
from Constants import Constants
from ScannerConstants import ScannerConstants
# }}}


# class BenchmarkFileParser_BENCH() {{{
class BenchmarkFileParser_BENCH(BenchmarkFileParser):
    # DOC {{{
    """Parser class for the BENCH format.
    """
    # }}}


    # METHODS {{{
    def createLexicon(self):
        # DOC {{{
        """Creates lexicon for the parser.
        """
        # }}}

        # CODE {{{
        self.lexicon = Lexicon([
            (Str('#') + Rep(AnyBut('\n')), ScannerConstants.T_COMMENT,),
            (ScannerConstants.S_LEFT_PARENTHESIS, ScannerConstants.T_LEFT_PARENTHESIS,),
            (ScannerConstants.S_RIGHT_PARENTHESIS, ScannerConstants.T_RIGHT_PARENTHESIS,),
            (NoCase(Str('INPUT')), ScannerConstants.T_INPUT,),
            (NoCase(Str('OUTPUT')), ScannerConstants.T_OUTPUT,),
            (NoCase(Str('BUF', 'BUFF')), ScannerConstants.T_BUF,),
            (NoCase(Str('NOT')), ScannerConstants.T_NOT,),
            (NoCase(Str('AND')), ScannerConstants.T_AND,),
            (NoCase(Str('OR')), ScannerConstants.T_OR,),
            (NoCase(Str('XOR')), ScannerConstants.T_XOR,),
            (NoCase(Str('XNOR')), ScannerConstants.T_XNOR,),
            (NoCase(Str('NAND')), ScannerConstants.T_NAND,),
            (NoCase(Str('NOR')), ScannerConstants.T_NOR,),
            (NoCase(Str('DFF')), ScannerConstants.T_DFF,),
            ScannerConstants.R_EQ_EQUAL_SIGN,
            ScannerConstants.R_COMA,
            ScannerConstants.R_NEWLINE,
            ScannerConstants.R_IGNORE_SPACES_AND_TABS,
            ScannerConstants.R_SYMBOL_WITH_DOTS,
        ])
        # }}}
        
    
    def getInitialAttributeValue_INPUTS_COUNT(self):
        # DOC {{{
        """Returns initial value for INPUTS COUNT benchmark attribute.
        """
        # }}}

        # CODE {{{
        return 0
        # }}}
        
        
    def accumulateLine_INPUTS_COUNT(self, lineTokens, getValueMethod, setValueMethod):
        # DOC {{{
        """Accumulator method that updates value of INPUTS COUNT benchmark attribute.

        Parameters

            lineTokens -- tokens from one line of the benchmark file

            getValueMethod -- method that returns the current value of the
                benchmark attribute
                
            setValueMethod -- method that sets value of the benchmark attribute        
        """
        # }}}

        # CODE {{{
        if (self.isInputLine(lineTokens)):
            setValueMethod(getValueMethod() + 1)
            return 1
        # }}}

    
    def getInitialAttributeValue_OUTPUTS_COUNT(self):
        # DOC {{{
        """Returns initial value for OUTPUTS COUNT benchmark attribute.
        """
        # }}}

        # CODE {{{
        return 0
        # }}}
        
        
    def accumulateLine_OUTPUTS_COUNT(self, lineTokens, getValueMethod, setValueMethod):
        # DOC {{{
        """Accumulator method that updates value of OUTPUTS COUNT benchmark attribute.

        Parameters

            lineTokens -- tokens from one line of the benchmark file

            getValueMethod -- method that returns the current value of the
                benchmark attribute
                
            setValueMethod -- method that sets value of the benchmark attribute        
        """
        # }}}

        # CODE {{{
        if (self.isOutputLine(lineTokens)):
            setValueMethod(getValueMethod() + 1)
            return 1
        # }}}

    
    def getInitialAttributeValue_DFF_COUNT(self):
        # DOC {{{
        """Returns initial value for DFF COUNT benchmark attribute.
        """
        # }}}

        # CODE {{{
        return 0
        # }}}
        
        
    def accumulateLine_DFF_COUNT(self, lineTokens, getValueMethod, setValueMethod):
        # DOC {{{
        """Accumulator method that updates value of DFF COUNT benchmark attribute.

        Parameters

            lineTokens -- tokens from one line of the benchmark file

            getValueMethod -- method that returns the current value of the
                benchmark attribute
                
            setValueMethod -- method that sets value of the benchmark attribute        
        """
        # }}}

        # CODE {{{
        if (self.isDFFLine(lineTokens)):
            setValueMethod(getValueMethod() + 1)
            return 1
        # }}}


    def getInitialAttributeValue_NOT_GATES_COUNT(self):
        # DOC {{{
        """Returns initial value for NOT GATES COUNT benchmark attribute.
        """
        # }}}

        # CODE {{{
        return 0
        # }}}
        
        
    def accumulateLine_NOT_GATES_COUNT(self, lineTokens, getValueMethod, setValueMethod):
        # DOC {{{
        """Accumulator method that updates value of NOT GATES COUNT benchmark attribute.

        Parameters

            lineTokens -- tokens from one line of the benchmark file

            getValueMethod -- method that returns the current value of the
                benchmark attribute
                
            setValueMethod -- method that sets value of the benchmark attribute        
        """
        # }}}

        # CODE {{{
        if (self.isNOTGateLine(lineTokens)):
            setValueMethod(getValueMethod() + 1)
            return 1
        # }}}


    def getInitialAttributeValue_BUF_GATES_COUNT(self):
        # DOC {{{
        """Returns initial value for BUF GATES COUNT benchmark attribute.
        """
        # }}}

        # CODE {{{
        return 0
        # }}}
        
        
    def accumulateLine_BUF_GATES_COUNT(self, lineTokens, getValueMethod, setValueMethod):
        # DOC {{{
        """Accumulator method that updates value of BUF GATES COUNT benchmark attribute.

        Parameters

            lineTokens -- tokens from one line of the benchmark file

            getValueMethod -- method that returns the current value of the
                benchmark attribute
                
            setValueMethod -- method that sets value of the benchmark attribute        
        """
        # }}}

        # CODE {{{
        if (self.isBUFGateLine(lineTokens)):
            setValueMethod(getValueMethod() + 1)
            return 1
        # }}}


    def getInitialAttributeValue_XNOR_GATES_COUNT(self):
        # DOC {{{
        """Returns initial value for XNOR GATES COUNT benchmark attribute.
        """
        # }}}

        # CODE {{{
        return 0
        # }}}
        
        
    def accumulateLine_XNOR_GATES_COUNT(self, lineTokens, getValueMethod, setValueMethod):
        # DOC {{{
        """Accumulator method that updates value of XNOR GATES COUNT benchmark attribute.

        Parameters

            lineTokens -- tokens from one line of the benchmark file

            getValueMethod -- method that returns the current value of the
                benchmark attribute
                
            setValueMethod -- method that sets value of the benchmark attribute        
        """
        # }}}

        # CODE {{{
        if (self.isXNORGateLine(lineTokens)):
            setValueMethod(getValueMethod() + 1)
            return 1
        # }}}


    def getInitialAttributeValue_OR_GATES_COUNT(self):
        # DOC {{{
        """Returns initial value for OR GATES COUNT benchmark attribute.
        """
        # }}}

        # CODE {{{
        return 0
        # }}}
        
        
    def accumulateLine_OR_GATES_COUNT(self, lineTokens, getValueMethod, setValueMethod):
        # DOC {{{
        """Accumulator method that updates value of OR GATES COUNT benchmark attribute.

        Parameters

            lineTokens -- tokens from one line of the benchmark file

            getValueMethod -- method that returns the current value of the
                benchmark attribute
                
            setValueMethod -- method that sets value of the benchmark attribute        
        """
        # }}}

        # CODE {{{
        if (self.isORGateLine(lineTokens)):
            setValueMethod(getValueMethod() + 1)
            return 1
        # }}}


    def getInitialAttributeValue_AND_GATES_COUNT(self):
        # DOC {{{
        """Returns initial value for AND GATES COUNT benchmark attribute.
        """
        # }}}

        # CODE {{{
        return 0
        # }}}
        
        
    def accumulateLine_AND_GATES_COUNT(self, lineTokens, getValueMethod, setValueMethod):
        # DOC {{{
        """Accumulator method that updates value of AND GATES COUNT benchmark attribute.

        Parameters

            lineTokens -- tokens from one line of the benchmark file

            getValueMethod -- method that returns the current value of the
                benchmark attribute
                
            setValueMethod -- method that sets value of the benchmark attribute        
        """
        # }}}

        # CODE {{{
        if (self.isANDGateLine(lineTokens)):
            setValueMethod(getValueMethod() + 1)
            return 1
        # }}}


    def getInitialAttributeValue_XOR_GATES_COUNT(self):
        # DOC {{{
        """Returns initial value for XOR GATES COUNT benchmark attribute.
        """
        # }}}

        # CODE {{{
        return 0
        # }}}
        
        
    def accumulateLine_XOR_GATES_COUNT(self, lineTokens, getValueMethod, setValueMethod):
        # DOC {{{
        """Accumulator method that updates value of XOR GATES COUNT benchmark attribute.

        Parameters

            lineTokens -- tokens from one line of the benchmark file

            getValueMethod -- method that returns the current value of the
                benchmark attribute
                
            setValueMethod -- method that sets value of the benchmark attribute        
        """
        # }}}

        # CODE {{{
        if (self.isXORGateLine(lineTokens)):
            setValueMethod(getValueMethod() + 1)
            return 1
        # }}}


    def getInitialAttributeValue_NOR_GATES_COUNT(self):
        # DOC {{{
        """Returns initial value for NOR GATES COUNT benchmark attribute.
        """
        # }}}

        # CODE {{{
        return 0
        # }}}
        
        
    def accumulateLine_NOR_GATES_COUNT(self, lineTokens, getValueMethod, setValueMethod):
        # DOC {{{
        """Accumulator method that updates value of NOR GATES COUNT benchmark attribute.

        Parameters

            lineTokens -- tokens from one line of the benchmark file

            getValueMethod -- method that returns the current value of the
                benchmark attribute
                
            setValueMethod -- method that sets value of the benchmark attribute        
        """
        # }}}

        # CODE {{{
        if (self.isNORGateLine(lineTokens)):
            setValueMethod(getValueMethod() + 1)
            return 1
        # }}}


    def getInitialAttributeValue_NAND_GATES_COUNT(self):
        # DOC {{{
        """Returns initial value for NAND GATES COUNT benchmark attribute.
        """
        # }}}

        # CODE {{{
        return 0
        # }}}
        
        
    def accumulateLine_NAND_GATES_COUNT(self, lineTokens, getValueMethod, setValueMethod):
        # DOC {{{
        """Accumulator method that updates value of NAND GATES COUNT benchmark attribute.

        Parameters

            lineTokens -- tokens from one line of the benchmark file

            getValueMethod -- method that returns the current value of the
                benchmark attribute
                
            setValueMethod -- method that sets value of the benchmark attribute        
        """
        # }}}

        # CODE {{{
        if (self.isNANDGateLine(lineTokens)):
            setValueMethod(getValueMethod() + 1)
            return 1
        # }}}


    def isInputLine(lineTokens):
        # DOC {{{
        """Tells whether the line contains information about an input.

        Parameters

            lineTokens -- tokens from one line of the benchmark file
        """
        # }}}

        # CODE {{{
        return ([t[0] for t in lineTokens[:4]] == [ScannerConstants.T_INPUT,
            ScannerConstants.T_LEFT_PARENTHESIS, ScannerConstants.T_SYMBOL,
            ScannerConstants.T_RIGHT_PARENTHESIS])
        # }}}
    isInputLine = staticmethod(isInputLine)


    def isOutputLine(lineTokens):
        # DOC {{{
        """Tells whether the line contains information about an output.

        Parameters

            lineTokens -- tokens from one line of the benchmark file
        """
        # }}}

        # CODE {{{
        return ([t[0] for t in lineTokens[:4]] == [ScannerConstants.T_OUTPUT,
            ScannerConstants.T_LEFT_PARENTHESIS, ScannerConstants.T_SYMBOL,
            ScannerConstants.T_RIGHT_PARENTHESIS])
        # }}}
    isOutputLine = staticmethod(isOutputLine)


    def isDFFLine(lineTokens):
        # DOC {{{
        """Tells whether the line contains information about a D flip-flop.

        Parameters

            lineTokens -- tokens from one line of the benchmark file
        """
        # }}}

        # CODE {{{
        return ([t[0] for t in lineTokens[:6]] == [ScannerConstants.T_SYMBOL,
                ScannerConstants.T_EQUAL_SIGN, ScannerConstants.T_DFF,
                ScannerConstants.T_LEFT_PARENTHESIS, ScannerConstants.T_SYMBOL,
                ScannerConstants.T_RIGHT_PARENTHESIS])
        # }}}
    isDFFLine = staticmethod(isDFFLine)


    def isNOTGateLine(lineTokens):
        # DOC {{{
        """Tells whether the line is a NOT gate line.

        Parameters

            lineTokens -- tokens from one line of the benchmark file
        """
        # }}}

        # CODE {{{
        return ([t[0] for t in lineTokens[:6]] == [ScannerConstants.T_SYMBOL,
                ScannerConstants.T_EQUAL_SIGN, ScannerConstants.T_NOT,
                ScannerConstants.T_LEFT_PARENTHESIS, ScannerConstants.T_SYMBOL,
                ScannerConstants.T_RIGHT_PARENTHESIS])
        # }}}
    isNOTGateLine = staticmethod(isNOTGateLine)


    def isXNORGateLine(lineTokens):
        # DOC {{{
        """Tells whether the line is a XNOR gate line.

        Parameters

            lineTokens -- tokens from one line of the benchmark file
        """
        # }}}

        # CODE {{{
        return BenchmarkFileParser_BENCH.isGateLine(lineTokens, ScannerConstants.T_XNOR)
        # }}}
    isXNORGateLine = staticmethod(isXNORGateLine)


    def isBUFGateLine(lineTokens):
        # DOC {{{
        """Tells whether the line is a BUF gate line.

        Parameters

            lineTokens -- tokens from one line of the benchmark file
        """
        # }}}

        # CODE {{{
        return BenchmarkFileParser_BENCH.isGateLine(lineTokens, ScannerConstants.T_BUF)
        # }}}
    isBUFGateLine = staticmethod(isBUFGateLine)


    def isORGateLine(lineTokens):
        # DOC {{{
        """Tells whether the line is an OR gate line.

        Parameters

            lineTokens -- tokens from one line of the benchmark file
        """
        # }}}

        # CODE {{{
        return BenchmarkFileParser_BENCH.isGateLine(lineTokens, ScannerConstants.T_OR)
        # }}}
    isORGateLine = staticmethod(isORGateLine)


    def isANDGateLine(lineTokens):
        # DOC {{{
        """Tells whether the line is an AND gate line.

        Parameters

            lineTokens -- tokens from one line of the benchmark file
        """
        # }}}

        # CODE {{{
        return BenchmarkFileParser_BENCH.isGateLine(lineTokens, ScannerConstants.T_AND)
        # }}}
    isANDGateLine = staticmethod(isANDGateLine)


    def isXORGateLine(lineTokens):
        # DOC {{{
        """Tells whether the line is an XOR gate line.

        Parameters

            lineTokens -- tokens from one line of the benchmark file
        """
        # }}}

        # CODE {{{
        return BenchmarkFileParser_BENCH.isGateLine(lineTokens, ScannerConstants.T_XOR)
        # }}}
    isXORGateLine = staticmethod(isXORGateLine)


    def isNORGateLine(lineTokens):
        # DOC {{{
        """Tells whether the line is a NOR gate line.

        Parameters

            lineTokens -- tokens from one line of the benchmark file
        """
        # }}}

        # CODE {{{
        return BenchmarkFileParser_BENCH.isGateLine(lineTokens, ScannerConstants.T_NOR)
        # }}}
    isNORGateLine = staticmethod(isNORGateLine)


    def isNANDGateLine(lineTokens):
        # DOC {{{
        """Tells whether the line is a NAND gate line.

        Parameters

            lineTokens -- tokens from one line of the benchmark file
        """
        # }}}

        # CODE {{{
        return BenchmarkFileParser_BENCH.isGateLine(lineTokens, ScannerConstants.T_NAND)
        # }}}
    isNANDGateLine = staticmethod(isNANDGateLine)


    def isGateLine(lineTokens, gateTypeToken):
        # DOC {{{
        """Tells whether the line is a gate line.

        Parameters

            lineTokens -- tokens from one line of the benchmark file

            gateTypeToken -- token of the specific gate type
        """
        # }}}

        # CODE {{{
        return (([t[0] for t in lineTokens[:4]]    == [ScannerConstants.T_SYMBOL,
                ScannerConstants.T_EQUAL_SIGN, gateTypeToken,
                ScannerConstants.T_LEFT_PARENTHESIS]) and
                (lineTokens[-1][0] == ScannerConstants.T_RIGHT_PARENTHESIS) and
                (BenchmarkFileParser_BENCH.isListOfTokensJoinedByComa(lineTokens[4:-1])))
        # }}}
    isGateLine = staticmethod(isGateLine)


    def isListOfTokensJoinedByComa(tokens):
        # DOC {{{
        """Tells whether the list of tokens has comas between other tokens
        (every other token is a COMA, the first and the last is not).
        
        Parameters

            tokens -- list of tokens
        """
        # }}}

        # CODE {{{
        return ((not (len([token for token in tokens[::2] if (token[0] != ScannerConstants.T_SYMBOL)]))) and
                (not (len([token for token in tokens[1::2] if (token[0] != ScannerConstants.T_COMA)]))))
        # }}}
    isListOfTokensJoinedByComa = staticmethod(isListOfTokensJoinedByComa)


    # }}}
# }}}
