Lua-Pattern - 评估条件表达式

标签 lua lua-patterns

我想计算一个条件表达式字符串,我定义了以下 BNF:

X     ::= <value>    
COND  ::= X | X '==' X | '!{' COND '}' | '{' COND '&&' COND '}' | '{' COND '||' COND '}'

基于这个结构,我编写了这个评估函数,返回一个 bool 值:

-- 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}}}'))

关于Lua-Pattern - 评估条件表达式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52759555/

相关文章:

c++ - 如何从 Lua 调用 C++ DLL 中的函数?

c++ - 如何在 SWIG 中包装可变模板类的可变模板成员函数?

https - 具有相同 header 的 firefox 和 luasocket 之间的差异

string - 当我们在 Lua 中没有 `|` 运算符时如何验证这个字符串?

string - 如何从 Lua 中以特定字符串开头的字符串中删除行?

regex - Lua 模式匹配与正则表达式

regex - 我不明白的正则表达式

lua - 如何在Lua中将对象作为回调参数传递

timer - 在 Corona SDK 中循环调用计时器

lua - 在lua中分配变量并在其之间添加标点符号