Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/25.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
.net 翻译表达式树时,如何推断括号的用法?_.net_Translation_Expression Trees_Parentheses_Inorder - Fatal编程技术网

.net 翻译表达式树时,如何推断括号的用法?

.net 翻译表达式树时,如何推断括号的用法?,.net,translation,expression-trees,parentheses,inorder,.net,Translation,Expression Trees,Parentheses,Inorder,我正在将表达式树转换为类似中缀符号的格式;我不是在评估树或执行其操作。树包含逻辑和关系操作,我希望在转换过程中以智能的方式发出括号 说明,考虑下面的设计表达式: a < x & (a < y | a == c) & a != d 尝试类似这样的操作,假设node.NodeType的类型为NodeType,并且如果第一个参数位于第二个参数之前,则函数位于前面,并返回true protected override Expression Visit(BinaryExpre

我正在将表达式树转换为类似中缀符号的格式;我不是在评估树或执行其操作。树包含逻辑和关系操作,我希望在转换过程中以智能的方式发出括号

说明,考虑下面的设计表达式:

a < x & (a < y | a == c) & a != d

尝试类似这样的操作,假设
node.NodeType
的类型为
NodeType
,并且如果第一个参数位于第二个参数之前,则函数
位于前面,并返回true

protected override Expression Visit(BinaryExpression node, NodeType parentType)
{
    bool useParenthesis = Precedes(parentType, node.NodeType);

    if (useParenthesis)
        Console.Write("(");

    Visit(node.Left, node.NodeType);
    Console.WriteLine(node.NodeType.ToString());
    Visit(node.Right, node.NodeType);

    if (useParenthesis)
        Console.Write(")");

    return node;
}
我接受了,因为它为实现这个算法提供了良好的基础。这个答案的唯一问题是它要求
VisitBinary()
方法作为方法参数了解其父调用方,这是不可行的,因为这些方法是基方法的重载

我提供了以下解决方案,该解决方案使用了类似的算法,但在表达式树的子节点的父调用中应用了检查以发出括号

class MyVisitor : ExpressionVisitor
{
    private readonly IComparer<ExpressionType> m_comparer = new OperatorPrecedenceComparer();

    protected override Expression VisitBinary(BinaryExpression node)
    {
        Visit(node, node.Left);
        Console.Write(node.NodeType.ToString());
        Visit(node, node.Right);

        return node;
    }

    private void Visit(Expression parent, Expression child)
    {
        if (m_comparer.Compare(child.NodeType, parent.NodeType) < 0)
        {
            Console.Write("(");
            base.Visit(child);
            Console.Write(")");
        }
        else
        {
            base.Visit(child);
        }
    }

    // VisitConstant, VisitMember, and VisitParameter omitted for brevity.
}
类MyVisitor:ExpressionVisitor
{
私有只读IComparer mu comparer=新运算符ReceidenceComparer();
受保护的重写表达式访问二进制(BinaryExpression节点)
{
访问(node,node.Left);
Write(node.NodeType.ToString());
访问(node,node.Right);
返回节点;
}
私有无效访问(表达式父级、表达式子级)
{
if(m_comparer.Compare(child.NodeType,parent.NodeType)<0)
{
控制台。写(“”);
参观基地(儿童);
控制台。写(“)”;
}
其他的
{
参观基地(儿童);
}
}
//为简洁起见,省略了VisitConstant、VisitMember和VisitParameter。
}
优先比较函数作为
i比较程序
实现,它应用了C#规则

类运算符或接收比较程序:比较程序
{
公共覆盖整型比较(表达式类型x、表达式类型y)
{
返回优先级(x)。比较(优先级(y));
}
私有int优先级(ExpressionType ExpressionType)
{
开关(expressionType){/*组表达式并返回优先顺序*}
}
}

+1和fav'd之前一直在为此苦苦挣扎。我相信有一些方法是通过传递当前操作符的优先级来实现的,但我们会看到的。我发现了下面的帖子,它提出了一种类似于下面辩证法的方法。您可以共享您的优先函数吗?您只需要根据函数中的优先规则枚举运算符,然后使包含的类实现
i可比较
。我手头没有代码,但是如果你仔细想想,它是很简单的。
class MyVisitor : ExpressionVisitor
{
    protected override Expression VisitBinary(BinaryExpression node)
    {
        Console.Write("(");

        Visit(node.Left);
        Console.WriteLine(node.NodeType.ToString());
        Visit(node.Right);

        Console.Write(")");

        return node;
    }

    // VisitConstant, VisitMember, and VisitParameter omitted for brevity.
}
protected override Expression Visit(BinaryExpression node, NodeType parentType)
{
    bool useParenthesis = Precedes(parentType, node.NodeType);

    if (useParenthesis)
        Console.Write("(");

    Visit(node.Left, node.NodeType);
    Console.WriteLine(node.NodeType.ToString());
    Visit(node.Right, node.NodeType);

    if (useParenthesis)
        Console.Write(")");

    return node;
}
class MyVisitor : ExpressionVisitor
{
    private readonly IComparer<ExpressionType> m_comparer = new OperatorPrecedenceComparer();

    protected override Expression VisitBinary(BinaryExpression node)
    {
        Visit(node, node.Left);
        Console.Write(node.NodeType.ToString());
        Visit(node, node.Right);

        return node;
    }

    private void Visit(Expression parent, Expression child)
    {
        if (m_comparer.Compare(child.NodeType, parent.NodeType) < 0)
        {
            Console.Write("(");
            base.Visit(child);
            Console.Write(")");
        }
        else
        {
            base.Visit(child);
        }
    }

    // VisitConstant, VisitMember, and VisitParameter omitted for brevity.
}
class OperatorPrecedenceComparer : Comparer<ExpressionType>
{
    public override int Compare(ExpressionType x, ExpressionType y)
    {
        return Precedence(x).CompareTo(Precedence(y));
    }

    private int Precedence(ExpressionType expressionType)
    {
        switch(expressionType) { /* group expressions and return precedence ordinal * }
    }
}