The LL(*) Parser Framework is Actipro's own framework for constructing robust text parsers that work standalone or with code editor controls like SyntaxEditor. The framework features grammars that are written in C#/VB using EBNF-like notation, customizable AST construction, advanced error handling/reporting, easy code injection, a complete debugger UI, and much more.
A parsing framework is the key to enhancing a SyntaxEditor editing experience because it gives meaningful information about what is contained in the document. This not only can be used to provide contextual information to the end user (what method is the caret in), but is used to help drive features like automated IntelliPrompt completion lists, parameter info, and quick info.
The parser in our framework is LL(*), meaning it is a top-down parser that can run on a subset of context-free grammars. It parses input from left to right, traces leftmost derivation, and by default uses one symbol of look-ahead. This normally would mean LL(1), however can-match callbacks allow infinite symbol look-ahead, thus making it LL(*).
LL parsers do not support left recursion however grammars can generally be refactored to eliminate left recursion and turn it into right recursion instead. Ambiguity can be resolved using can-match callbacks.
There are many types of parsers, each with their pros and cons. Actipro's LL(*) Parser Framework was carefully designed to be easy-to-use, provide an enormous feature set, and address the most common shortcomings encountered with other third-party parsers. Features include:
The Language Designer tool includes a complete debugger for stepping your grammar-based parsers through its parsing of input text. This mechanism allows you to see how the parser is functioning so that you can quickly find and correct any problems in your grammar definition.
This code snippet shows a grammar production for parsing a function declaration. Note the EBNF-like C# syntax and how to specify the AST that is created for the results.
functionDeclaration.Production = @function + identifier["name"] + openParenthesis.OnErrorContinue() + functionParameterList["params"].Optional() + closeParenthesis.OnErrorContinue() + block["block"].OnErrorContinue() > Ast("FunctionDeclaration", AstFrom("name"), AstConditionalFrom("Parameters", "params"), AstFrom("block"));