使用递归评估字符串

时间:2014-03-16 16:46:00

标签: python

我试图创建一个返回True的函数,传入的字符串是'1'(有效)或'1*'(有效)或'(' + valid + '|' + valid + ')'的形式(有效)。我的意思是最后一部分是例如:

(1|1)< - 因为它以'(' + valid + '|' + valid + ')''1'的形式有效。 ((1|1)|1)< - 因为它的格式为'(' + valid + '|' + valid + ')'(1|1)有效,所以' 1'

((1|(1|1))|1)< - 因为它的格式为'(' + valid + '|' + valid + ')'(1|(1|1))有效,因此'1'

我的计划:

  • 1。)如果传入的字符串是' 1',则返回True(基本案例)
  • 2。)如果传入的字符串是' 1' *' *',则返回True
  • 3。)否则,如果传入的字符串以'('并以'结尾)开头。    查看括号内的内容,找到' |'符号    那不在另一个括号内。一旦找到它再次运行该功能    在找到的符号左侧的字符串上,并再次运行该函数    在找到的符号右侧的字符串上。如果两者都是True则为字符串    是真的(递归步骤)
  • 4。)如果传入任何其他内容,则返回False。

我的代码基于我的计划:

def check(s):
    if s == '1':
        return True
    elif s == '1'+'*':
        return True
    else:
        if s.startswith('(') and s.endswith(')'):
            #TO-DO
            pass
    return False 

一些例子:

check('((1|1)|1)')
True
check('((1|1*)|1)')
True
check('(1|1)')
True
check('1')
True
check('1*')
True
check('((1|(1|1))|1)')
True
check('((1|(1|1))|((1|(1|1))|1))')
True
check('*1')
False
check('2')
False
check('((1|(1|1));1)')
False

我在这上花了3天时间仍然无法弄清楚如何进行递归步骤,所以我希望有人可以帮助我。我无法弄清楚如何找到不在另一组括号内的'*'符号。我想如果我能够找到'*'符号而不是我自己可以做的其他符号。

我确信我们可以使用re模块执行此操作,但我们只是假装我们无法使用它。

1 个答案:

答案 0 :(得分:2)

为了解析像这样的小语法,我建议你手动简化它们,以便你可以应用非回溯recursive descent parser。你给出的语法是:

valid ::= "1*" | "1" | "(" valid "|" valid ")"

所以它已经非左递归并准备好了,你只需要1*而不是1。我建议您的解析器函数具有类型string -> (bool, string),其中bool指示解析是否成功,第二个组件是未解析的字符串的其余部分。您也可以返回已解析字符串的内部表示(AST),而不是bool

例如,这是valid制作的解析器:

def valid(s):
    if s.startswith('1*'):
        return True, s[2:]
    if s.startswith('1'):
        return True, s[1:]
    if s.startswith('('):
        success, rest = valid(s[1:])
        if not success or not rest.startswith('|'): return False, s
        success, rest = valid(rest[1:])
        if not success or not rest.startswith(')'): return False, s
        return True, rest[1:]
    return False, s

def check(s):
    return valid(s) == (True, '')