lpeg解析一阶逻辑术语

如标题所说,我正在尝试解析以下示例:

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(A,b,c(d,“e”,7))),它仅返回{term,{} }(而对于term(A,b,c)则没问题)。
  • 为了去除字符串中的引号,我使用了{~ ~},但因此我不得不将所有捕获移动到下面的行的argumentterm之外。有什么方法可以避免这种情况吗?
  • 我想为每个元素关联一个键来指定其类型,例如,代替A,类似{value="A",type="variable"}。我找到了一种使用{:name::}做到这一点的方法,但是表中的元素顺序丢失了(因为它不会创建新表,而是仅添加一个键,在这种情况下为variable =“A”,这些元素的顺序不固定)。如何标记项目以保持顺序?
点赞
用户1847592
用户1847592

抱歉,我没有使用 LPeg 的经验,但通常 Lua 模式足以轻松解决您的任务:

local str = 'term(A, b, c(d, "e", 7))'

local function convert(expr)
    return (expr:gsub('(%w+)(%b())',
        function (name, par_expr)
            return '{'..name..', {'..convert(par_expr:sub(2, -2))..'}}'
        end
    ))
end

print(convert(str))  -- {term, {A, b, {c, {d, "e", 7}}}}

现在只需使用 load() 加载转换后的字符串以创建表格。

2013-07-26 16:07:14