在C#中,是否保证表达式从左到右进行求值?
例如:
myClass = GetClass();
if (myClass == null || myClass.Property > 0)
continue;
Run Code Online (Sandbox Code Playgroud)
有没有不符合的语言?
c# language-agnostic compiler-construction expression expression-evaluation
假设我有一些看起来像的表达式a /\ b \/ c.我想为此生成真值表,例如:
a | b | c | a /\ b \/ c
---+----+----+-------------+-
F | F | F | F
F | F | T | T
F | T | F | F
F | T | T | T
T | F | F | F
T | F | T | T
T | T | F | T
T | T | T | T
Run Code Online (Sandbox Code Playgroud)
这里的一个关键思想是处理尚未处理的运算符is/2,例如逻辑含义->.顺便说一句,这个问题来自reddit用户 …
我需要使用 PHP 在服务器上处理一些用户提供的代码。该代码将涵盖一些非常基本的编程功能,例如:变量、文字、(最好)函数和一些相关操作。
一种选择是使用 的危险函数eval()。对于我的具体情况,除了安全问题和性能瓶颈之外,它的功能极其丰富且冗余。使用消毒令牌可以token_get_all()防止墨菲,而不是马基雅维利!不管它有什么缺点,它确实能够实现我一直渴望实现的目标。
我还检查了 Symphony 的ExpressionLanguage;它有一些缺点:
唉! 更复杂的ExpressionLanguage就足够了。
我正在寻找一种能够为用户提供一些非常基本的“编程”能力的东西。有这样的事吗,如果有的话,那是什么?(即使它是用另一种语言编写的,但可以在服务器上以某种方式使用。)如果这样的东西不存在,那么我应该如何对待eval()不吸引我?!或者,作为最后的手段,我如何设计这样一个简单的编程功能?(请详细说明事项:)
if和一个重复结构(例如:for循环)如何在 .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
C 标准有这种语言:
6.5.3.4 sizeof 和 _Alignof 运算符
语义学
- 该
sizeof运算符产生其操作数的大小(以字节为单位),该操作数可以是表达式或带括号的类型名称。大小由操作数的类型确定。结果是一个整数。如果操作数的类型是变长数组类型,则对操作数求值;否则,不计算操作数并且结果是整型常量。
我不清楚标准的含义:如果操作数的类型是可变长度数组类型,则对操作数进行求值
sizeof(char[foo()])大小表达式中必须在运行时求值来计算大小,但标准的语言似乎没有涵盖这种情况(什么是类型名称的类型吗?)C 标准的语言是否应该修改以澄清?
下面是一个测试程序,用于说明 VLA 的某些特定情况下的行为:
#include <stdio.h>
static int N = 0;
int foo(void) { return ++N; }
int main() {
typedef char S[foo()]; // foo() is called
printf("typedef char S[foo()];\t"); printf("N=%d\n", N);
printf("sizeof(S)=%d\t\t", (int)sizeof(S)); printf("N=%d\n", N);
typedef char U[foo()]; // foo() is called
printf("typedef char U[foo()];\t"); printf("N=%d\n", N);
printf("sizeof(U)=%d\t\t", (int)sizeof(U)); printf("N=%d\n", N);
S s1;
printf("S s1;\t\t\t"); …Run Code Online (Sandbox Code Playgroud) c c99 expression-evaluation language-lawyer variable-length-array
一位朋友让我简单地解释一下运算符优先级和求值顺序之间的区别。我是这样向他们解释的:-
让我们举个例子——
int x;
int a = 2;
int b = 5;
int c = 6;
int d = 4;
x = a * b / (c + d);
Run Code Online (Sandbox Code Playgroud)
在这里, 的最终值x将变为1。c这是因为,首先将和 的值d相加( ),然后将和6+4的值相乘(),最后进行除法(),最终值变为,然后将其赋值到。ab2*510/101x
所有这些都是由运算符优先级指定的。在此示例中,括号强制加法在乘法和除法之前进行,即使加法的优先级较低。另外,乘法是在除法之前执行的,因为乘法和除法具有相同的优先级,并且两者都具有从左到右的结合性。
现在到了重要的部分,即该表达式的求值顺序。
在一个系统上,求值的顺序可能是这样的 -
/* Step 1 */ x = a * b / (c + d);
/* Step 2 */ x = a * 5 / (c + d);
/* …Run Code Online (Sandbox Code Playgroud) 我是Irony和整个语言实现shebang的新手,所以我一直在玩Irony源附带的ExpressionEvaluator示例,这似乎(几乎)适合我正在进行的项目的需求.
但是,我希望它也支持布尔值,所以我将比较运算符添加到二元运算符列表中,如下所示:
BinOp.Rule = ToTerm("+") | "-" | "*" | "/" | "**"
| "==" | "<=" | ">=" | "<" | ">" | "!=" | "<>"; // added comparison operators
Run Code Online (Sandbox Code Playgroud)
这是我想要实现的一个例子:
x = 1
y = 2
eval = x < 2
eval2 = y < x
bool = true
bool2 = (eval == eval2)
Run Code Online (Sandbox Code Playgroud)
由于添加了二元运算符,它成功解析了上述内容.但是,在编译和运行代码时,它在最后两行失败.
bool = true行失败并显示以下消息:错误:变量true未定义.在(5:8).如何将true和false定义为常量?bool2 = (eval == eval2) …数学表达式通常用中缀表示法表示.出于评估目的,我们可以将其更改为postfix(反向抛光)表示法(使用Shunting-Yard等算法),然后使用堆栈评估后缀表示法.
我发现计算器使用这种技术,但今天的现代编译器是否使用它进行算术表达式评估?它是否足够有效或正在使用其他技术(或算法)?
compiler-construction infix-notation expression-evaluation shunting-yard
在一个...用于提供参数列表的简单函数中,该函数是否可以找到从调用环境传递的对象的名称?如果是这样,怎么样?
这出现在问题的背景下,并排打印矩阵和向量,但可能更为一般.
在该上下文中,参数...还可以包括不需要名称的字符串.这是我的MWE,我尝试过使用deparse(substitute()),但无济于事.
test_names <- function(...) {
# get arguments
args <- list(...)
chars <- sapply(args, is.character)
names <- sapply(args, function(x) if(is.character(x)) " " else deparse(substitute(x)))
names
}
Run Code Online (Sandbox Code Playgroud)
测试:
A = matrix(c(0.5, 1, 3, 0.75, 2.8, 4), nrow = 2)
x = c(0.5, 3.7, 2.3)
y = c(0.7, -1.2)
b = A %*% x - y
> test_names(A, " * ", x, " - ", y, " = …Run Code Online (Sandbox Code Playgroud) 我正在尝试学习如何在 C++ 中评估表达式。所以尝试并阅读不同的例子。下面是我无法理解它是否会产生未定义行为的代码。代码来自这里。所以我猜既然他们已经用过它了,这一定不是UB。但我有疑问。
#include <iostream>
int main()
{
int n = 1;
//std::cout << n << " " << ++n << std::endl;//this is undefined behavior i am sure
int m = (++n, std::cout << "n = " << n << '\n', ++n, 2*n);//will this also produce UB because here also we have cout in the same manner as above?
std::cout << "m = " << (++m, m) << '\n';
}
Run Code Online (Sandbox Code Playgroud)
正如您在上面的代码中看到的,我确信该声明:
cout << n << " " << …Run Code Online (Sandbox Code Playgroud)