加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

lua – lpeg解析一阶逻辑项

发布时间:2020-12-14 21:48:25 所属栏目:大数据 来源:网络整理
导读:正如标题所说,我试图解析例如 term(A,b,c(d,"e",7)) 在Lua表中 {term,{A,{c,{d,7}}}} 这是我建立的语法: local pattern = re.compile[=[ term - variable / function argument - variable / lowercase /number / string function - {|lowercase {|(open arg
正如标题所说,我试图解析例如

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

在Lua表中

{term,{A,{c,{d,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,c),它可以正常).
>要从我使用的字符串中删除引号{~~},但由于这一点,我必须从下面的行中的参数和术语中移动所有捕获.有办法避免这种情况吗?
>我希望有一个与每个元素关联的键来指定其类型,例如,而不是像{value =“A”,type =“variable”}这样的东西.我找到了一种使用{:name ::}的方法,但是,表中元素的顺序丢失了(因为它不会创建新表但只是添加一个键,在这种情况下变量=“A”并且这些元素的顺序不固定).如何标记维护订单的商品?

解决方法

在你的语法中你有:

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

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

这里它无法匹配嵌套函数调用,因为它看到c可以匹配

`argument  <- variable`

由于您的变量非终端在函数之前列出,因此lpeg不考虑后者,因此它会停止解析之后出现的标记.

作为一个实验,我稍微修改了你的语法,并为你感兴趣的大多数非终端添加了一些表格和命名的捕获.

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,c(d(42),f,7))]]
dump( pattern:match(test) )

这在我的机器上提供以下输出:

{
  {
    {
      type = "var",name = "A"
    },{
      type = "var",name = "b"
    },{
      {
        "42",type = "func",name = "d"
      },{
        type = "var",name = "f"
      },"7",name = "c"
    },name = "fun"
  },type = "term"
}

仔细观察上面的内容,你会发现函数参数按照它们传入的顺序出现在表的索引部分.OTOH的类型和名称可以按任何顺序出现,因为它位于表的关联部分.您可以将这些“属性”包装在另一个表中,并将该内部属性表放在外部表的索引部分中.

编辑:这是一个修改后的语法,使解析更加统一.我删除了术语捕获,以帮助修剪一些不必要的分支.

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"
      },name = "d"
    },{
      type = "string",value = "e"
    },name = "f"
    },{
      type = "number",value = "7"
    },name = "c"
  },name = "fun"
}

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读