简体   繁体   English

如何在python中设置ply的yacc优先级?

[英]How to set the precedence of yacc of ply in python?

I need to make a AST from a regular expression using ply. 我需要使用ply从正则表达式中创建一个AST。 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. 例如,如果RE是(a | b *)abc,我想把削弱的元组设为(':',(':',(':',('|','a',('* ','b')),'a'),'b'),'c')< - ':'表示将字符串分成两部分。

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)

To resurrect this question, ply allows you to set a precedence variable that contains the precedence for the symbols. 要恢复此问题,ply允许您设置包含符号优先级的优先级变量。 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) 您可以在这里找到完整的教程和文档: http//www.dabeaz.com/ply/ply.html#ply_nn27 (我必须使用查找功能来找到正确的位置)

I can't answer your question directly. 我不能直接回答你的问题。 However, you could perhaps consider using greenery . 但是,你也许可以考虑使用绿色植物

>>> from greenery.lego import parse
>>> thingy = parse('(a|b*)abc')
>>> thingy.to_fsm()
fsm(alphabet = {'b', 'c', anything_else, 'a'}, states = {0, 1, 2, 3, 4, 5}, initial = 0, finals = {5}, map = {0: {'b': 2, 'a': 1}, 1: {'b': 4, 'a': 3}, 2: {'b': 2, 'a': 3}, 3: {'b': 4}, 4: {'c': 5}, 5: {}})

I think you could recover what you want by stepping backwards recursively from the each of the finals states in map . 我认为你可以通过递归地从地图中的每个决赛状态向后退步来恢复你想要的东西。

If you down-vote please indicate why. 如果您投票,请说明原因。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM