Lua-Pattern - 评估条件表达式
2018-10-11 11:59:52
收藏:0
阅读:101
评论:2
我想要评估一个条件表达式字符串,我定义了以下BNF格式:
X ::= <value>
COND ::= X | X '==' X | '!{' COND '}' | '{' COND '&&' COND '}' | '{' COND '||' COND '}'
基于这个结构,我编写了以下这个评估函数,返回了一个布尔值:
-- Bedingung auswerten
function eval(exp, valueTab, loopValue)
-- !{COND} - Negierung
if string.find(exp, '^!{(.+)}$') then
return not eval(string.gsub(exp, '^!{(.+)}$', '%1'))
-- {COND&&COND} - AND
elseif string.find(exp, '^{(.+)&&(.+)}$') then
return (eval(string.gsub(exp, '^{(.+)&&(.+)}$', '%1')) and eval(string.gsub(exp, '^{(.+)&&(.+)}$', '%2')))
-- {COND||COND} - OR
elseif string.find(exp, '^{(.+)||(.+)}$') then
return (eval(string.gsub(exp, '^{(.+)||(.+)}$', '%1')) or eval(string.gsub(exp, '^{(.+)||(.+)}$', '%2')))
-- X==X - Gleichheit -> true/false
elseif string.find(exp, '^(.+)==(.+)$') then
return (getValue(string.gsub(exp, '^(.+)==(.+)$', '%1'), valueTab, loopValue) == getValue(string.gsub(exp, '^(.+)==(.+)$', '%2'), valueTab, loopValue))
-- X -> false wenn X nil/false auswertet ansonsten true
else
return (getValue(exp, valueTab, loopValue) and true or false)
end
end
但是它不能处理一些嵌套的条件,比如
exp = '{{1||boolean:false}&&{boolean:true&&!{boolean:false}}}'
第一次递归步骤将表达式分为
eval('{1||boolean:false}&&{boolean:true') and
eval('!{boolean:false}}'
任何想法如何检查“{'”的数量是否等于“}'”的数量?它应该将表达式分解为
eval('{1||boolean:false}') 和
eval('{boolean:true&&!{boolean:false}}')
我希望您理解我的问题,如果您有任何进一步的问题,请告诉我。如果您有更好的建议,我也愿意更改我的语法。但是否定,AND和OR子句应得到支持。
点赞
用户1944004
语法非常简单,LPEG 允许您基本上直接复制语法,加入一些语义动作,然后它就可以工作了â„¢。
如果您想了解更多关于 LPEG 和解析表达式语法方面的知识,我推荐这个教程:http://leafo.net/guides/parsing-expression-grammars.html
local lpeg = require"lpeg"
local P, V = lpeg.P, lpeg.V
local True = function() return true end
local False = function() return false end
local Not = function(a) return not a end
local Eq = function(a,b) return a == b end
local And = function(a,b) return a and b end
local Or = function(a,b) return a or b end
local grammar = P{
"cond",
cond = (V"x")
+ (V"x" * "==" * V"x") / Eq
+ (P"!{" * V"cond" * P"}") / Not
+ (P"{" * V"cond" * P"&&" * V"cond" * P"}") / And
+ (P"{" * V"cond" * P"||" * V"cond" * P"}") / Or,
x = P"1" / True
+ P"0" / False
+ P"boolean:true" / True
+ P"boolean:false" / False
}
local eval = function(exp)
return grammar:match(exp)
end
print(eval('{{1||boolean:false}&&{boolean:true&&!{boolean:false}}}'))
2018-10-12 09:53:37
评论区的留言会收到邮件通知哦~
推荐文章
- Lua 虚拟机加密load(string.dump(function)) 后执行失败问题如何解决
- 我想创建一个 Nginx 规则,禁止访问
- 如何将两个不同的lua文件合成一个 东西有点长 大佬请耐心看完 我是小白研究几天了都没搞定
- 如何在roblox studio中1:1导入真实世界的地形?
- 求解,lua_resume的第二次调用继续执行协程问题。
- 【上海普陀区】内向猫网络招募【Skynet游戏框架Lua后端程序员】
- SF爱好求教:如何用lua实现游戏内调用数据库函数实现账号密码注册?
- Lua实现网站后台开发
- LUA错误显式返回,社区常见的规约是怎么样的
- lua5.3下载库失败
- 请问如何实现文本框内容和某个网页搜索框内容连接,并把网页输出来的结果反馈到另外一个文本框上
- lua lanes多线程使用
- 一个kv数据库
- openresty 有没有比较轻量的 docker 镜像
- 想问一下,有大佬用过luacurl吗
- 在Lua执行过程中使用Load函数出现问题
- 为什么 neovim 里没有显示一些特殊字符?
- Lua比较两个表的值(不考虑键的顺序)
- 有个lua简单的项目,外包,有意者加微信 liuheng600456详谈,最好在成都
- 如何在 Visual Studio 2022 中运行 Lua 代码?

解决方案
我按照以下方式完成了它:
编辑 BNF
COND ::= '{' (X|X '==' X|COND '&&' COND|COND '||' COND) '}'|'!' COND编辑模式
-- Bedingung auswerten function eval(exp, valueTab, loopValue) -- !{COND} - Negierung if string.find(exp, '^!(%b{})$') then return not eval(string.gsub(exp, '^!(%b{})$', '%1')) -- {COND&&COND} - AND elseif string.find(exp, '^{(!?%b{})&&(!?%b{})}$') then return (eval(string.gsub(exp, '^{(!?%b{})&&(!?%b{})}$', '%1')) and eval(string.gsub(exp, '^{(!?%b{})&&(!?%b{})}$', '%2'))) -- {COND||COND} - OR elseif string.find(exp, '^{(!?%b{})||(!?%b{})}$') then return (eval(string.gsub(exp, '^{(!?%b{})||(!?%b{})}$', '%1')) or eval(string.gsub(exp, '^{(!?%b{})||(!?%b{})}$', '%2'))) -- X==X - Gleichheit -> true/false elseif string.find(exp, '^{(.+)==(.+)}$') then return (getValue(string.gsub(exp, '^{(.+)==(.+)}$', '%1'), valueTab, loopValue) == getValue(string.gsub(exp, '^{(.+)==(.+)}$', '%2'), valueTab, loopValue)) -- X -> false wenn X nil/false auswertet ansonsten true elseif string.find(exp, '^{(.+)}$') then return (getValue(string.gsub(exp, '^{(.+)}$', '%1'), valueTab, loopValue) and true or false) else print('wrong syntax') return end end