# parser for Unix yacc-based grammars
#
# Author: David Beazley (dave@dabeaz.com)
# Date  : October 2, 2006

import ylex
tokens = ylex.tokens

from ply import *

tokenlist = []
preclist  = []

emit_code = 1

def p_yacc(p):
    '''yacc : defsection rulesection'''

def p_defsection(p):
    '''defsection : definitions SECTION
                  | SECTION'''
    p.lexer.lastsection = 1
    print "tokens = ", repr(tokenlist)
    print
    print "precedence = ", repr(preclist)
    print
    print "# -------------- RULES ----------------"
    print

def p_rulesection(p):
    '''rulesection : rules SECTION'''

    print "# -------------- RULES END ----------------"
    print_code(p[2],0)

def p_definitions(p):
    '''definitions : definitions definition
                   | definition'''

def p_definition_literal(p):
    '''definition : LITERAL'''
    print_code(p[1],0)

def p_definition_start(p):
    '''definition : START ID'''
    print "start = '%s'" % p[2]

def p_definition_token(p):
    '''definition : toktype opttype idlist optsemi '''
    for i in p[3]:
       if i[0] not in "'\"":
           tokenlist.append(i)
    if p[1] == '%left':
        preclist.append(('left',) + tuple(p[3]))
    elif p[1] == '%right':
        preclist.append(('right',) + tuple(p[3]))
    elif p[1] == '%nonassoc':
        preclist.append(('nonassoc',)+ tuple(p[3]))

def p_toktype(p):
    '''toktype : TOKEN
               | LEFT
               | RIGHT
               | NONASSOC'''
    p[0] = p[1]

def p_opttype(p):
    '''opttype : '<' ID '>'
               | empty'''

def p_idlist(p):
    '''idlist  : idlist optcomma tokenid
               | tokenid'''
    if len(p) == 2:
        p[0] = [p[1]]
    else:
        p[0] = p[1]
        p[1].append(p[3])

def p_tokenid(p):
    '''tokenid : ID
               | ID NUMBER
               | QLITERAL
               | QLITERAL NUMBER'''
    p[0] = p[1]

def p_optsemi(p):
    '''optsemi : ';'
               | empty'''

def p_optcomma(p):
    '''optcomma : ','
                | empty'''

def p_definition_type(p):
    '''definition : TYPE '<' ID '>' namelist optsemi'''
    # type declarations are ignored

def p_namelist(p):
    '''namelist : namelist optcomma ID
                | ID'''

def p_definition_union(p):
    '''definition : UNION CODE optsemi'''
    # Union declarations are ignored

def p_rules(p):
    '''rules   : rules rule
               | rule'''
    if len(p) == 2:
       rule = p[1]
    else:
       rule = p[2]

    # Print out a Python equivalent of this rule

    embedded = [ ]      # Embedded actions (a mess)
    embed_count = 0

    rulename = rule[0]
    rulecount = 1
    for r in rule[1]:
        # r contains one of the rule possibilities
        print "def p_%s_%d(p):" % (rulename,rulecount)
        prod = []
        prodcode = ""
        for i in range(len(r)):
             item = r[i]
             if item[0] == '{':    # A code block
                  if i == len(r) - 1:
                      prodcode = item
                      break
                  else:
                      # an embedded action
                      embed_name = "_embed%d_%s" % (embed_count,rulename)
                      prod.append(embed_name)
                      embedded.append((embed_name,item))
                      embed_count += 1
             else:
                  prod.append(item)
        print "    '''%s : %s'''" % (rulename, " ".join(prod))
        # Emit code
        print_code(prodcode,4)
        print
        rulecount += 1

    for e,code in embedded:
        print "def p_%s(p):" % e
        print "    '''%s : '''" % e
        print_code(code,4)
        print

def p_rule(p):
   '''rule : ID ':' rulelist ';' '''
   p[0] = (p[1],[p[3]])

def p_rule2(p):
   '''rule : ID ':' rulelist morerules ';' '''
   p[4].insert(0,p[3])
   p[0] = (p[1],p[4])

def p_rule_empty(p):
   '''rule : ID ':' ';' '''
   p[0] = (p[1],[[]])

def p_rule_empty2(p):
   '''rule : ID ':' morerules ';' '''

   p[3].insert(0,[])
   p[0] = (p[1],p[3])

def p_morerules(p):
   '''morerules : morerules '|' rulelist
                | '|' rulelist
                | '|'  '''

   if len(p) == 2:
       p[0] = [[]]
   elif len(p) == 3:
       p[0] = [p[2]]
   else:
       p[0] = p[1]
       p[0].append(p[3])

#   print "morerules", len(p), p[0]

def p_rulelist(p):
   '''rulelist : rulelist ruleitem
               | ruleitem'''

   if len(p) == 2:
        p[0] = [p[1]]
   else:
        p[0] = p[1]
        p[1].append(p[2])

def p_ruleitem(p):
   '''ruleitem : ID
               | QLITERAL
               | CODE
               | PREC'''
   p[0] = p[1]

def p_empty(p):
    '''empty : '''

def p_error(p):
    pass

yacc.yacc(debug=0)

def print_code(code,indent):
    if not emit_code: return
    codelines = code.splitlines()
    for c in codelines:
         print "%s# %s" % (" "*indent,c)

