使用 Pyparsing 解析函数

我正在尝试使用 Pyparsing 解析一些 LUA 函数。它几乎可以解析所有我需要解析的内容,但是有一种情况就是最后一个参数只是一个单词。以下是我的代码。这是我第一次使用 Pyparsing 的解析器,但我已经尽力逻辑清晰地构建了它:

所以下面是代码中的解释:

trigger_async(<object>, <name>, <param>)

trigger_async(<parameters>)

<param> = <name> = <type>

def parse_events_from_text(text):
    variable = Word(alphanums + "-_.:()")

    # 触发事件的实体
    obj = variable.setResultsName("object")

    # 事件名称
    name = (quotedString + Optional(Suppress("..") + variable)).setResultsName("name")

    # 事件参数列表
    paramName = variable.setResultsName("name")
    paramType = variable.setResultsName("type")
    param = Group(paramName + Suppress("=") + paramType).setResultsName("parameter")
    paramList = Group(Optional(Suppress("{") + ZeroOrMore(delimitedList(param)) + Suppress("}"))).setResultsName("parameters")

    function_parameter = obj | name | paramList

    # 开始函数
    trigger = "trigger"
    async = Optional("_async")

    # 函数调用
    functionOpening = Combine(trigger + async + "(").setResultsName("functionOpening")
    functionCall = ZeroOrMore(Group(functionOpening + delimitedList(function_parameter) + Suppress(")")))

    resultsList = functionCall.searchString(text)

    results = []

    for resultsL in resultsList:
        if len(resultsL) != 0:
            if resultsL not in results:
                results.append(resultsL)

    return results

所以该解析器是为这些类型的事件编写的:

trigger(self._entity, 'game:construction:changed', { entity = target })`
trigger_async(entity, 'game:heal:healer_damaged', { healer = entity })`
trigger_async(entity, 'game:heal:healer_damaged', { healer = entity, entity = target, test = party})`
trigger_async(entity, 'game:heal:healer')`
trigger(entity.function(), 'game:heal:healer', {})`

但问题在于如果没有花括号:

trigger(entity, 'game:heal:healer', entity.test)

它不会工作,因为我定义的变量

variable = Word(alphanums + "-_.:()")

只允许花括号,所以解析器会对最后一个花括号感到困惑。如果我写:

trigger(entity,'game:heal:healer',entity.test))

它可以工作。我想重新编写解析器,但我不知道如何做。我必须告诉它仅在 variable 只有一个开括号和一个闭括号时才有效,如下所示:

trigger(entity,'game:heal:healer',entity.test(input))

否则,不要吃掉那个闭合括号。

trigger(entity,'game:heal:healer',entity.test) <-- 变量,不要吃掉它!
点赞