简体   繁体   English

使用递归评估字符串

[英]Evaluating a string using recursion

I'm trying to create a function that returns True is the string passed in is '1' (valid) or '1*' (valid) or in the form of '(' + valid + '|' + valid + ')' (valid). 我正在尝试创建一个返回True的函数,传入的字符串是'1' (有效)或'1*' (有效)或以'(' + valid + '|' + valid + ')' (有效)。 What I mean by the last part is for example: 我的意思是最后一部分是例如:

(1|1) <- since its in the form of '(' + valid + '|' + valid + ')' and '1' is valid. (1|1) < - 因为它的形式为'(' + valid + '|' + valid + ')''1'是有效的。 ((1|1)|1) <- since its in the form of '(' + valid + '|' + valid + ')' and (1|1) is valid and so is '1' ((1|1)|1) < - 因为它的形式为'(' + valid + '|' + valid + ')'(1|1)有效,所以'1'

((1|(1|1))|1) <- since its in the form of '(' + valid + '|' + valid + ')' and (1|(1|1)) is valid and so is '1' ((1|(1|1))|1) < - 因为它的形式为'(' + valid + '|' + valid + ')'(1|(1|1))有效,所以是'1'

My plan: 我的计划:

  • 1.) if the string passed in is '1', return True (Base Case) 1.)如果传入的字符串为'1',则返回True(基本情况)
  • 2.) if the string passed in is '1'+'*', return True 2.)如果传入的字符串是'1'+'*',则返回True
  • 3.) Else, if the string passed in begins with a '(' and ends with ')' look at the contents inside of the bracket and find the '|' 3.)否则,如果传入的字符串以'('并以'结尾'开头,则查看括号内的内容并找到'|' symbol that's not inside of another bracket. 不在另一个括号内的符号。 Once it is found run the function again on the string on the left of the found symbol, and also run the function again on the string on the right of the found symbol. 一旦找到它,再次在找到的符号左侧的字符串上运行该函数,并再次在找到的符号右侧的字符串上运行该函数。 If both are True then the string is True (Recursive Step) 如果两者都为True则字符串为True(递归步骤)
  • 4.) Return False if anything else is passed in. 4.)如果传入任何其他内容,则返回False。

My code based on my plan: 我的代码基于我的计划:

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 

Some examples: 一些例子:

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

I spent 3 days on this and still couldn't figure out how to do the recursive step so I'm hoping someone can help me with this. 我在这上花了3天时间仍然无法弄清楚如何进行递归步骤,所以我希望有人可以帮助我。 I can't figure out how to find the '*' symbol that is not within another set of brackets. 我无法弄清楚如何找到不在另一组括号内的'*'符号。 I think if I'am able to find that '*' symbol than I can do the rest myself. 我想如果我能找到'*'符号,那么我自己就可以做到。

I'm sure that we can do this using the re module but let's just pretend we can't use that. 我确信我们可以使用re模块执行此操作,但我们只是假装我们不能使用它。

For parsing small grammars like this, I would suggest you to simplify them manually to a point where you can apply a non-backtracking recursive descent parser . 为了解析像这样的小语法,我建议你手动简化它们,以便你可以应用非回溯递归下降解析器 The grammar you gave is: 你给出的语法是:

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

so it is already non-left-recursive and ready to go, you just have to prefer 1* over 1 . 所以它已经非左递归并准备好了,你只需要1*超过1 I suggest your parser functions to have type string -> (bool, string) , where the bool indicates whether the parsing was successful and the second component is the unparsed rest of the string. 我建议您的解析器函数具有类型string -> (bool, string) ,其中bool指示解析是否成功,第二个组件是未解析的字符串的其余部分。 Instead of the bool , you can also return an internal representation (AST) of the parsed string. 您也可以返回已解析字符串的内部表示(AST),而不是bool

As an example, here is a parser for the valid production: 例如,这是一个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, '')

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

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