14479Sbinkertn@umich.edu# parser for Unix yacc-based grammars
24479Sbinkertn@umich.edu#
34479Sbinkertn@umich.edu# Author: David Beazley (dave@dabeaz.com)
44479Sbinkertn@umich.edu# Date  : October 2, 2006
54479Sbinkertn@umich.edu
64479Sbinkertn@umich.eduimport ylex
74479Sbinkertn@umich.edutokens = ylex.tokens
84479Sbinkertn@umich.edu
94479Sbinkertn@umich.edufrom ply import *
104479Sbinkertn@umich.edu
114479Sbinkertn@umich.edutokenlist = []
124479Sbinkertn@umich.edupreclist  = []
134479Sbinkertn@umich.edu
144479Sbinkertn@umich.eduemit_code = 1
154479Sbinkertn@umich.edu
164479Sbinkertn@umich.edudef p_yacc(p):
174479Sbinkertn@umich.edu    '''yacc : defsection rulesection'''
184479Sbinkertn@umich.edu
194479Sbinkertn@umich.edudef p_defsection(p):
204479Sbinkertn@umich.edu    '''defsection : definitions SECTION
214479Sbinkertn@umich.edu                  | SECTION'''
224479Sbinkertn@umich.edu    p.lexer.lastsection = 1
234479Sbinkertn@umich.edu    print "tokens = ", repr(tokenlist)
244479Sbinkertn@umich.edu    print
254479Sbinkertn@umich.edu    print "precedence = ", repr(preclist)
264479Sbinkertn@umich.edu    print
274479Sbinkertn@umich.edu    print "# -------------- RULES ----------------"
286498Snate@binkert.org    print
294479Sbinkertn@umich.edu
304479Sbinkertn@umich.edudef p_rulesection(p):
314479Sbinkertn@umich.edu    '''rulesection : rules SECTION'''
324479Sbinkertn@umich.edu
334479Sbinkertn@umich.edu    print "# -------------- RULES END ----------------"
344479Sbinkertn@umich.edu    print_code(p[2],0)
354479Sbinkertn@umich.edu
364479Sbinkertn@umich.edudef p_definitions(p):
374479Sbinkertn@umich.edu    '''definitions : definitions definition
384479Sbinkertn@umich.edu                   | definition'''
394479Sbinkertn@umich.edu
404479Sbinkertn@umich.edudef p_definition_literal(p):
414479Sbinkertn@umich.edu    '''definition : LITERAL'''
424479Sbinkertn@umich.edu    print_code(p[1],0)
434479Sbinkertn@umich.edu
444479Sbinkertn@umich.edudef p_definition_start(p):
454479Sbinkertn@umich.edu    '''definition : START ID'''
464479Sbinkertn@umich.edu    print "start = '%s'" % p[2]
474479Sbinkertn@umich.edu
484479Sbinkertn@umich.edudef p_definition_token(p):
494479Sbinkertn@umich.edu    '''definition : toktype opttype idlist optsemi '''
504479Sbinkertn@umich.edu    for i in p[3]:
514479Sbinkertn@umich.edu       if i[0] not in "'\"":
524479Sbinkertn@umich.edu           tokenlist.append(i)
534479Sbinkertn@umich.edu    if p[1] == '%left':
544479Sbinkertn@umich.edu        preclist.append(('left',) + tuple(p[3]))
554479Sbinkertn@umich.edu    elif p[1] == '%right':
564479Sbinkertn@umich.edu        preclist.append(('right',) + tuple(p[3]))
574479Sbinkertn@umich.edu    elif p[1] == '%nonassoc':
584479Sbinkertn@umich.edu        preclist.append(('nonassoc',)+ tuple(p[3]))
594479Sbinkertn@umich.edu
604479Sbinkertn@umich.edudef p_toktype(p):
614479Sbinkertn@umich.edu    '''toktype : TOKEN
624479Sbinkertn@umich.edu               | LEFT
634479Sbinkertn@umich.edu               | RIGHT
644479Sbinkertn@umich.edu               | NONASSOC'''
654479Sbinkertn@umich.edu    p[0] = p[1]
664479Sbinkertn@umich.edu
674479Sbinkertn@umich.edudef p_opttype(p):
684479Sbinkertn@umich.edu    '''opttype : '<' ID '>'
694479Sbinkertn@umich.edu               | empty'''
704479Sbinkertn@umich.edu
714479Sbinkertn@umich.edudef p_idlist(p):
724479Sbinkertn@umich.edu    '''idlist  : idlist optcomma tokenid
734479Sbinkertn@umich.edu               | tokenid'''
744479Sbinkertn@umich.edu    if len(p) == 2:
754479Sbinkertn@umich.edu        p[0] = [p[1]]
764479Sbinkertn@umich.edu    else:
774479Sbinkertn@umich.edu        p[0] = p[1]
784479Sbinkertn@umich.edu        p[1].append(p[3])
794479Sbinkertn@umich.edu
804479Sbinkertn@umich.edudef p_tokenid(p):
816498Snate@binkert.org    '''tokenid : ID
824479Sbinkertn@umich.edu               | ID NUMBER
834479Sbinkertn@umich.edu               | QLITERAL
844479Sbinkertn@umich.edu               | QLITERAL NUMBER'''
854479Sbinkertn@umich.edu    p[0] = p[1]
866498Snate@binkert.org
874479Sbinkertn@umich.edudef p_optsemi(p):
884479Sbinkertn@umich.edu    '''optsemi : ';'
894479Sbinkertn@umich.edu               | empty'''
904479Sbinkertn@umich.edu
914479Sbinkertn@umich.edudef p_optcomma(p):
924479Sbinkertn@umich.edu    '''optcomma : ','
934479Sbinkertn@umich.edu                | empty'''
944479Sbinkertn@umich.edu
954479Sbinkertn@umich.edudef p_definition_type(p):
964479Sbinkertn@umich.edu    '''definition : TYPE '<' ID '>' namelist optsemi'''
974479Sbinkertn@umich.edu    # type declarations are ignored
984479Sbinkertn@umich.edu
994479Sbinkertn@umich.edudef p_namelist(p):
1004479Sbinkertn@umich.edu    '''namelist : namelist optcomma ID
1014479Sbinkertn@umich.edu                | ID'''
1024479Sbinkertn@umich.edu
1034479Sbinkertn@umich.edudef p_definition_union(p):
1044479Sbinkertn@umich.edu    '''definition : UNION CODE optsemi'''
1054479Sbinkertn@umich.edu    # Union declarations are ignored
1064479Sbinkertn@umich.edu
1074479Sbinkertn@umich.edudef p_rules(p):
1084479Sbinkertn@umich.edu    '''rules   : rules rule
1094479Sbinkertn@umich.edu               | rule'''
1104479Sbinkertn@umich.edu    if len(p) == 2:
1114479Sbinkertn@umich.edu       rule = p[1]
1124479Sbinkertn@umich.edu    else:
1134479Sbinkertn@umich.edu       rule = p[2]
1144479Sbinkertn@umich.edu
1154479Sbinkertn@umich.edu    # Print out a Python equivalent of this rule
1164479Sbinkertn@umich.edu
1174479Sbinkertn@umich.edu    embedded = [ ]      # Embedded actions (a mess)
1184479Sbinkertn@umich.edu    embed_count = 0
1194479Sbinkertn@umich.edu
1204479Sbinkertn@umich.edu    rulename = rule[0]
1214479Sbinkertn@umich.edu    rulecount = 1
1224479Sbinkertn@umich.edu    for r in rule[1]:
1234479Sbinkertn@umich.edu        # r contains one of the rule possibilities
1244479Sbinkertn@umich.edu        print "def p_%s_%d(p):" % (rulename,rulecount)
1254479Sbinkertn@umich.edu        prod = []
1264479Sbinkertn@umich.edu        prodcode = ""
1274479Sbinkertn@umich.edu        for i in range(len(r)):
1284479Sbinkertn@umich.edu             item = r[i]
1294479Sbinkertn@umich.edu             if item[0] == '{':    # A code block
1304479Sbinkertn@umich.edu                  if i == len(r) - 1:
1314479Sbinkertn@umich.edu                      prodcode = item
1324479Sbinkertn@umich.edu                      break
1334479Sbinkertn@umich.edu                  else:
1344479Sbinkertn@umich.edu                      # an embedded action
1354479Sbinkertn@umich.edu                      embed_name = "_embed%d_%s" % (embed_count,rulename)
1364479Sbinkertn@umich.edu                      prod.append(embed_name)
1374479Sbinkertn@umich.edu                      embedded.append((embed_name,item))
1384479Sbinkertn@umich.edu                      embed_count += 1
1394479Sbinkertn@umich.edu             else:
1404479Sbinkertn@umich.edu                  prod.append(item)
1414479Sbinkertn@umich.edu        print "    '''%s : %s'''" % (rulename, " ".join(prod))
1424479Sbinkertn@umich.edu        # Emit code
1434479Sbinkertn@umich.edu        print_code(prodcode,4)
1444479Sbinkertn@umich.edu        print
1454479Sbinkertn@umich.edu        rulecount += 1
1464479Sbinkertn@umich.edu
1474479Sbinkertn@umich.edu    for e,code in embedded:
1484479Sbinkertn@umich.edu        print "def p_%s(p):" % e
1494479Sbinkertn@umich.edu        print "    '''%s : '''" % e
1504479Sbinkertn@umich.edu        print_code(code,4)
1514479Sbinkertn@umich.edu        print
1524479Sbinkertn@umich.edu
1534479Sbinkertn@umich.edudef p_rule(p):
1544479Sbinkertn@umich.edu   '''rule : ID ':' rulelist ';' '''
1554479Sbinkertn@umich.edu   p[0] = (p[1],[p[3]])
1564479Sbinkertn@umich.edu
1574479Sbinkertn@umich.edudef p_rule2(p):
1584479Sbinkertn@umich.edu   '''rule : ID ':' rulelist morerules ';' '''
1594479Sbinkertn@umich.edu   p[4].insert(0,p[3])
1604479Sbinkertn@umich.edu   p[0] = (p[1],p[4])
1614479Sbinkertn@umich.edu
1624479Sbinkertn@umich.edudef p_rule_empty(p):
1634479Sbinkertn@umich.edu   '''rule : ID ':' ';' '''
1644479Sbinkertn@umich.edu   p[0] = (p[1],[[]])
1654479Sbinkertn@umich.edu
1664479Sbinkertn@umich.edudef p_rule_empty2(p):
1674479Sbinkertn@umich.edu   '''rule : ID ':' morerules ';' '''
1686498Snate@binkert.org
1694479Sbinkertn@umich.edu   p[3].insert(0,[])
1704479Sbinkertn@umich.edu   p[0] = (p[1],p[3])
1714479Sbinkertn@umich.edu
1724479Sbinkertn@umich.edudef p_morerules(p):
1734479Sbinkertn@umich.edu   '''morerules : morerules '|' rulelist
1744479Sbinkertn@umich.edu                | '|' rulelist
1754479Sbinkertn@umich.edu                | '|'  '''
1766498Snate@binkert.org
1776498Snate@binkert.org   if len(p) == 2:
1784479Sbinkertn@umich.edu       p[0] = [[]]
1796498Snate@binkert.org   elif len(p) == 3:
1804479Sbinkertn@umich.edu       p[0] = [p[2]]
1814479Sbinkertn@umich.edu   else:
1824479Sbinkertn@umich.edu       p[0] = p[1]
1834479Sbinkertn@umich.edu       p[0].append(p[3])
1844479Sbinkertn@umich.edu
1854479Sbinkertn@umich.edu#   print "morerules", len(p), p[0]
1864479Sbinkertn@umich.edu
1874479Sbinkertn@umich.edudef p_rulelist(p):
1884479Sbinkertn@umich.edu   '''rulelist : rulelist ruleitem
1894479Sbinkertn@umich.edu               | ruleitem'''
1904479Sbinkertn@umich.edu
1914479Sbinkertn@umich.edu   if len(p) == 2:
1924479Sbinkertn@umich.edu        p[0] = [p[1]]
1934479Sbinkertn@umich.edu   else:
1944479Sbinkertn@umich.edu        p[0] = p[1]
1954479Sbinkertn@umich.edu        p[1].append(p[2])
1964479Sbinkertn@umich.edu
1974479Sbinkertn@umich.edudef p_ruleitem(p):
1984479Sbinkertn@umich.edu   '''ruleitem : ID
1994479Sbinkertn@umich.edu               | QLITERAL
2004479Sbinkertn@umich.edu               | CODE
2014479Sbinkertn@umich.edu               | PREC'''
2024479Sbinkertn@umich.edu   p[0] = p[1]
2034479Sbinkertn@umich.edu
2044479Sbinkertn@umich.edudef p_empty(p):
2054479Sbinkertn@umich.edu    '''empty : '''
2064479Sbinkertn@umich.edu
2074479Sbinkertn@umich.edudef p_error(p):
2084479Sbinkertn@umich.edu    pass
2094479Sbinkertn@umich.edu
2104479Sbinkertn@umich.eduyacc.yacc(debug=0)
2114479Sbinkertn@umich.edu
2124479Sbinkertn@umich.edudef print_code(code,indent):
2134479Sbinkertn@umich.edu    if not emit_code: return
2144479Sbinkertn@umich.edu    codelines = code.splitlines()
2154479Sbinkertn@umich.edu    for c in codelines:
2164479Sbinkertn@umich.edu         print "%s# %s" % (" "*indent,c)
2174479Sbinkertn@umich.edu
218