将伪代码转换为可用(使用正则表达式?)

时间:2015-05-11 10:12:05

标签: php regex parsing pseudocode lexer

作为我写的系统的一部分,用户可以创建自己的自定义规则,以便在发生特定事件时运行。

他们可以使用一定数量的对象来创建这些规则,所有这些规则都有一定数量的属性和方法:

list of objects

作为规则的一个例子,我们可以说:

“如果此单位奖励为'Distinction',则将此单位的所有标准设置为'已实现'”

IF UNIT.award equals “Distinction”
THEN UNIT.criteria.set_award(‘A’)

“如果此单位奖励为'Merit',则设置该单位的任何标准的奖励,其名称以”P“或”M“开头为”已实现“

IF UNIT.award equals “Merit”
THEN UNIT.criteria.filter(‘starts’, ‘name’, ‘P’, ‘M’).set_award(‘A’)

“否则,如果此单位奖励是'通过,则将该单位的任何标准的奖励设置为'P'到'已实现'

IF UNIT.award equals “Merit”
THEN UNIT.criteria.filter(‘starts’, ‘name’, ‘P’).set_award(‘A’)

我遇到的问题是,我只是不确定如何使用该字符串的对象,属性和方法,例如, “UNIT.criteria.filter('starts','name','P')。set_award('A')”并将其转换为可用的东西。

我希望将字符串转换为最终结果:

example result

然后我可以将其转换为实际的正确对象并返回相关值或运行相关方法。

由于我只需要支持一定数量的东西(至少现在)并且我不需要像计算支持或变量那样复杂的东西,所以创建一个Lexer系统似乎有些过分,所以我在想只需使用正则表达式来拆分所有部分。

因此,使用上面的示例,我可以对“。”字符进行简单的拆分,但是如果在方法参数中使用该字符,例如“CRITERION.filter('是','name','P.1')”然后将它完全搞砸了。

我可以使用一个不太常见的字符来分割它们,例如双冒号或“::”但是如果出于某种原因有人将它放入参数中,它仍然会导致同样的问题。我已经尝试创建一个正则表达式,它分裂在角色上,只要它不在引号之间,但我无法让它工作。

所以基本上我的问题是:正则表达式是最好的方法吗? (如果是这样,任何人都可以帮助我让它忽略指定的字符,如果它在一个方法中)。或者还有另一种方法可以做到更容易/更好吗?

感谢。

1 个答案:

答案 0 :(得分:1)

我认为像eloquent这样的ORM语言可以为你做到这一点。

但是,如果我必须这样做,那么首先我将拆分IF THEN ELSE部分。 离去:

  1. UNIT.award等于“Distinction”
  2. UNIT.criteria.filter('starts','name','P','M')。set_award('A')
  3. 我猜“等于”也可能是“不等于”或“更大”所以...... 我把第一部分分开了。

    /(?'ident'[a-z.]*?) (?'expression'equals|greater) (?'compare'[0-9a-z\“\”]+)/gi
    

    但围绕'等于'的爆炸也会做同样的事情。

    然后我会围绕圆点爆炸第二部分。 给出:

    1. 单元
    2. 标准
    3. 过滤器(A,B,C,d)
    4. set_ward(e)中
    5. 弹出前2个以获取对象和属性,然后弹出可能的过滤器和操作列表。

      但坦率地说,我会开发一种不会将属性与动作和过滤器混合的语言。

      类似的东西:

      IF object.prop EQUALS const|var 
      THEN UPDATE object.prop 
      WITH const|var [WHERE object.prop filter const|var [AND|OR const|var]] 
      

      Eloquent直接在php中完成:

      DB::table('users')
                  ->where('id', 1)
                  ->update(['votes' => 1]);
      

      所以也许我会这样做:

      THEN object.prop->filter(a,b,c,d)->set('award','A')
      

      这样可以轻松地分割动作 - >和周围的物业。

      总之... 我在https://regex101.com/做我的正则表达式 希望这会有所帮助。