3

I need to make a AST from a regular expression using ply. For example, if the RE is (a|b*)abc, I want to make a pared tuple as (':', (':', (':', ('|', 'a', ('*', 'b')), 'a'), 'b'), 'c') <-- ':' means just split a string in two parts.

Here is my code.

tokens = (
    "SYMBOL",
    "LBRACKET",
    "RBRACKET",
    "STAR",
    "UNION"
)

t_ignore = ' \t\n'
t_SYMBOL = r'[a-zA-Z0-9]'
t_LBRACKET = r'\('
t_RBRACKET = r'\)'
t_STAR = r'\*'
t_UNION = r'\|'

def t_error(t):
    raise TypeError("Unknown text '%s'" % t.value)

def p_multiple(p) :
    '''string : SYMBOL SYMBOL
              | string SYMBOL
              | string string'''
    p[0] = (':', p[1], p[2])    

def p_union(p) :
    '''string : string UNION string'''
    p[0] = ('|', p[1], p[3])

def p_star(p) :
    '''string : string STAR'''
    p[0] = ('*', p[1])

def p_brackets(p) :
    '''string : LBRACKET string RBRACKET'''
    p[0] = p[2]


def p_symbol(p) :
    '''string : SYMBOL'''
    p[0] = p[1]

def p_error(p):
    print ("Syntax error at '%s'" % p.value)

lex.lex()
yacc.yacc()

lex.input("(a|b*)abc")
parsed = yacc.parse(RE)
Trenton McKinney
  • 56,955
  • 33
  • 144
  • 158
auto_auto
  • 31
  • 1
  • 2

1 Answers1

5

To resurrect this question, ply allows you to set a precedence variable that contains the precedence for the symbols. For example:

precedence = (
    ('left', 'PLUS', 'MINUS'),
    ('left', 'TIMES', 'DIVIDE'),
)

You can find a full tutorial and documentation here: http://www.dabeaz.com/ply/ply.html#ply_nn27 (I had to use find functionality for finding the right spot)

Hovestar
  • 1,544
  • 4
  • 18
  • 26