您好,登录后才能下订单哦!
小编给大家分享一下C# Parsing Library是什么意思,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!
C# Parsing Library 是一个LL解析器产生框架,可以在C#中模拟ENBF文法定义。设计思路来自于Boost.Spirit,一个C++解析器框架。
一)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方法:
bool Parse(Scanner scanner);
Scanner类主要存储一个字符串输入,及一个光标位置,光标随着解析的进行向前移动。
例子:一个整数解析器, 定义为一个可选的符号后面跟若干数字:
Parser signed = (Parser.Lit('+') | '-').Opt;  Parser p = (signed + Parser.DigitChar.Plus).Lexeme;  bool success = p.Parse(new Scanner("-123"));其中,Lit表示常量,Lexeme表示为词法分析,即不忽略空格。
二)C# Parsing Library:ParserRef
一个常用的四则运算表达式文法:
group      ::= '(' expression ')' factor     ::= integer | group  term       ::= factor (('*' factor) | ('/' factor))*  expression ::= term (('+' term) | ('-' term))*用下面的方法是错误的:
Parser group; // Parser 是抽象类,无法 new Parser factor; factor = Parser.Int | group; // 错误! group没有初始化!
但是使用ParserRef 就可以了:
ParserRef group = new ParserRef(); ParserRef factor = new ParserRef(); factor.Parser = Parser.Int | group;
完整的定义如下:
ParserRef group = new ParserRef();  ParserRef factor = new ParserRef();  ParserRef term = new ParserRef();  ParserRef expression = new ParserRef();    group.Parser = '(' + expression + ')';   factor.Parser = Parser.Int                | group;   term.Parser     = factor +                     ( ('*' + factor)                    | ('/' + factor)                    ).Star;   expression.Parser = term +                       ( ('+' + term)                      | ('-' + term)                      ).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)。对于以下的简单规则:
LeftRule := RightRule [ Action(lhs, rhs) ]
其语义为:LeftRule.Attribute = Action(LeftRule.Attribute, RightRule.Attribute).
上面的四则运算示例可修改如下:
Grammar< int> grammar  = new Grammar< int>();  Rule< int> group = new Rule< int>(grammar);  Rule< int> factor = new Rule< int>(grammar);  Rule< int> term = new Rule< int>(grammar);  Rule< int> expression  = new Rule< int>(grammar);  Rule< int> start = new Rule< int>(grammar);  grammar.Start = start;   group.Parser = '(' + expression [ (lhs, rhs) => rhs ] + ')';   factor.Parser = Parser.IntValue [ v => grammar.Ret(v) ]  // (#1)                | group [ (lhs, rhs) => rhs ];   term.Parser = factor [ (lhs, rhs) => rhs ] +                 ( ('*' + factor [ (lhs, rhs) => lhs * rhs ])                | ('/' + factor [ (lhs, rhs) => lhs / rhs ])                ).Star;   expression.Parser = term [ (lhs, rhs) => rhs ] +                       ( ('+' + term [ (lhs, rhs) => lhs + rhs ])                      | ('-' + term [ (lhs, rhs) => lhs - rhs ])                      ).Star;    start.Parser = expression [ (lhs, rhs) => rhs ] + Parser.End;    int result;  bool success = grammar.Parse("10 + 20 + 30 * (40 + 50)", out result);  if (success) Console.WriteLine(result);说明:
对于一般的Parser,语义动作中并不能有返回值,因为它不知道属性的确切类型,要支持属性,必须使用 Grammar.Ret().
在我自己实现以前,大致搜了一下,在CodeProject上有一个类似的实现,也是模仿Boost.Spirit,不过它的语义处理采用C#的事件机制,用起来极不方便。
以上是“C# Parsing Library是什么意思”这篇文章的所有内容,感谢各位的阅读!相信大家都有了一定的了解,希望分享的内容对大家有所帮助,如果还想学习更多知识,欢迎关注亿速云行业资讯频道!
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。