parser.py revision 7055
16657Snate@binkert.org# Copyright (c) 2009 The Hewlett-Packard Development Company
26657Snate@binkert.org# All rights reserved.
36657Snate@binkert.org#
46657Snate@binkert.org# Redistribution and use in source and binary forms, with or without
56657Snate@binkert.org# modification, are permitted provided that the following conditions are
66657Snate@binkert.org# met: redistributions of source code must retain the above copyright
76657Snate@binkert.org# notice, this list of conditions and the following disclaimer;
86657Snate@binkert.org# redistributions in binary form must reproduce the above copyright
96657Snate@binkert.org# notice, this list of conditions and the following disclaimer in the
106657Snate@binkert.org# documentation and/or other materials provided with the distribution;
116657Snate@binkert.org# neither the name of the copyright holders nor the names of its
126657Snate@binkert.org# contributors may be used to endorse or promote products derived from
136657Snate@binkert.org# this software without specific prior written permission.
146657Snate@binkert.org#
156657Snate@binkert.org# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
166657Snate@binkert.org# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
176657Snate@binkert.org# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
186657Snate@binkert.org# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
196657Snate@binkert.org# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
206657Snate@binkert.org# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
216657Snate@binkert.org# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
226657Snate@binkert.org# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
236657Snate@binkert.org# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
246657Snate@binkert.org# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
256657Snate@binkert.org# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
266657Snate@binkert.org#
276657Snate@binkert.org# Authors: Nathan Binkert
286657Snate@binkert.org
296657Snate@binkert.orgimport os.path
306657Snate@binkert.orgimport re
316657Snate@binkert.orgimport sys
326657Snate@binkert.org
336999Snate@binkert.orgfrom m5.util import code_formatter
346657Snate@binkert.orgfrom m5.util.grammar import Grammar, TokenError, ParseError
356657Snate@binkert.org
366657Snate@binkert.orgimport slicc.ast as ast
376657Snate@binkert.orgimport slicc.util as util
386657Snate@binkert.orgfrom slicc.symbols import SymbolTable
396657Snate@binkert.org
406657Snate@binkert.orgdef read_slicc(sources):
416657Snate@binkert.org    if not isinstance(sources, (list,tuple)):
426657Snate@binkert.org        sources = [ sources ]
436657Snate@binkert.org
446657Snate@binkert.org    for source in sources:
456657Snate@binkert.org        for sm_file in file(source, "r"):
466657Snate@binkert.org            sm_file = sm_file.strip()
476657Snate@binkert.org            if not sm_file:
486657Snate@binkert.org                continue
496657Snate@binkert.org            if sm_file.startswith("#"):
506657Snate@binkert.org                continue
516657Snate@binkert.org            yield sm_file
526657Snate@binkert.org
536657Snate@binkert.orgclass SLICC(Grammar):
546999Snate@binkert.org    def __init__(self, protocol, **kwargs):
556657Snate@binkert.org        super(SLICC, self).__init__(**kwargs)
566657Snate@binkert.org        self.decl_list_vec = []
576657Snate@binkert.org        self.current_file = None
586999Snate@binkert.org        self.protocol = protocol
596999Snate@binkert.org        self.symtab = SymbolTable(self)
606999Snate@binkert.org
616999Snate@binkert.org    def codeFormatter(self, *args, **kwargs):
626999Snate@binkert.org        code = code_formatter(*args, **kwargs)
636999Snate@binkert.org        code['protocol'] = self.protocol
646999Snate@binkert.org        return code
656657Snate@binkert.org
666657Snate@binkert.org    def parse(self, filename):
676657Snate@binkert.org        self.current_file = filename
686657Snate@binkert.org        f = file(filename, 'r')
696657Snate@binkert.org        text = f.read()
706657Snate@binkert.org        try:
716657Snate@binkert.org            decl_list = super(SLICC, self).parse(text)
726657Snate@binkert.org        except (TokenError, ParseError), e:
736657Snate@binkert.org            sys.exit("%s: %s:%d" % (e, filename, e.token.lineno))
746657Snate@binkert.org        self.decl_list_vec.append(decl_list)
756657Snate@binkert.org        self.current_file = None
766657Snate@binkert.org
776657Snate@binkert.org    def _load(self, *filenames):
786657Snate@binkert.org        filenames = list(filenames)
796657Snate@binkert.org        while filenames:
806657Snate@binkert.org            f = filenames.pop(0)
816657Snate@binkert.org            if isinstance(f, (list, tuple)):
826657Snate@binkert.org                filenames[0:0] = list(f)
836657Snate@binkert.org                continue
846657Snate@binkert.org
856657Snate@binkert.org            yield f
866657Snate@binkert.org            if f.endswith(".slicc"):
876657Snate@binkert.org                dirname,basename = os.path.split(f)
886657Snate@binkert.org                filenames[0:0] = [ os.path.join(dirname, x) \
896657Snate@binkert.org                                   for x in read_slicc(f)]
906657Snate@binkert.org            else:
916657Snate@binkert.org                assert f.endswith(".sm")
926657Snate@binkert.org                self.parse(f)
936657Snate@binkert.org
946657Snate@binkert.org    def load(self, *filenames, **kwargs):
956657Snate@binkert.org        verbose = kwargs.pop("verbose", False)
966657Snate@binkert.org        if kwargs:
976657Snate@binkert.org            raise TypeError
986657Snate@binkert.org
996657Snate@binkert.org        gen = self._load(*filenames)
1006657Snate@binkert.org        if verbose:
1016657Snate@binkert.org            return gen
1026657Snate@binkert.org        else:
1036657Snate@binkert.org            # Run out the generator if we don't want the verbosity
1046657Snate@binkert.org            for foo in gen:
1056657Snate@binkert.org                pass
1066657Snate@binkert.org
1076657Snate@binkert.org    def findMachines(self):
1086657Snate@binkert.org        for decl_list in self.decl_list_vec:
1096657Snate@binkert.org            decl_list.findMachines()
1106657Snate@binkert.org
1116657Snate@binkert.org    def generate(self):
1126657Snate@binkert.org        for decl_list in self.decl_list_vec:
1136657Snate@binkert.org            decl_list.generate()
1146657Snate@binkert.org
1156657Snate@binkert.org    def writeCodeFiles(self, code_path):
1166657Snate@binkert.org        util.makeDir(code_path)
1176657Snate@binkert.org        self.symtab.writeCodeFiles(code_path)
1186657Snate@binkert.org
1196657Snate@binkert.org    def writeHTMLFiles(self, code_path):
1206657Snate@binkert.org        util.makeDir(code_path)
1216657Snate@binkert.org        self.symtab.writeHTMLFiles(code_path)
1226657Snate@binkert.org
1236657Snate@binkert.org    def files(self):
1246714Ssteve.reinhardt@amd.com        f = set([
1256714Ssteve.reinhardt@amd.com            'MachineType.cc',
1266657Snate@binkert.org            'MachineType.hh',
1276657Snate@binkert.org            'Types.hh' ])
1286657Snate@binkert.org
1296657Snate@binkert.org        for decl_list in self.decl_list_vec:
1306714Ssteve.reinhardt@amd.com            f |= decl_list.files()
1316657Snate@binkert.org
1326714Ssteve.reinhardt@amd.com        return f
1336657Snate@binkert.org
1346657Snate@binkert.org    t_ignore = '\t '
1356657Snate@binkert.org
1366657Snate@binkert.org    # C or C++ comment (ignore)
1376657Snate@binkert.org    def t_c_comment(self, t):
1386657Snate@binkert.org        r'/\*(.|\n)*?\*/'
1396657Snate@binkert.org        t.lexer.lineno += t.value.count('\n')
1406657Snate@binkert.org
1416657Snate@binkert.org    def t_cpp_comment(self, t):
1426657Snate@binkert.org        r'//.*'
1436657Snate@binkert.org
1446657Snate@binkert.org    # Define a rule so we can track line numbers
1456657Snate@binkert.org    def t_newline(self, t):
1466657Snate@binkert.org        r'\n+'
1476657Snate@binkert.org        t.lexer.lineno += len(t.value)
1486657Snate@binkert.org
1496657Snate@binkert.org    reserved = {
1506657Snate@binkert.org        'global' : 'GLOBAL',
1516657Snate@binkert.org        'machine' : 'MACHINE',
1526657Snate@binkert.org        'in_port' : 'IN_PORT',
1536657Snate@binkert.org        'out_port' : 'OUT_PORT',
1546657Snate@binkert.org        'action' : 'ACTION',
1556657Snate@binkert.org        'transition' : 'TRANS',
1566657Snate@binkert.org        'structure' : 'STRUCT',
1576657Snate@binkert.org        'external_type' : 'EXTERN_TYPE',
1586657Snate@binkert.org        'enumeration' : 'ENUM',
1596657Snate@binkert.org        'peek' : 'PEEK',
1606657Snate@binkert.org        'enqueue' : 'ENQUEUE',
1616657Snate@binkert.org        'copy_head' : 'COPY_HEAD',
1626657Snate@binkert.org        'check_allocate' : 'CHECK_ALLOCATE',
1636657Snate@binkert.org        'check_stop_slots' : 'CHECK_STOP_SLOTS',
1646882SBrad.Beckmann@amd.com        'static_cast' : 'STATIC_CAST',
1656657Snate@binkert.org        'if' : 'IF',
1666657Snate@binkert.org        'else' : 'ELSE',
1676657Snate@binkert.org        'return' : 'RETURN',
1686657Snate@binkert.org        'THIS' : 'THIS',
1696657Snate@binkert.org        'CHIP' : 'CHIP',
1706657Snate@binkert.org        'void' : 'VOID',
1716657Snate@binkert.org        'new' : 'NEW',
1726657Snate@binkert.org    }
1736657Snate@binkert.org
1746657Snate@binkert.org    literals = ':[]{}(),='
1756657Snate@binkert.org
1766657Snate@binkert.org    tokens = [ 'EQ', 'NE', 'LT', 'GT', 'LE', 'GE',
1776657Snate@binkert.org               'LEFTSHIFT', 'RIGHTSHIFT',
1786657Snate@binkert.org               'NOT', 'AND', 'OR',
1796657Snate@binkert.org               'PLUS', 'DASH', 'STAR', 'SLASH',
1806657Snate@binkert.org               'DOUBLE_COLON', 'SEMI',
1816657Snate@binkert.org               'ASSIGN', 'DOT',
1826657Snate@binkert.org               'IDENT', 'LIT_BOOL', 'FLOATNUMBER', 'NUMBER', 'STRING' ]
1836657Snate@binkert.org    tokens += reserved.values()
1846657Snate@binkert.org
1856657Snate@binkert.org    t_EQ = r'=='
1866657Snate@binkert.org    t_NE = r'!='
1876657Snate@binkert.org    t_LT = r'<'
1886657Snate@binkert.org    t_GT = r'>'
1896657Snate@binkert.org    t_LE = r'<='
1906657Snate@binkert.org    t_GE = r'>='
1916657Snate@binkert.org    t_LEFTSHIFT = r'<<'
1926657Snate@binkert.org    t_RIGHTSHIFT = r'>>'
1936657Snate@binkert.org    t_NOT = r'!'
1946657Snate@binkert.org    t_AND = r'&&'
1956657Snate@binkert.org    t_OR = r'\|\|'
1966657Snate@binkert.org    t_PLUS = r'\+'
1976657Snate@binkert.org    t_DASH = r'-'
1986657Snate@binkert.org    t_STAR = r'\*'
1996657Snate@binkert.org    t_SLASH = r'/'
2006657Snate@binkert.org    t_DOUBLE_COLON = r'::'
2016657Snate@binkert.org    t_SEMI = r';'
2026657Snate@binkert.org    t_ASSIGN = r':='
2036657Snate@binkert.org    t_DOT = r'\.'
2046657Snate@binkert.org
2056657Snate@binkert.org    precedence = (
2066657Snate@binkert.org        ('left', 'AND', 'OR'),
2076657Snate@binkert.org        ('left', 'EQ', 'NE'),
2086657Snate@binkert.org        ('left', 'LT', 'GT', 'LE', 'GE'),
2096657Snate@binkert.org        ('left', 'RIGHTSHIFT', 'LEFTSHIFT'),
2106657Snate@binkert.org        ('left', 'PLUS', 'DASH'),
2116657Snate@binkert.org        ('left', 'STAR', 'SLASH'),
2126657Snate@binkert.org        ('right', 'NOT', 'UMINUS'),
2136657Snate@binkert.org    )
2146657Snate@binkert.org
2156657Snate@binkert.org    def t_IDENT(self, t):
2166657Snate@binkert.org        r'[a-zA-Z_][a-zA-Z_0-9]*'
2176657Snate@binkert.org        if t.value == 'true':
2186657Snate@binkert.org            t.type = 'LIT_BOOL'
2196657Snate@binkert.org            t.value = True
2206657Snate@binkert.org            return t
2216657Snate@binkert.org
2226657Snate@binkert.org        if t.value == 'false':
2236657Snate@binkert.org            t.type = 'LIT_BOOL'
2246657Snate@binkert.org            t.value = False
2256657Snate@binkert.org            return t
2266657Snate@binkert.org
2276657Snate@binkert.org        # Check for reserved words
2286657Snate@binkert.org        t.type = self.reserved.get(t.value, 'IDENT')
2296657Snate@binkert.org        return t
2306657Snate@binkert.org
2316657Snate@binkert.org    def t_FLOATNUMBER(self, t):
2326657Snate@binkert.org        '[0-9]+[.][0-9]+'
2336657Snate@binkert.org        try:
2346657Snate@binkert.org            t.value = float(t.value)
2356657Snate@binkert.org        except ValueError:
2366657Snate@binkert.org            raise TokenError("Illegal float", t)
2376657Snate@binkert.org        return t
2386657Snate@binkert.org
2396657Snate@binkert.org    def t_NUMBER(self, t):
2406657Snate@binkert.org        r'[0-9]+'
2416657Snate@binkert.org        try:
2426657Snate@binkert.org            t.value = int(t.value)
2436657Snate@binkert.org        except ValueError:
2446657Snate@binkert.org            raise TokenError("Illegal number", t)
2456657Snate@binkert.org        return t
2466657Snate@binkert.org
2476657Snate@binkert.org    def t_STRING1(self, t):
2486657Snate@binkert.org        r'\"[^"\n]*\"'
2496657Snate@binkert.org        t.type = 'STRING'
2506657Snate@binkert.org        t.value = t.value[1:-1]
2516657Snate@binkert.org        return t
2526657Snate@binkert.org
2536657Snate@binkert.org    def t_STRING2(self, t):
2546657Snate@binkert.org        r"\'[^'\n]*\'"
2556657Snate@binkert.org        t.type = 'STRING'
2566657Snate@binkert.org        t.value = t.value[1:-1]
2576657Snate@binkert.org        return t
2586657Snate@binkert.org
2596657Snate@binkert.org    def p_file(self, p):
2606657Snate@binkert.org        "file : decls"
2616657Snate@binkert.org        p[0] = p[1]
2626657Snate@binkert.org
2636657Snate@binkert.org    def p_empty(self, p):
2646657Snate@binkert.org        "empty :"
2656657Snate@binkert.org
2666657Snate@binkert.org    def p_decls(self, p):
2676657Snate@binkert.org        "decls : declsx"
2686657Snate@binkert.org        p[0] = ast.DeclListAST(self, p[1])
2696657Snate@binkert.org
2706657Snate@binkert.org    def p_declsx__list(self, p):
2716657Snate@binkert.org        "declsx : decl declsx"
2726657Snate@binkert.org        p[0] = [ p[1] ] + p[2]
2736657Snate@binkert.org
2746657Snate@binkert.org    def p_declsx__none(self, p):
2756657Snate@binkert.org        "declsx : empty"
2766657Snate@binkert.org        p[0] = []
2776657Snate@binkert.org
2786657Snate@binkert.org    def p_decl__machine(self, p):
2796657Snate@binkert.org        "decl : MACHINE '(' ident pairs ')' ':' params '{' decls '}'"
2806657Snate@binkert.org        p[0] = ast.MachineAST(self, p[3], p[4], p[7], p[9])
2816657Snate@binkert.org
2826657Snate@binkert.org    def p_decl__action(self, p):
2836657Snate@binkert.org        "decl : ACTION '(' ident pairs ')' statements"
2846657Snate@binkert.org        p[0] = ast.ActionDeclAST(self, p[3], p[4], p[6])
2856657Snate@binkert.org
2866657Snate@binkert.org    def p_decl__in_port(self, p):
2876657Snate@binkert.org        "decl : IN_PORT '(' ident ',' type ',' var pairs ')' statements"
2886657Snate@binkert.org        p[0] = ast.InPortDeclAST(self, p[3], p[5], p[7], p[8], p[10])
2896657Snate@binkert.org
2906657Snate@binkert.org    def p_decl__out_port(self, p):
2916657Snate@binkert.org        "decl : OUT_PORT '(' ident ',' type ',' var pairs ')' SEMI"
2926657Snate@binkert.org        p[0] = ast.OutPortDeclAST(self, p[3], p[5], p[7], p[8])
2936657Snate@binkert.org
2946657Snate@binkert.org    def p_decl__trans0(self, p):
2956657Snate@binkert.org        "decl : TRANS '(' idents ',' idents ',' ident pairs ')' idents"
2966657Snate@binkert.org        p[0] = ast.TransitionDeclAST(self, p[3], p[5], p[7], p[8], p[10])
2976657Snate@binkert.org
2986657Snate@binkert.org    def p_decl__trans1(self, p):
2996657Snate@binkert.org        "decl : TRANS '(' idents ',' idents           pairs ')' idents"
3006657Snate@binkert.org        p[0] = ast.TransitionDeclAST(self, p[3], p[5], None, p[6], p[8])
3016657Snate@binkert.org
3026657Snate@binkert.org    def p_decl__extern0(self, p):
3036657Snate@binkert.org        "decl : EXTERN_TYPE '(' type pairs ')' SEMI"
3046657Snate@binkert.org        p[4]["external"] = "yes"
3056657Snate@binkert.org        p[0] = ast.TypeDeclAST(self, p[3], p[4], [])
3066657Snate@binkert.org
3076657Snate@binkert.org    def p_decl__extern1(self, p):
3086657Snate@binkert.org        "decl : EXTERN_TYPE '(' type pairs ')' '{' type_methods '}'"
3096657Snate@binkert.org        p[4]["external"] = "yes"
3106657Snate@binkert.org        p[0] = ast.TypeDeclAST(self, p[3], p[4], p[7])
3116657Snate@binkert.org
3126657Snate@binkert.org    def p_decl__global(self, p):
3136657Snate@binkert.org        "decl : GLOBAL '(' type pairs ')' '{' type_members '}'"
3146657Snate@binkert.org        p[4]["global"] = "yes"
3156657Snate@binkert.org        p[0] = ast.TypeDeclAST(self, p[3], p[4], p[7])
3166657Snate@binkert.org
3176657Snate@binkert.org    def p_decl__struct(self, p):
3186657Snate@binkert.org        "decl : STRUCT '(' type pairs ')' '{' type_members '}'"
3196657Snate@binkert.org        p[0] = ast.TypeDeclAST(self, p[3], p[4], p[7])
3206657Snate@binkert.org
3216657Snate@binkert.org    def p_decl__enum(self, p):
3226657Snate@binkert.org        "decl : ENUM '(' type pairs ')' '{' type_enums   '}'"
3236657Snate@binkert.org        p[4]["enumeration"] = "yes"
3246657Snate@binkert.org        p[0] = ast.EnumDeclAST(self, p[3], p[4], p[7])
3256657Snate@binkert.org
3266657Snate@binkert.org    def p_decl__object(self, p):
3276657Snate@binkert.org        "decl : type ident pairs SEMI"
3286657Snate@binkert.org        p[0] = ast.ObjDeclAST(self, p[1], p[2], p[3])
3296657Snate@binkert.org
3306657Snate@binkert.org    def p_decl__func_decl(self, p):
3316657Snate@binkert.org        """decl : void ident '(' params ')' pairs SEMI
3326657Snate@binkert.org                | type ident '(' params ')' pairs SEMI"""
3336657Snate@binkert.org        p[0] = ast.FuncDeclAST(self, p[1], p[2], p[4], p[6], None)
3346657Snate@binkert.org
3356657Snate@binkert.org    def p_decl__func_def(self, p):
3366657Snate@binkert.org        """decl : void ident '(' params ')' pairs statements
3376657Snate@binkert.org                | type ident '(' params ')' pairs statements"""
3386657Snate@binkert.org        p[0] = ast.FuncDeclAST(self, p[1], p[2], p[4], p[6], p[7])
3396657Snate@binkert.org
3406657Snate@binkert.org    # Type fields
3416657Snate@binkert.org    def p_type_members__list(self, p):
3426657Snate@binkert.org        "type_members : type_member type_members"
3436657Snate@binkert.org        p[0] = [ p[1] ] + p[2]
3446657Snate@binkert.org
3456657Snate@binkert.org    def p_type_members__empty(self, p):
3466657Snate@binkert.org        "type_members : empty"
3476657Snate@binkert.org        p[0] = []
3486657Snate@binkert.org
3496657Snate@binkert.org    def p_type_member__1(self, p):
3506657Snate@binkert.org        "type_member : type ident pairs SEMI"
3516657Snate@binkert.org        p[0] = ast.TypeFieldMemberAST(self, p[1], p[2], p[3], None)
3526657Snate@binkert.org
3536657Snate@binkert.org    def p_type_member__2(self, p):
3546657Snate@binkert.org        "type_member : type ident ASSIGN expr SEMI"
3556657Snate@binkert.org        p[0] = ast.TypeFieldMemberAST(self, p[1], p[2],
3566657Snate@binkert.org                                      ast.PairListAST(self), p[4])
3576657Snate@binkert.org
3586657Snate@binkert.org    # Methods
3596657Snate@binkert.org    def p_type_methods__list(self, p):
3606657Snate@binkert.org        "type_methods : type_method type_methods"
3616657Snate@binkert.org        p[0] = [ p[1] ] + p[2]
3626657Snate@binkert.org
3636657Snate@binkert.org    def p_type_methods(self, p):
3646657Snate@binkert.org        "type_methods : empty"
3656657Snate@binkert.org        p[0] = []
3666657Snate@binkert.org
3676657Snate@binkert.org    def p_type_method(self, p):
3686657Snate@binkert.org        "type_method : type_or_void ident '(' types ')' pairs SEMI"
3696657Snate@binkert.org        p[0] = ast.TypeFieldMethodAST(self, p[1], p[2], p[4], p[6])
3706657Snate@binkert.org
3716657Snate@binkert.org    # Enum fields
3726657Snate@binkert.org    def p_type_enums__list(self, p):
3736657Snate@binkert.org        "type_enums : type_enum type_enums"
3746657Snate@binkert.org        p[0] = [ p[1] ] + p[2]
3756657Snate@binkert.org
3766657Snate@binkert.org    def p_type_enums__empty(self, p):
3776657Snate@binkert.org        "type_enums : empty"
3786657Snate@binkert.org        p[0] = []
3796657Snate@binkert.org
3806657Snate@binkert.org    def p_type_enum(self, p):
3816657Snate@binkert.org        "type_enum : ident pairs SEMI"
3826657Snate@binkert.org        p[0] = ast.TypeFieldEnumAST(self, p[1], p[2])
3836657Snate@binkert.org
3846657Snate@binkert.org    # Type
3856657Snate@binkert.org    def p_types__multiple(self, p):
3866657Snate@binkert.org        "types : type ',' types"
3876657Snate@binkert.org        p[0] = [ p[1] ] + p[3]
3886657Snate@binkert.org
3896657Snate@binkert.org    def p_types__one(self, p):
3906657Snate@binkert.org        "types : type"
3916657Snate@binkert.org        p[0] = [ p[1] ]
3926657Snate@binkert.org
3936657Snate@binkert.org    def p_types__empty(self, p):
3946657Snate@binkert.org        "types : empty"
3956657Snate@binkert.org        p[0] = []
3966657Snate@binkert.org
3977055Snate@binkert.org    def p_typestr__multi(self, p):
3987055Snate@binkert.org        "typestr : typestr DOUBLE_COLON ident"
3997055Snate@binkert.org        p[0] = '%s::%s' % (p[1], p[3])
4007055Snate@binkert.org
4017055Snate@binkert.org    def p_typestr__single(self, p):
4027055Snate@binkert.org        "typestr : ident"
4037055Snate@binkert.org        p[0] = p[1]
4047055Snate@binkert.org
4057055Snate@binkert.org    def p_type__one(self, p):
4067055Snate@binkert.org        "type : typestr"
4076657Snate@binkert.org        p[0] = ast.TypeAST(self, p[1])
4086657Snate@binkert.org
4096657Snate@binkert.org    def p_void(self, p):
4106657Snate@binkert.org        "void : VOID"
4116657Snate@binkert.org        p[0] = ast.TypeAST(self, p[1])
4126657Snate@binkert.org
4136657Snate@binkert.org    def p_type_or_void(self, p):
4146657Snate@binkert.org        """type_or_void : type
4156657Snate@binkert.org                        | void"""
4166657Snate@binkert.org        p[0] = p[1]
4176657Snate@binkert.org
4186657Snate@binkert.org    # Formal Param
4196657Snate@binkert.org    def p_params__many(self, p):
4206657Snate@binkert.org        "params : param ',' params"
4216657Snate@binkert.org        p[0] = [ p[1] ] + p[3]
4226657Snate@binkert.org
4236657Snate@binkert.org    def p_params__one(self, p):
4246657Snate@binkert.org        "params : param"
4256657Snate@binkert.org        p[0] = [ p[1] ]
4266657Snate@binkert.org
4276657Snate@binkert.org    def p_params__none(self, p):
4286657Snate@binkert.org        "params : empty"
4296657Snate@binkert.org        p[0] = []
4306657Snate@binkert.org
4316657Snate@binkert.org    def p_param(self, p):
4326657Snate@binkert.org        "param : type ident"
4336657Snate@binkert.org        p[0] = ast.FormalParamAST(self, p[1], p[2])
4346657Snate@binkert.org
4356882SBrad.Beckmann@amd.com    def p_param__pointer(self, p):
4366882SBrad.Beckmann@amd.com        "param : type STAR ident"
4376882SBrad.Beckmann@amd.com        p[0] = ast.FormalParamAST(self, p[1], p[3], None, True)
4386882SBrad.Beckmann@amd.com
4396907SBrad.Beckmann@amd.com    def p_param__pointer_default(self, p):
4406907SBrad.Beckmann@amd.com        "param : type STAR ident '=' STRING"
4416907SBrad.Beckmann@amd.com        p[0] = ast.FormalParamAST(self, p[1], p[3], p[5], True)
4426907SBrad.Beckmann@amd.com
4436907SBrad.Beckmann@amd.com    def p_param__default_number(self, p):
4446877Ssteve.reinhardt@amd.com        "param : type ident '=' NUMBER"
4456877Ssteve.reinhardt@amd.com        p[0] = ast.FormalParamAST(self, p[1], p[2], p[4])
4466877Ssteve.reinhardt@amd.com
4476907SBrad.Beckmann@amd.com    def p_param__default_bool(self, p):
4486907SBrad.Beckmann@amd.com        "param : type ident '=' LIT_BOOL"
4496907SBrad.Beckmann@amd.com        p[0] = ast.FormalParamAST(self, p[1], p[2], p[4])
4506907SBrad.Beckmann@amd.com
4516907SBrad.Beckmann@amd.com    def p_param__default_string(self, p):
4526907SBrad.Beckmann@amd.com        "param : type ident '=' STRING"
4536907SBrad.Beckmann@amd.com        p[0] = ast.FormalParamAST(self, p[1], p[2], p[4])
4546907SBrad.Beckmann@amd.com
4556657Snate@binkert.org    # Idents and lists
4566657Snate@binkert.org    def p_idents__braced(self, p):
4576657Snate@binkert.org        "idents : '{' identx '}'"
4586657Snate@binkert.org        p[0] = p[2]
4596657Snate@binkert.org
4606657Snate@binkert.org    def p_idents__bare(self, p):
4616657Snate@binkert.org        "idents : ident"
4626657Snate@binkert.org        p[0] = [ p[1] ]
4636657Snate@binkert.org
4646657Snate@binkert.org    def p_identx__multiple_1(self, p):
4656657Snate@binkert.org        """identx : ident SEMI identx
4666657Snate@binkert.org                  | ident ',' identx"""
4676657Snate@binkert.org        p[0] = [ p[1] ] + p[3]
4686657Snate@binkert.org
4696657Snate@binkert.org    def p_identx__multiple_2(self, p):
4706657Snate@binkert.org        "identx : ident identx"
4716657Snate@binkert.org        p[0] = [ p[1] ] + p[2]
4726657Snate@binkert.org
4736657Snate@binkert.org    def p_identx__single(self, p):
4746657Snate@binkert.org        "identx : empty"
4756657Snate@binkert.org        p[0] = [ ]
4766657Snate@binkert.org
4776657Snate@binkert.org    def p_ident(self, p):
4786657Snate@binkert.org        "ident : IDENT"
4796657Snate@binkert.org        p[0] = p[1]
4806657Snate@binkert.org
4816657Snate@binkert.org    # Pair and pair lists
4826657Snate@binkert.org    def p_pairs__list(self, p):
4836657Snate@binkert.org        "pairs : ',' pairsx"
4846657Snate@binkert.org        p[0] = p[2]
4856657Snate@binkert.org
4866657Snate@binkert.org    def p_pairs__empty(self, p):
4876657Snate@binkert.org        "pairs : empty"
4886657Snate@binkert.org        p[0] = ast.PairListAST(self)
4896657Snate@binkert.org
4906657Snate@binkert.org    def p_pairsx__many(self, p):
4916657Snate@binkert.org        "pairsx : pair ',' pairsx"
4926657Snate@binkert.org        p[0] = p[3]
4936657Snate@binkert.org        p[0].addPair(p[1])
4946657Snate@binkert.org
4956657Snate@binkert.org    def p_pairsx__one(self, p):
4966657Snate@binkert.org        "pairsx : pair"
4976657Snate@binkert.org        p[0] = ast.PairListAST(self)
4986657Snate@binkert.org        p[0].addPair(p[1])
4996657Snate@binkert.org
5006657Snate@binkert.org    def p_pair__assign(self, p):
5016657Snate@binkert.org        """pair : ident '=' STRING
5026657Snate@binkert.org                | ident '=' ident"""
5036657Snate@binkert.org        p[0] = ast.PairAST(self, p[1], p[3])
5046657Snate@binkert.org
5056657Snate@binkert.org    def p_pair__literal(self, p):
5066657Snate@binkert.org        "pair : STRING"
5076657Snate@binkert.org        p[0] = ast.PairAST(self, "short", p[1])
5086657Snate@binkert.org
5096657Snate@binkert.org    # Below are the rules for action descriptions
5106657Snate@binkert.org    def p_statements__inner(self, p):
5116657Snate@binkert.org        "statements : '{' statements_inner '}'"
5126657Snate@binkert.org        p[0] = ast.StatementListAST(self, p[2])
5136657Snate@binkert.org
5146657Snate@binkert.org    def p_statements__none(self, p):
5156657Snate@binkert.org        "statements : '{' '}'"
5166657Snate@binkert.org        p[0] = ast.StatementListAST(self, [])
5176657Snate@binkert.org
5186657Snate@binkert.org    def p_statements_inner__many(self, p):
5196657Snate@binkert.org        "statements_inner : statement statements_inner"
5206657Snate@binkert.org        p[0] = [ p[1] ] + p[2]
5216657Snate@binkert.org
5226657Snate@binkert.org    def p_statements_inner__one(self, p):
5236657Snate@binkert.org        "statements_inner : statement"
5246657Snate@binkert.org        p[0] = [ p[1] ]
5256657Snate@binkert.org
5266657Snate@binkert.org    def p_exprs__multiple(self, p):
5276657Snate@binkert.org        "exprs : expr ',' exprs"
5286657Snate@binkert.org        p[0] = [ p[1] ] + p[3]
5296657Snate@binkert.org
5306657Snate@binkert.org    def p_exprs__one(self, p):
5316657Snate@binkert.org        "exprs : expr"
5326657Snate@binkert.org        p[0] = [ p[1] ]
5336657Snate@binkert.org
5346657Snate@binkert.org    def p_exprs__empty(self, p):
5356657Snate@binkert.org        "exprs : empty"""
5366657Snate@binkert.org        p[0] = []
5376657Snate@binkert.org
5386657Snate@binkert.org    def p_statement__expression(self, p):
5396657Snate@binkert.org        "statement : expr SEMI"
5406657Snate@binkert.org        p[0] = ast.ExprStatementAST(self, p[1])
5416657Snate@binkert.org
5426657Snate@binkert.org    def p_statement__assign(self, p):
5436657Snate@binkert.org        "statement : expr ASSIGN expr SEMI"
5446657Snate@binkert.org        p[0] = ast.AssignStatementAST(self, p[1], p[3])
5456657Snate@binkert.org
5466657Snate@binkert.org    def p_statement__enqueue(self, p):
5476657Snate@binkert.org        "statement : ENQUEUE '(' var ',' type pairs ')' statements"
5486657Snate@binkert.org        p[0] = ast.EnqueueStatementAST(self, p[3], p[5], p[6], p[8])
5496657Snate@binkert.org
5506657Snate@binkert.org    def p_statement__peek(self, p):
5516863Sdrh5@cs.wisc.edu        "statement : PEEK '(' var ',' type pairs ')' statements"
5526863Sdrh5@cs.wisc.edu        p[0] = ast.PeekStatementAST(self, p[3], p[5], p[6], p[8], "peek")
5536657Snate@binkert.org
5546657Snate@binkert.org    def p_statement__copy_head(self, p):
5556657Snate@binkert.org        "statement : COPY_HEAD '(' var ',' var pairs ')' SEMI"
5566657Snate@binkert.org        p[0] = ast.CopyHeadStatementAST(self, p[3], p[5], p[6])
5576657Snate@binkert.org
5586657Snate@binkert.org    def p_statement__check_allocate(self, p):
5596657Snate@binkert.org        "statement : CHECK_ALLOCATE '(' var ')' SEMI"
5606657Snate@binkert.org        p[0] = ast.CheckAllocateStatementAST(self, p[3])
5616657Snate@binkert.org
5626657Snate@binkert.org    def p_statement__check_stop(self, p):
5636657Snate@binkert.org        "statement : CHECK_STOP_SLOTS '(' var ',' STRING ',' STRING ')' SEMI"
5646657Snate@binkert.org        p[0] = ast.CheckStopStatementAST(self, p[3], p[5], p[7])
5656657Snate@binkert.org
5666882SBrad.Beckmann@amd.com    def p_statement__static_cast(self, p):
5676882SBrad.Beckmann@amd.com        "aexpr : STATIC_CAST '(' type ',' expr ')'"
5686882SBrad.Beckmann@amd.com        p[0] = ast.StaticCastAST(self, p[3], p[5])
5696882SBrad.Beckmann@amd.com
5706657Snate@binkert.org    def p_statement__return(self, p):
5716657Snate@binkert.org        "statement : RETURN expr SEMI"
5726657Snate@binkert.org        p[0] = ast.ReturnStatementAST(self, p[2])
5736657Snate@binkert.org
5746657Snate@binkert.org    def p_statement__if(self, p):
5756657Snate@binkert.org        "statement : if_statement"
5766657Snate@binkert.org        p[0] = p[1]
5776657Snate@binkert.org
5786657Snate@binkert.org    def p_if_statement__if(self, p):
5796657Snate@binkert.org        "if_statement : IF '(' expr ')' statements"
5806657Snate@binkert.org        p[0] = ast.IfStatementAST(self, p[3], p[5], None)
5816657Snate@binkert.org
5826657Snate@binkert.org    def p_if_statement__if_else(self, p):
5836657Snate@binkert.org        "if_statement : IF '(' expr ')' statements ELSE statements"
5846657Snate@binkert.org        p[0] = ast.IfStatementAST(self, p[3], p[5], p[7])
5856657Snate@binkert.org
5866657Snate@binkert.org    def p_statement__if_else_if(self, p):
5876657Snate@binkert.org        "if_statement : IF '(' expr ')' statements ELSE if_statement"
5886657Snate@binkert.org        p[0] = ast.IfStatementAST(self, p[3], p[5],
5896657Snate@binkert.org                                  ast.StatementListAST(self, p[7]))
5906657Snate@binkert.org
5916657Snate@binkert.org    def p_expr__var(self, p):
5926657Snate@binkert.org        "aexpr : var"
5936657Snate@binkert.org        p[0] = p[1]
5946657Snate@binkert.org
5956657Snate@binkert.org    def p_expr__literal(self, p):
5966657Snate@binkert.org        "aexpr : literal"
5976657Snate@binkert.org        p[0] = p[1]
5986657Snate@binkert.org
5996657Snate@binkert.org    def p_expr__enumeration(self, p):
6006657Snate@binkert.org        "aexpr : enumeration"
6016657Snate@binkert.org        p[0] = p[1]
6026657Snate@binkert.org
6036657Snate@binkert.org    def p_expr__func_call(self, p):
6046657Snate@binkert.org        "aexpr : ident '(' exprs ')'"
6056657Snate@binkert.org        p[0] = ast.FuncCallExprAST(self, p[1], p[3])
6066657Snate@binkert.org
6076657Snate@binkert.org    def p_expr__new(self, p):
6086657Snate@binkert.org        "aexpr : NEW type"
6096657Snate@binkert.org        p[0] = ast.NewExprAST(self, p[2])
6106657Snate@binkert.org
6116657Snate@binkert.org    # globally access a local chip component and call a method
6126657Snate@binkert.org    def p_expr__local_chip_method(self, p):
6136657Snate@binkert.org        "aexpr : THIS DOT var '[' expr ']' DOT var DOT ident '(' exprs ')'"
6146657Snate@binkert.org        p[0] = ast.LocalChipMethodAST(self, p[3], p[5], p[8], p[10], p[12])
6156657Snate@binkert.org
6166657Snate@binkert.org    # globally access a local chip component and access a data member
6176657Snate@binkert.org    def p_expr__local_chip_member(self, p):
6186657Snate@binkert.org        "aexpr : THIS DOT var '[' expr ']' DOT var DOT field"
6196657Snate@binkert.org        p[0] = ast.LocalChipMemberAST(self, p[3], p[5], p[8], p[10])
6206657Snate@binkert.org
6216657Snate@binkert.org    # globally access a specified chip component and call a method
6226657Snate@binkert.org    def p_expr__specified_chip_method(self, p):
6236657Snate@binkert.org        "aexpr : CHIP '[' expr ']' DOT var '[' expr ']' DOT var DOT ident '(' exprs ')'"
6246657Snate@binkert.org        p[0] = ast.SpecifiedChipMethodAST(self, p[3], p[6], p[8], p[11], p[13],
6256657Snate@binkert.org                                          p[15])
6266657Snate@binkert.org
6276657Snate@binkert.org    # globally access a specified chip component and access a data member
6286657Snate@binkert.org    def p_expr__specified_chip_member(self, p):
6296657Snate@binkert.org        "aexpr : CHIP '[' expr ']' DOT var '[' expr ']' DOT var DOT field"
6306657Snate@binkert.org        p[0] = ast.SpecifiedChipMemberAST(self, p[3], p[6], p[8], p[11], p[13])
6316657Snate@binkert.org
6326657Snate@binkert.org    def p_expr__member(self, p):
6336657Snate@binkert.org        "aexpr : aexpr DOT ident"
6346657Snate@binkert.org        p[0] = ast.MemberExprAST(self, p[1], p[3])
6356657Snate@binkert.org
6366657Snate@binkert.org    def p_expr__member_method_call(self, p):
6376657Snate@binkert.org        "aexpr : aexpr DOT ident '(' exprs ')'"
6386657Snate@binkert.org        p[0] = ast.MemberMethodCallExprAST(self, p[1], p[3], p[5])
6396657Snate@binkert.org
6406657Snate@binkert.org    def p_expr__member_method_call_lookup(self, p):
6416657Snate@binkert.org        "aexpr : aexpr '[' exprs ']'"
6426657Snate@binkert.org        p[0] = ast.MemberMethodCallExprAST(self, p[1], "lookup", p[3])
6436657Snate@binkert.org
6446657Snate@binkert.org    def p_expr__class_method_call(self, p):
6456657Snate@binkert.org        "aexpr : type DOUBLE_COLON ident '(' exprs ')'"
6466657Snate@binkert.org        p[0] = ast.ClassMethodCallExprAST(self, p[1], p[3], p[5])
6476657Snate@binkert.org
6486657Snate@binkert.org    def p_expr__aexpr(self, p):
6496657Snate@binkert.org        "expr : aexpr"
6506657Snate@binkert.org        p[0] = p[1]
6516657Snate@binkert.org
6526657Snate@binkert.org    def p_expr__binary_op(self, p):
6536657Snate@binkert.org        """expr : expr STAR  expr
6546657Snate@binkert.org                | expr SLASH expr
6556657Snate@binkert.org                | expr PLUS  expr
6566657Snate@binkert.org                | expr DASH  expr
6576657Snate@binkert.org                | expr LT    expr
6586657Snate@binkert.org                | expr GT    expr
6596657Snate@binkert.org                | expr LE    expr
6606657Snate@binkert.org                | expr GE    expr
6616657Snate@binkert.org                | expr EQ    expr
6626657Snate@binkert.org                | expr NE    expr
6636657Snate@binkert.org                | expr AND   expr
6646657Snate@binkert.org                | expr OR    expr
6656657Snate@binkert.org                | expr RIGHTSHIFT expr
6666657Snate@binkert.org                | expr LEFTSHIFT  expr"""
6676657Snate@binkert.org        p[0] = ast.InfixOperatorExprAST(self, p[1], p[2], p[3])
6686657Snate@binkert.org
6696657Snate@binkert.org    # FIXME - unary not
6706657Snate@binkert.org    def p_expr__unary_op(self, p):
6716657Snate@binkert.org        """expr : NOT expr
6726657Snate@binkert.org                | DASH expr %prec UMINUS"""
6736657Snate@binkert.org        p[0] = PrefixOperatorExpr(p[1], p[2])
6746657Snate@binkert.org
6756657Snate@binkert.org    def p_expr__parens(self, p):
6766657Snate@binkert.org        "aexpr : '(' expr ')'"
6776657Snate@binkert.org        p[0] = p[2]
6786657Snate@binkert.org
6796657Snate@binkert.org    def p_literal__string(self, p):
6806657Snate@binkert.org        "literal : STRING"
6817055Snate@binkert.org        p[0] = ast.LiteralExprAST(self, p[1], "std::string")
6826657Snate@binkert.org
6836657Snate@binkert.org    def p_literal__number(self, p):
6846657Snate@binkert.org        "literal : NUMBER"
6856657Snate@binkert.org        p[0] = ast.LiteralExprAST(self, p[1], "int")
6866657Snate@binkert.org
6876657Snate@binkert.org    def p_literal__float(self, p):
6886657Snate@binkert.org        "literal : FLOATNUMBER"
6896657Snate@binkert.org        p[0] = ast.LiteralExprAST(self, p[1], "int")
6906657Snate@binkert.org
6916657Snate@binkert.org    def p_literal__bool(self, p):
6926657Snate@binkert.org        "literal : LIT_BOOL"
6936657Snate@binkert.org        p[0] = ast.LiteralExprAST(self, p[1], "bool")
6946657Snate@binkert.org
6956657Snate@binkert.org    def p_enumeration(self, p):
6966657Snate@binkert.org        "enumeration : ident ':' ident"
6976657Snate@binkert.org        p[0] = ast.EnumExprAST(self, ast.TypeAST(self, p[1]), p[3])
6986657Snate@binkert.org
6996657Snate@binkert.org    def p_var(self, p):
7006657Snate@binkert.org        "var : ident"
7016657Snate@binkert.org        p[0] = ast.VarExprAST(self, p[1])
7026657Snate@binkert.org
7036657Snate@binkert.org    def p_field(self, p):
7046657Snate@binkert.org        "field : ident"
7056657Snate@binkert.org        p[0] = p[1]
706