What does C # Parsing Library mean?
Xiaobian to share with you what C#Parsing Library means, I believe most people still do not know how, so share this article for your reference, I hope you have a lot of harvest after reading this article, let's go to understand it together!
C#Parsing Library is an LL parser generation framework that emulates ENBF grammar definitions in C#. The design idea comes from Boost.Spirit, a C++ parser framework.
C#Parsing Library: Basic Parser Concepts
a) Grammar definition example: P ::= a b C#Usage: P = a + b sequence
b) Example of grammar definition: P ::= a| b C#Usage: P = a| B select
c) Example of grammar definition: P ::= a * C#Usage: P = a.Star 0.. n times matching
d) Example of grammar definition: P ::= a + C#Usage: P = a.Plus 1.. n times matching
e) Grammar definition example: P ::= a ? C#Usage: P = a.Opt 0.. 1 Match
P is a Parser type, an abstract base class for parsers, which defines an abstract Parse method:
bool Parse(Scanner scanner);
The Scanner class basically stores a string input and a cursor position, and the cursor moves forward as the parse proceeds.
Example: An integer resolver, defined as an optional symbol followed by several numbers:
Parser signed = (Parser.Lit('+') | '-').Opt; Parser p = (signed + Parser.DigitChar.Plus).Lexeme; bool success = p.Parse(new Scanner("-123"));
Where Lit represents constant and Lexeme represents lexical analysis, i.e. spaces are not ignored.
C# Parsing Library: ParserRef
A common grammar of four operational expressions:
group ::= '(' expression ')' factor ::= integer | group term ::= factor (('*' factor) | ('/' factor))* expression ::= term (('+' term) | ('-' term))*
It is wrong to use the following method:
Parser group; // Parser is abstract class, cannot new Parser factor; factor = Parser.Int| group; //error! group is not initialized!
However, ParserRef can be used:
ParserRef group = new ParserRef(); ParserRef factor = new ParserRef(); factor.Parser = Parser.Int | group;
The complete definition is as follows:
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 and Semantic Support
As with spirit, support for semantics is achieved by overloading []. The Action type of a parser is Action.
< string>void Action(string s). s is the content matched by the parser. If you want to support context, you have to use Rule. Rule takes a template parameter T, which indicates the attribute type. Action type is Func
< T,T,T>T Action(T lhs, T rhs). For the following simple rules:
LeftRule := RightRule [ Action(lhs, rhs) ]
Its semantics are: LeftRule.Attribute = Action(LeftRule.Attribute, RightRule.Attribute).
The above example of four operations can be modified as follows:
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);
Description:
For a normal Parser, the semantic action cannot have a return value because it does not know the exact type of the attribute. To support attributes, you must use Grammar.Ret().
Before I implemented it myself, I roughly searched it, and there is a similar implementation on CodeProject, which also imitates Boost.Spirit, but its semantic processing uses C#event mechanism, which is extremely inconvenient to use.
The above is all the content of this article "C#Parsing Library", thank you for reading! I believe that everyone has a certain understanding, hope to share the content to help everyone, if you still want to learn more knowledge, welcome to pay attention to the industry information channel!