gpt4 book ai didi

lua - lpeg 解析一阶逻辑项

转载 作者:行者123 更新时间:2023-12-04 17:42:05 28 4
gpt4 key购买 nike

正如标题所说,我正在尝试解析例如

term(A, b, c(d, "e", 7))

在 Lua 表中
{term, {A, b, {c, {d, "e", 7}}}}

这是我构建的语法:
local pattern = re.compile[=[
term <- variable / function
argument <- variable / lowercase /number / string
function <- {|lowercase {|(open argument (separator (argument / function))* close)?|}|}
variable <- uppercase
lowercase <- {[a-z][A-Za-z0-9]*}
uppercase <- {[A-Z][A-Za-z0-9]*}
string <- '"' {~ [^"]* ~} '"'
number <- {[0-9]+}
close <- blank ")"
open <- "(" blank
separator <- blank "," blank
blank <- " "*
]=]

我有以下问题:
  • 它无法解析嵌套的术语。对于上面的例子,它只返回 {term, {} } (虽然可以使用 term(A, b, c) )。
  • 从我使用的字符串中去除引号 {~ ~} ,但正因为如此,我不得不从 argument 移动所有捕获和 term在下面的行中。有没有办法避免这种情况?
  • 我想有一个与每个元素相关联的键来指定它的类型,例如而不是 A类似 {value = "A", type = "variable"} .我找到了一种方法来做到这一点 {:name: :}但是,表中元素的顺序丢失了(因为它不会创建新表而只是添加一个键,在这种情况下 variable="A" 并且此元素的顺序不固定)。如何标记维护订单的项目?
  • 最佳答案

    在你的语法中,你有:

    argument  <- variable / lowercase /number / string
    function <- {|lowercase {|(open argument (separator (argument / function))* close)?|}|}

    请记住,lpeg 尝试按照您拥有的顺序匹配规则中的模式/谓词。一旦找到匹配项,lpeg 就不会考虑该语法规则中的其他可能匹配项,即使以后可能有“更好”的匹配项。

    这里它无法匹配嵌套的函数调用,因为它看到 c可以匹配
    `argument  <- variable`

    由于您的 variable非终端列在 function 之前, lpeg 不考虑后者,因此它停止解析后面的标记。

    作为一项实验,我稍微修改了您的语法,并为您感兴趣的大多数非终端添加了一些 table&named 捕获。
    local pattern = re.compile
    [=[
    term <- {| {:type: '' -> "term" :} term_t |}
    term_t <- func / var
    func <- {| {:type: '' -> "func":} {:name: func_id:} "(" arg(separator arg)* ")" |}
    func_id <- lower / upper
    arg <- number / string / term_t
    var <- {| {:type: '' -> "var" :} {:name: lower / upper:} |}
    string <- '"' {~ [^"]* ~} '"'
    lower <- {%l%w*}
    upper <- {%u%w*}
    number <- {%d+}
    separator <- blank "," blank
    blank <- " "*
    ]=]

    使用快速模式测试:
    local test = [[fun(A, b, c(d(42), "e", f, 7))]]
    dump( pattern:match(test) )

    这在我的机器上给出了以下输出:
    {
    {
    {
    type = "var",
    name = "A"
    },
    {
    type = "var",
    name = "b"
    },
    {
    {
    "42",
    type = "func",
    name = "d"
    },
    "e",
    {
    type = "var",
    name = "f"
    },
    "7",
    type = "func",
    name = "c"
    },
    type = "func",
    name = "fun"
    },
    type = "term"
    }

    仔细查看上面的内容,您会注意到函数参数按照它们传入的顺序出现在表的索引部分。OTOH typename可以按任何顺序出现,因为它位于表格的关联部分。您可以将这些“属性”包装在另一个表中,并将该内部属性表放在外部表的索引部分。

    编辑:这是一个修改后的语法,使解析更加统一。我已经删除了 term捕获以帮助修剪一些不必要的分支。
    local pattern2 = re.compile
    [=[
    term <- term_t
    term_t <- func / var
    func <- {| {:type: '' -> "func":} {:name: func_id:} "(" args? ")" |}
    func_id <- lower / upper
    arg <- number / string / term_t
    args <- arg (separator args)?
    var <- {| {:type: '' -> "var" :} {:name: lower / upper:} |}
    string <- {| {:type: '' -> "string" :}'"' {:value: [^"]* :} '"' |}
    lower <- {%l%w*}
    upper <- {%u%w*}
    number <- {| {:type: '' -> "number":} {:value: %d+:} |}
    separator <- blank "," blank
    blank <- " "*
    ]=]

    产生以下结果:
    {
    {
    type = "var",
    name = "A"
    },
    {
    type = "var",
    name = "b"
    },
    {
    {
    {
    type = "number",
    value = "42"
    },
    type = "func",
    name = "d"
    },
    {
    type = "string",
    value = "e"
    },
    {
    type = "var",
    name = "f"
    },
    {
    type = "number",
    value = "7"
    },
    type = "func",
    name = "c"
    },
    type = "func",
    name = "fun"
    }

    关于lua - lpeg 解析一阶逻辑项,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17885614/

    28 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com