Writing Offline Parser Classes - RopleyIT/GLRParser GitHub Wiki

Writing offline parser classes

An offline parser is created using the ParseLR.exe command line tool to create source code for a parser. This source file is then added to the project in which the parser is needed, and compiled to make the executable with an embedded parser. Because of this, there are some differences in how the parser class source code is written relative to an inline parser.

In an offline parser, the parser class source code is written as a two-part inheritance hierarchy. For some parser whose class name is MyParser, the file MyParser.cs is written by the developer wishing to use a parser, and MyParser.Designer.cs is generated from the ParseLR command line tool. MyParser.cs is the base class that contains the application-specific methods, properties and fields that you wish to implement on a one per parser instance basis. MyParser.Designer.cs is the derived class, created from the input grammar specification by the ParseLR.exe application. Note that your parser class should be inherited from the Parsing.Parser base class, and references to the parsing assemblies added to the project. The auto-generated derived class in MyParser.Designer.cs is generated to inherit from your MyParser class.

In an offline parser, rather than having references out to action functions made in the grammar, it is more conventional to write the actual C# action code inline at the end of each grammar production. The ParseLR.exe application converts these inline code fragments into action functions automatically, and places them in the parser class as member functions. These action functions are to be found in the MyParser.Designer.cs half of the class. Guard functions can also be written in the same way, if you wish.

Once generated, the source code for the offline parser should be added to the same project as the application-specific parser class. Hence both MyParser.designer.cs and MyParser.cs will end up in the same compiled assembly. This is necessary for the parser factory to be able to find the parser class when an instance is to be constructed.

An example of the non auto-generated part of the parser class is given below:

// References will have been added to the project for Parsing.dll and
// ParserGenerator.dll. Suitable using statements appear here:
 
using Parsing;
using ParserGenerator;
 
namespace MyApplication
{
    public class MyParser : Parser
    {
        // Example of a guard function.
        // Note that this, like action functions,
        // could have been written in the grammar
        // under the definition of PluralNoun
        // in the guards section of the grammar.
         
        public bool PluralNoun(object arg)
        {
            return arg.ToString().EndsWith("s");
        }
    }
}

Construction

The default (parameterless) constructor for your offline parser will be called automatically from the auto-generated derived class in the MyParser.Designer.cs file. Hence your parser class should either provide a default constructor, or no constructor at all. Initialisation should be handled by property assignment or a hand-crafted initialiser function called once the parser instance has been constructed.

To create an instance of the parser for an offline generated and compiled parser, you will invoke the static CreateInstance() method of the parser factory.

// References will have been added to the project for Parsing.dll and
// ParserGenerator.dll. Suitable using statements appear here:
 
using Parsing;
using ParserGenerator;
 
namespace MyApplication
{
    public class MyParser : Parser
    {
        // Example of a guard function.
        // Note that no action functions are
        // written here, as they are captured
        // from inline code in the grammar
        // description.
         
        public bool PluralNoun(object arg)
        {
            return arg.ToString().EndsWith("s");
        }
    }
     
    ... Client code creating a parser instance ...
     
    MyParser myParser =
        ParserFactory<MyParser>.CreateInstance();
         
    ... Use the parser to parse input ...
}
⚠️ **GitHub.com Fallback** ⚠️