lua - Lua-Pattern - 评估条件表达式
问题描述
我想评估一个条件表达式字符串,我定义了以下 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}') and
eval('{boolean:true&&!{boolean:false}}')
我希望你能理解我的问题,如果你有任何进一步的问题,请告诉我。如果你有更好的主意,我也愿意改变我的语法。但是应该支持否定、AND- 和 OR-从句。
解决方案
语法非常简单,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}}}'))
推荐阅读
- javascript - 自定义静态路由不起作用
- android - 我想用 EditText 设计一个 OTP 屏幕
- jekyll - Jekyll `site.posts` 在将自定义域与 Github 页面合并后显示为空
- python - Django Queryset 查找日期之间的数据
- android - 如何从活动类操作的活动中运行位置请求权限扩展了 ActivityGroup
- java - java 8中的单元测试黄瓜步骤
- html - html - 使用查询字符串进行缓存破坏会导致始终下载资源
- javascript - 在 Chrome 中打开指向文件的链接
- android-things - 如何在 Android Things 上显示 NavigationBar?
- c - 错误检查 y 或没有答案 (C)