本文介绍了C# Parsing Library,即一个模仿Boost.Spirit的LL解析器库,可以在C#中模拟ENBF文法定义。

C# Parsing Library 是一个LL解析器发生结构,能够在C#中仿照ENBF文法界说。规划思路来自于Boost.Spirit,一个C++解析器结构。

介绍C# Parsing Library(介绍卖婬罪最新量刑标准)  C# Library 第1张

一)C# Parsing Library:Parser 基本概念

a) 文法界说举例:P ::= a b C#用法:P = a + b 序列

b) 文法界说举例:P ::= a | b C#用法:P = a | b 挑选

c) 文法界说举例:P ::= a * C#用法:P = a.Star 0..n次匹配

d) 文法界说举例:P ::= a + C#用法:P = a.Plus 1..n次匹配

e) 文法界说举例:P ::= a ? C#用法:P = a.Opt 0..1次匹配

P为Parser类型,是解析器的笼统基类,它界说了一个笼统的Parse办法:

  1. boolParse(Scannerscanner);

Scanner类首要存储一个字符串输入,及一个光标方位,光标跟着解析的进行向前移动。

比如:一个整数解析器, 界说为一个可选的符号后边跟若干数字:

  1. Parsersigned=(Parser.Lit('+')|'-').Opt;
  2. Parserp=(signed+Parser.DigitChar.Plus).Lexeme;
  3. boolsuccess=p.Parse(newScanner("-123"));

其间,Lit表明常量,Lexeme表明为词法剖析,即不疏忽空格。

二)C# Parsing Library:ParserRef

一个常用的四则运算表达式文法:

  1. group::='('expression')'
  2. factor::=integer|group
  3. term::=factor(('*'factor)|('/'factor))*
  4. expression::=term(('+'term)|('-'term))*

用下面的办法是过错的:

  1. Parsergroup;//Parser是笼统类,无法new
  2. Parserfactor;
  3. factor=Parser.Int|group;//过错!group没有初始化!

可是运用ParserRef 就能够了:

  1. ParserRefgroup=newParserRef();
  2. ParserReffactor=newParserRef();
  3. factor.Parser=Parser.Int|group;

完好的界说如下:

  1. ParserRefgroup=newParserRef();
  2. ParserReffactor=newParserRef();
  3. ParserRefterm=newParserRef();
  4. ParserRefexpression=newParserRef();
  5. group.Parser='('+expression+')';
  6. factor.Parser=Parser.Int
  7. |group;
  8. term.Parser=factor+
  9. (('*'+factor)
  10. |('/'+factor)
  11. ).Star;
  12. expression.Parser=term+
  13. (('+'+term)
  14. |('-'+term)
  15. ).Star;

三)C# Parsing Library:Rule和语义支撑

和 spirit相同,经过对[]的重载,完成对语义的支撑。一般的parser的Action类型为Action< string>, 即 void Action(string s)。s为该parser匹配的内容。假如要支撑上下文, 就要运用Rule了. Rule带有一个模板参数T,表明特点类型。Action类型为Func< T,T,T> 即 T Action(T lhs, T rhs)。关于以下的简略规矩:

  1. LeftRule:=RightRule[Action(lhs,rhs)]

其语义为:LeftRule.Attribute = Action(LeftRule.Attribute, RightRule.Attribute).

上面的四则运算示例可修正如下:

  1. Grammar<int>grammar=newGrammar<int>();
  2. Rule<int>group=newRule<int>(grammar);
  3. Rule<int>factor=newRule<int>(grammar);
  4. Rule<int>term=newRule<int>(grammar);
  5. Rule<int>expression=newRule<int>(grammar);
  6. Rule<int>start=newRule<int>(grammar);
  7. grammar.Start=start;
  8. group.Parser='('+expression[(lhs,rhs)=>rhs]+')';
  9. factor.Parser=Parser.IntValue[v=>grammar.Ret(v)]//(#1)
  10. |group[(lhs,rhs)=>rhs];
  11. term.Parser=factor[(lhs,rhs)=>rhs]+
  12. (('*'+factor[(lhs,rhs)=>lhs*rhs])
  13. |('/'+factor[(lhs,rhs)=>lhs/rhs])
  14. ).Star;
  15. expression.Parser=term[(lhs,rhs)=>rhs]+
  16. (('+'+term[(lhs,rhs)=>lhs+rhs])
  17. |('-'+term[(lhs,rhs)=>lhs-rhs])
  18. ).Star;
  19. start.Parser=expression[(lhs,rhs)=>rhs]+Parser.End;
  20. intresult;
  21. boolsuccess=grammar.Parse("10+20+30*(40+50)",outresult);
  22. if(success)Console.WriteLine(result);

阐明:

关于一般的Parser,语义动作中并不能有返回值,由于它不知道特点的切当类型,要支撑特点,有必要运用 Grammar.Ret().

在我自己完成曾经,大致搜了一下,在CodeProject上有一个相似的完成,也是仿照Boost.Spirit,不过它的语义处理选用C#的事情机制,用起来极不便利。这个项目我刚刚把它发布在google code 上面,项目主页:http://code.google.com/p/csParsing/。当然它还远远不够老练。

【修改引荐】

  1. 简略易懂的C#.NET多线程使用
  2. C#注册表是怎么操作的
  3. C#扩展办法:对扩展进行分组办理
  4. Visual C# 3.0新特性的总结
  5. 网站安全性:C#防SQL注入代码的完成办法

转载请说明出处
知优网 » 介绍C# Parsing Library(介绍卖婬罪最新量刑标准)

发表评论

您需要后才能发表评论