首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >如何用C#编写解析器?

如何用C#编写解析器?
EN

Stack Overflow用户
提问于 2011-09-11 17:24:21
回答 5查看 82.1K关注 0票数 68

如何编写解析器(递归下降?)在C#?现在,我只需要一个简单的解析器来解析算术表达式(并读取变量?)。尽管稍后我打算编写一个xml和html解析器(用于学习目的)。我之所以这样做,是因为解析器在很多方面都很有用:网页开发、编程语言解释器、内部工具、游戏引擎、地图和图块编辑器等。那么,编写解析器的基本理论是什么?我如何在C#中实现解析器?C#是解析器的合适语言吗(我曾经用C++编写了一个简单的算术解析器,它非常高效。JIT编译会证明同样好吗?)。任何有用的资源和文章。最重要的是,代码示例(或代码示例的链接)。

注意:出于好奇,回答这个问题的人有没有用C#实现过解析器?

EN

回答 5

Stack Overflow用户

发布于 2012-11-05 20:34:27

Sprache是一个用.NET编写解析器的强大而轻量级的框架,还有一个Sprache NuGet package。为了让您对该框架有一个概念,这里是一个可以将简单的算术表达式解析为.NET表达式树的samples。我想说这真是太神奇了。

代码语言:javascript
复制
using System;
using System.Linq.Expressions;
using Sprache;

namespace LinqyCalculator
{
    static class ExpressionParser
    {
        public static Expression<Func<decimal>> ParseExpression(string text)
        {
            return Lambda.Parse(text);
        }

        static Parser<ExpressionType> Operator(string op, ExpressionType opType)
        {
            return Parse.String(op).Token().Return(opType);
        }

        static readonly Parser<ExpressionType> Add = Operator("+", ExpressionType.AddChecked);
        static readonly Parser<ExpressionType> Subtract = Operator("-", ExpressionType.SubtractChecked);
        static readonly Parser<ExpressionType> Multiply = Operator("*", ExpressionType.MultiplyChecked);
        static readonly Parser<ExpressionType> Divide = Operator("/", ExpressionType.Divide);

        static readonly Parser<Expression> Constant =
            (from d in Parse.Decimal.Token()
             select (Expression)Expression.Constant(decimal.Parse(d))).Named("number");

        static readonly Parser<Expression> Factor =
            ((from lparen in Parse.Char('(')
              from expr in Parse.Ref(() => Expr)
              from rparen in Parse.Char(')')
              select expr).Named("expression")
             .XOr(Constant)).Token();

        static readonly Parser<Expression> Term = Parse.ChainOperator(Multiply.Or(Divide), Factor, Expression.MakeBinary);

        static readonly Parser<Expression> Expr = Parse.ChainOperator(Add.Or(Subtract), Term, Expression.MakeBinary);

        static readonly Parser<Expression<Func<decimal>>> Lambda =
            Expr.End().Select(body => Expression.Lambda<Func<decimal>>(body));
    }
}
票数 20
EN

Stack Overflow用户

发布于 2011-09-12 02:55:58

C#几乎是一种不错的函数式语言,所以在其中实现类似Parsec的东西并不是什么大不了的事情。下面是如何做到这一点的一个例子:http://jparsec.codehaus.org/NParsec+Tutorial

也可以用非常类似的方式实现一个基于组合子的Packrat,但这一次将全局解析状态保留在某个地方,而不是执行纯函数操作。在我的(非常基本的和特别的)实现中,它相当快,但当然,像this这样的代码生成器必须执行得更好。

票数 4
EN

Stack Overflow用户

发布于 2011-10-16 17:39:17

我知道我来晚了一点,但我刚刚发布了一个名为Ve Parser的解析器/语法/AST生成器库。你可以在http://veparser.codeplex.com找到它,或者通过在包管理器控制台中输入'Install-Package veparser‘来添加到你的项目中。这个库是一种递归下降解析器,旨在易于使用和灵活。由于您可以获得它的源码,您可以从它的源码中学习。我希望它能帮上忙。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/7377344

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档