How to use infragistics syntax parsing engine?

2019-08-11 07:08发布

I want to make use of infragistics syntax parsing engine to do something like this:

  1. User defines grammar for a language in an EBNF format.
  2. The grammar defined above is used to verify whether a user input in a textbox is valid (i.e. matches or could match the above grammar) or not.

I have read all the documentation they have and I cannot see what a good first step would be. Any help will be appreciated.

1条回答
啃猪蹄的小仙女
2楼-- · 2019-08-11 07:39

I work on the parsing engine for Infragistics and this sounds like a perfect way to use it. The type of parser created by the framework is based entirely on a Grammar instance, and this class can be created from an EBNF file. We have a custom format that can be used in special sequences at the start of the file or before each non-terminal symbol definition to provide attributes to the grammar or non-terminal symbol, respectively, but normal EBNF without these special attributes is also recognized. For help on this format, you can view this link: http://help.infragistics.com/doc/WPF/2013.2/CLR4.0/?page=IG_SPE_EBNF_Format.html. And for help on the framework in general, see this link: http://help.infragistics.com/doc/WPF/2013.2/CLR4.0/?page=IG_SPE.html.

To create a Grammar instance containing the grammar definition of the documents to be parsed, you can either use one of the static Grammar.LoadEbnf(…) methods to create a Grammar instance from an EBNF file or raw EBNF content, or you can build the grammar up manually by adding terminal and non-terminal symbols using code. For your purposes, it sounds like the best approach would be to use the LoadEbnf method and just pass it the EBNF specified by the user.

Once your Grammar instance is created, you need to create the parser for it. This is all handled internally when the Grammar is wrapped in a LanguageBase derived class. You can either use a code generator to write out a derived language class specific to your grammar (via the LanguageGenerator.GenerateClass method) or you can create a new CustomLanguage instance, passing the Grammar to its constructor. For your purposes, it sounds like the latter option is the best. This allows you to read EBNF and create a language instance at runtime, without having to generate code and re-compile.

Once you have a LanguageBase instance representing your Grammar and parser, all you need to do is specify it on a TextDocument’s Language property. If you have a XamSyntaxEditor in which the user can type input, the Document property of this editor will be a TextDocument instance and you would set the Language property on this instance. Then the editor will automatically show errors for content which is not correct based on the grammar definition. If you do not have an editor, or you would like more programmatic control over detecting errors, you can create a TextDocument, sets its text using the InitializeText method, parse the text using the Parse() or ParseAsync() methods, and then get the parsed content using the SyntaxTree property.

The SyntaxTree holds a tree-like representation of the parsed text in a structure that matches the grammar definition exactly (any required content which is missing from the user’s input will have error nodes inserted to represent that content, and any unexpected content will be in the leading ignored content collection of the next node in the tree). From this SyntaxTree, you can access the RootNode.ContainsDiagnostics property to see if there are any errors in the entire tree (you can also use ContainsDiagnostics on any interior node to see if there are errors on or within that node). And you can use the GetDiagnostics method on a node to enumerate all errors on or within that node.

I hope I was able to help. Let me know if anything is unclear or you would like more information about anything. Also, check out my blog for more info on parsing: http://www.infragistics.com/community/blogs/mike_dour/

查看更多
登录 后发表回答