我试图创建一个返回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'
我的计划:
我的代码基于我的计划:
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模块执行此操作,但我们只是假装我们无法使用它。
答案 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, '')