我似乎无法找到正确方向的指针,我甚至不确定我应该研究的条款是什么,但无数小时的谷歌搜索似乎在旋转我的圈子,所以希望堆栈智能的集体蜂巢溢出可以帮助.
问题是,我需要一种方法来过滤数据,我只能称之为复合逻辑树.目前,该系统实现了一个简单的AND过滤系统.例如,假设我们有一个人的数据集.你添加了一堆过滤器,显示所有人(性别=女性)和(年龄> 23)AND(年龄<30)和(状态=单身).很容易,遍历每个项目,只有在每个条件都为真时才添加到有效的项目集合.
我遇到的问题是如何处理用户能够构建涉及的复杂查询和/或?我正在考虑像每个节点所代表的树和表达式,将其子节点评估为真或假.一个简单的例子是 - 过滤到((性别= =男性和年龄= = 25)或(性别==女性和状态==单身))和智商> 120.对不起我想不出一个更好的例子在此时此刻.但是,您将如何表示此类型的表达式树,并针对这些过滤器评估集合中的项目.有哪些参考资料会有所帮助?天啊,谷歌搜索什么可能会导致一个积极的方向?!
感谢任何可以提供任何帮助的人.
以下是使用人员数据集的树形式的复合查询示例
所以在树形式即时思考
o-Root Node
- And - Sex = Male
- And - Eyes = Blue
- Or - Sex = Female
- And Eyes = Blue
- Or Status = Single
Run Code Online (Sandbox Code Playgroud)
我相信解决方案是在数据结构中表示每个节点
Node
{
OpType - AND or OR
ExpressionField - The field to evaluate
ExpressionOp - =, !=, >, >=, <, <=
ExpressionValue - the value to compare the field's value against …Run Code Online (Sandbox Code Playgroud) user-interface boolean-logic expression-trees expression-evaluation decision-tree
在今天的考试中,我被要求在Haskell中创建一个表达式评估树.通常答案很简单:
data Expr = Value Integer
| Add Expr Expr
| Sub Expr Expr
| Mul Expr Expr
Run Code Online (Sandbox Code Playgroud)
要评估它,您只需使用如下功能:
eval :: Expr -> Integer
eval (Value x) = x
eval (Add l r) = eval l + eval r
eval (Sub l r) = eval l - eval r
eval (Mul l r) = eval l * eval r
Run Code Online (Sandbox Code Playgroud)
但是今天我们得到了一种数据类型:
data Op = Add
| Sub
| Mul
Run Code Online (Sandbox Code Playgroud)
所以我假设创建了我可以做的表达式树:
data Expr = Value Integer
| Op Expr Expr
Run Code Online (Sandbox Code Playgroud)
并使用相同的eval …
嗨,欢迎来到Evaluate()之谜
使用方括号(例如,"[A1:C5]")与使用字符串参数调用Evaluate方法相同.
因此,我运行了一个非常简单的代码来查看Microsoft的Evaluate()方法文档的准确性.
毫不奇怪,我得到了一个奇怪但一致的结果.
注意: 执行Immediate Window CTRL+ 中的4个命令中的每一个G.查看每个呼叫的差异.注意内置错误,它显示每个MsgBox两次.请记住这一点,不要混淆......
将此代码粘贴在一个模块中
Private Sub SleepESub()
Application.Wait Now + TimeValue("0:00:20")
MsgBox "w8'd "
End Sub
Run Code Online (Sandbox Code Playgroud)
然后在立即窗口中执行这4个命令(每次1个)
? Evaluate ("SleepESub()")
? [SleepESub()]
? [SleepESub]
? SleepESub
前2个立即执行代码; 对我来说意味着他们已经评估了代码.第三个(根据文档)应该是,Evaluating但它的行为方式与模块正文中的行为不同.然后立即窗口给出了Error 2023一个模块体内相同的调用执行它,就好像你正在调用一个sub.It等等,20 seconds如果它是一个正常Call SleepESub()的4号调用.
任何人都能解释我在这里缺少的东西吗?第3行不是正确的Evaluation电话吗?或者它是否评估对sub本身的调用(如果这是有道理的)
更新:
我认为有些人误解了我在这里评估的内容 - 不要担心这是一个高级主题,我不是一个书作家,你不是读者.(原谅我......)
为了更好地了解你可以比较即时窗口与模块体的结果.试试这段代码:
' Run each of …Run Code Online (Sandbox Code Playgroud) 看一下类似这个问题的示例代码:
public class A {
public static void main(String args[]){
A a = new A();
System.out.println(a.equals((a = null)));
}
}
Run Code Online (Sandbox Code Playgroud)
这打印错误.为什么它不会因NullPointerException而失败?在equals方法可以运行之前必须处理赋值,但是在评估整行之前,不会以某种方式影响equals的引用?
我没有看到它描述的Java语言规范在哪里,我在某个地方想念它吗?
我想知道如何评估方程的字符串表示,就好像它是一个真实的方程:
if(@"15+14==23")
{
//True statement...
}
else
{
//False statement....
}
Run Code Online (Sandbox Code Playgroud)
我想返回"假",因为15 + 14不等于23.我怎么能让它工作?
cocoa cocoa-touch objective-c expression-evaluation nsstring
我已经为我计划在以后的项目中使用的预处理器语言编写了tokenizer和expression评估器.我开始想我也许应该用EBNF(Extended Backus-Naur Form)来描述语言,以保持语法更易于维护,甚至用它来生成解析器的更高版本.
我的第一印象是EBNF用于标记化过程和语法验证.后来我发现它也可以用来描述运营商的优先级,就像在这篇文章或维基百科文章中一样:
expression ::= equality-expression
equality-expression ::= additive-expression ( ( '==' | '!=' ) additive-expression ) *
additive-expression ::= multiplicative-expression ( ( '+' | '-' ) multiplicative-expression ) *
multiplicative-expression ::= primary ( ( '*' | '/' ) primary ) *
primary ::= '(' expression ')' | NUMBER | VARIABLE | '-' primary
Run Code Online (Sandbox Code Playgroud)
我可以看到如何允许生成器生成内置运算符优先级的代码,但这究竟应该如何表达优先级?运算符优先级更多是关于语义还是关于语法的EBNF?如果我决定在EBNF中编写我的语言描述,我应该在考虑运算符优先级的情况下编写它还是在单独的部分中记录它?
programming-languages language-design ebnf expression-evaluation operator-precedence
当我使用我最喜欢的容器时,我倾向于连锁操作.例如,在众所周知的Erase-remove成语中:
v.erase( std::remove_if(v.begin(), v.end(), is_odd), v.end() );
Run Code Online (Sandbox Code Playgroud)
根据我所知的评估顺序,v.end()(在rhs上)可能会在调用之前进行评估std::remove_if.这不是问题,因为std::remove*只是在不改变其结束迭代器的情况下对矢量进行洗牌.
但它可能导致非常令人惊讶的结构,例如(演示):
#include <iostream>
struct Data
{
int v;
int value() const { return v; }
};
auto inc(Data& data) { return ++data.v; }
void print_rhs(int, int value) { std::cout << value << '\n'; }
int main()
{
Data data{0};
print_rhs(inc(data), data.value()); // might print 0
}
Run Code Online (Sandbox Code Playgroud)
这是令人惊讶的,因为print_rhs被叫之后 inc被称为; 这意味着data.v是1当print_rhs …
为了学习和演示,我需要一个宏来打印其参数并对其进行评估.我怀疑这是一个非常常见的情况,甚至可能是常见问题,但我找不到实际的参考.
我目前的代码是:
#define PRINT(expr) (fprintf(stdout, "%s -> %d\n", __STRING(expr), (expr)))
Run Code Online (Sandbox Code Playgroud)
然后:
PRINT(x & 0x01);
Run Code Online (Sandbox Code Playgroud)
它工作正常,但我不确定__STRING宏的合法状态,特别是因为它在private __命名空间中.
所以,我的问题:
是否需要C实现来忽略无效表达式评估期间发生的未定义行为,就好像评估本身从未发生过一样?
考虑C11,6.3.2.2§1:
如果将任何其他类型的表达式评估为void表达式,则将其值或指示符丢弃。(将评估void表达式的副作用。)
这与用于防止编译器警告未使用的变量的常用用法有关:
void f() {
int a;
(void)a;
}
Run Code Online (Sandbox Code Playgroud)
但是,如果我们有未定义的行为,例如:
void f() {
int a;
(void)(1/0);
}
Run Code Online (Sandbox Code Playgroud)
我可以安全地声明该程序不包含未定义的行为吗?该标准说“它的值或指示符被丢弃”,但是“表达式(...)被评估(...)”,因此评估似乎确实发生了。
GCC / Clang确实报告了未定义的行为,因为在这种情况下很明显,但是在一个更微妙的示例中,它们没有:
int main() {
int a = 1;
int b = 0;
(void)(a/b);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
即使这样-O0,GCC和Clang都无法评估1/0。但这即使没有强制转换也会发生,因此它不具有代表性。
将论点推到极致,(void)a在我的第一个示例(a未初始化的地方)中的简单评估是否会系统地触发未定义的行为?
ISO C11 6.3.2.1§2确实提到:
如果左值指定了可以使用寄存器存储类声明的自动存储持续时间的对象(从未使用其地址),并且该对象未初始化(未使用初始化器声明,并且在使用前未对其进行任何赋值) ),则行为未定义。
但是,在附件J.2未定义行为中,措词略有不同:
在以下情况下,行为是不确定的:
(...)
在需要指定对象值的上下文中使用了一个左值,该值指定了可以用寄存器存储类声明的自动存储持续时间的对象,但是该对象未初始化。(6.3.2.1)。
本附件确实导致了这样的解释,即void在评估过程中包含未定义行为的表达式实际上并未得到评估,但是由于它只是附件,因此我不确定其论据的重要性。
如何在 .NET Core 中卸载程序集?
注意:
.NET Core 不支持 AppDomain。
背景:
我必须动态评估用户生成的 VisualBasic 表达式。
为此,我使用 Roslyn 动态编译表达式。
我从 Roslyn 编译器生成的字节数组加载生成的程序集。
然后我创建一个实现抽象类的实例(因此我不必使用反射)。然后我调用抽象类的方法EvaluateExpression。
完成此操作后,我想卸载已加载的程序集(否则,我将享受内存泄漏的乐趣)。
因此,我在计算表达式后立即卸载程序集:
Parameters.AbstractEvaluator x = RoslynExpressionEvaluator.CreateEvaluator(expression, report.Code);
object value = x.EvaluateExpression();
x.LoadContext.Unload();
Run Code Online (Sandbox Code Playgroud)
(loadContext在生成时保存在抽象类中)
到目前为止一切正常,但是在x.LoadContext.Unload();,我得到
System.InvalidOperationException:“无法卸载不可收集的 AssemblyLoadContext。”
有可能解决这个问题吗?
如何使组件成为收藏品?
另外,我注意到我可以加载具有相同类名的程序集(如您所见,代码中没有命名空间)
这在多线程环境(又名网络)中表现如何?
我可以无限地加载动态生成的类的不同版本,直到机器用完 RAM 而没有出现故障吗?
或者为什么当加载同一个类两次时这会起作用?
using Microsoft.CodeAnalysis.Operations;
namespace ReportTester
{
public static class RoslynExpressionEvaluator
{
// a utility method that creates Roslyn compilation
// for the passed code.
// The compilation references the collection of
// passed "references" arguments …Run Code Online (Sandbox Code Playgroud) c# code-generation expression-evaluation assembly-loading roslyn