lua – lpeg解析一阶逻辑项
正如标题所说,我试图解析例如
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),它可以正常). 解决方法
在你的语法中你有:
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" } (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |