Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/vb.net/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C#或VB中的动态逻辑表达式解析/计算?_C#_Vb.net_Expression - Fatal编程技术网

C#或VB中的动态逻辑表达式解析/计算?

C#或VB中的动态逻辑表达式解析/计算?,c#,vb.net,expression,C#,Vb.net,Expression,最好是对表达式求值,如下所示: (A和B)或(A和C)或(不是B和C) 或 (A&B)| | | | | | |(!B&C) 在运行时,我计划将上述表达式转换为以下表达式: (真与假)或(真与假)或(非真与假) 或 (真与假)| |(真与假)| |(!假与真) 条件: 1) 直到运行时,才知道逻辑表达式。 2) 直到运行时,数字变量及其值才为人所知。 3) 变量值从不为空 我知道我可以用一个类和一个方法创建一个简单的汇编,我在运行时根据输入生成该类和方法,但是有更好的方法吗。 我以前做过这件事

最好是对表达式求值,如下所示:
(A和B)或(A和C)或(不是B和C)

(A&B)| | | | | | |(!B&C)

在运行时,我计划将上述表达式转换为以下表达式:
(真与假)或(真与假)或(非真与假)

(真与假)| |(真与假)| |(!假与真)

条件: 1) 直到运行时,才知道逻辑表达式。 2) 直到运行时,数字变量及其值才为人所知。 3) 变量值从不为空

我知道我可以用一个类和一个方法创建一个简单的汇编,我在运行时根据输入生成该类和方法,但是有更好的方法吗。 我以前做过这件事。使用字符串生成器编写代码,然后调用编译器。然后,加载程序集并调用该方法

建议


谢谢。

您可以编写一个简单的解释器/解析器。使用类似的语法并重用现有语法。

如果使用.NET3.5,则可以解析文本并使用表达式类创建抽象sytax树。然后创建一个合适的LambdaExpression实例并将其编译成一个委托,然后执行该委托

为这种相当简单的语法构建解析器和语法树生成器是一个非常有趣的练习,它的执行速度比调用编译器要快(在我看来也更简洁)


如果您没有使用.NET3.5,那么自己实现解释的抽象语法树也不复杂。

请注意:您所说的两个最终条件不一定是等价的。C#中的&&运算符将使用短路求值,而VB中的逻辑
运算符则不使用短路求值。如果要确保语句等效,请将用户
翻译为
并将用户
翻译为
翻译为


对于简单的表达,你可能不会注意到有什么不同。但是,如果条件可能有副作用,或者两者之间的性能差异是一个问题,这可能很重要。

如果使用.NET 3.5,则可以创建Lambda表达式。然后您可以从它创建一个委托,并作为标准委托/方法调用。
互联网上有很多关于Lambda表达式的示例。

一种解决方案是将表达式组装成字符串,然后将其发送到SQL Server或任何数据库进行计算。将实际变量分别替换为1=1或0=1表示True和False,最终得到如下查询:

program: exprList ;

exprList: expr { Append($1); }
    | expr OR exprList { Append(OR); }
    | expr AND exprList { Append(AND); }
    | NOT exprList { Append(NOT); }
    | ( exprList ) { /* Do nothing */ }
    ;

expr: var { Append($1); }
    | TRUE { Append(True); }
    | FALSE { Append(False); }
    ;
选择1,其中(1=1和0=1)或(1=1和1=1)或(不是0=1和1=1)


然后,当运行查询时,当结果为真时,返回1。可能不是最优雅的解决方案,但它会起作用。很多人可能会建议不要这样做,但我还是要把它作为一个可能的解决方案扔出去。

您可以通过以下方式轻松做到这一点:

  • 一个解析器生成器(如上面提到的ANTLR),它接受布尔表达式作为输入,并生成中缀列表和
  • 用于计算反向波兰符号堆栈的代码
  • 语法如下所示:

    program: exprList ;
    
    exprList: expr { Append($1); }
        | expr OR exprList { Append(OR); }
        | expr AND exprList { Append(AND); }
        | NOT exprList { Append(NOT); }
        | ( exprList ) { /* Do nothing */ }
        ;
    
    expr: var { Append($1); }
        | TRUE { Append(True); }
        | FALSE { Append(False); }
        ;
    
    要进行评估,请执行以下操作:

    for each item in list
        if item is symbol or truth value, push onto RPN stack
        else if item is AND, push (pop() AND pop())
        else if item is OR, push (pop() OR pop())
        else if item is NOT, push (NOT pop())
    
    result = pop()
    
    对于符号,您必须在运行时替换真值。

    您可以使用


    它只是用来编写逻辑表达式的库(用前面的表计算,允许OR,NOT,AND运算符AND>,>=,),这不是最好的答案,但我自己不久前就遇到了这个问题

    这是我的旧代码: VB.Net-完全没有保修

    这段代码使用多个“(”、“)”、“和”、“或”加上“其他东西”的字符串,并通过用布尔值替换这些东西将逻辑分解为布尔值。 因此:

    无论我想评估什么“其他东西”,我都必须在函数resolveTerm()中输入 在评论中,“我们的元首和祖鲁克本,埃恩泽尔韦特!” 在第2页。 现在唯一的评估是“如果数字大于1”


    问候语

    看看我的库。它是一个.NET标准库,使用来计算布尔表达式

    它还可以为您的表达式生成一个真值表


    你也可以实现你自己的语法。

    你想实现什么?你能分享一下你是如何进行比较的吗?这看起来像是一个更好的方法。看起来像是一个要比较的东西的列表。你可以重复这个列表,当你发现任何两个都是真的时,就打断它。你可以写一个简单的propositional Logic parser…我记得必须做一个来解决Wumpus世界的问题。不管它们是否短路,表达式的结果都是一样的。唯一的区别是当A、B、C是函数时,短路会影响它们是否被调用,它不会影响表达式的最终结果。@Kibbee-但如果涉及副作用,可能会影响系统的最终结果。-1:不要鼓励人们编写这样的黑客,尤其是在发布代码中。这是一个有趣的想法。使用嵌入式版本的sql server,而不是依赖完整的安装,你可以更轻松地实现它。有时这样的黑客可以帮你省钱。+1A链接或示例可能有用。