--
-- An instance of this template must have a $Export section and the export_terminals option
--
-- Macros that may be redefined in an instance of this template
--
--     $eof_token
--     $additional_interfaces
--     $super_stream_class -- subclass com.ibm.lpg.LpgLexStream for getKind
--     $prs_stream_class -- use /.PrsStream./ if not subclassing
--     $super_class
--
-- B E G I N N I N G   O F   T E M P L A T E   LexerTemplateF
--
%Options programming_language=rt_cpp,margin=4
%Options table
%options action-block=("*.h", "/.", "./")
%options ParseTable=ParseTable
%Options prefix=Char_

--
-- This template requires that the name of the EOF token be set
-- to EOF and that the prefix be "Char_" to be consistent with
-- KeywordTemplateD.
--
%Eof
    EOF
%End

--
-- This template also requires that the name of the parser EOF
-- Token to be exported be set to EOF_TOKEN
--
%Export
    EOF_TOKEN
%End

%Define
    --
    -- Macros that are be needed in an instance of this template
    --
    $eof_token /.$_EOF_TOKEN./

    $additional_interfaces /../
    $super_stream_class /.$file_prefix$LpgLexStream./
    $prs_stream_class /.IPrsStream./
    $super_class /.Object./

    $prs_stream /. // macro prs_stream is deprecated. Use function getPrsStream
                  getPrsStream()./
    $setSym1 /. // macro setSym1 is deprecated. Use function setResult
               lexParser->setSym1./
    $setResult /. // macro setResult is deprecated. Use function setResult
                 lexParser->setSym1./
    $getSym /. // macro getSym is deprecated. Use function getLastToken
              lexParser->getSym./
    $getToken /. // macro getToken is deprecated. Use function getToken
                lexParser->getToken./
    $getLeftSpan /. // macro getLeftSpan is deprecated. Use function getLeftSpan
                   lexParser->getFirstToken./
    $getRightSpan /. // macro getRightSpan is deprecated. Use function getRightSpan
                    lexParser->getLastToken./

    --
    -- Macros useful for specifying actions
    --
    $Header
    /.
                //
                // Rule $rule_number:  $rule_text
                //
                ./

    $DefaultAction
    /.$Header$case $rule_number: { ./

    $BeginAction /.$DefaultAction./

    $EndAction
    /.            break;
                }./

    $BeginJava
    /.$BeginAction
                $symbol_declarations./

    $EndJava /.$EndAction./

    $NoAction
    /.$Header$case $rule_number:
                    break; ./

    $BeginActions
    /.
         void ruleAction(int ruleNumber)
        {
            switch(ruleNumber)
            {./

    $SplitActions
    /.
                    default:
                        ruleAction$rule_number(ruleNumber);
                        break;
                }
                return;
            }

             void ruleAction$rule_number(int ruleNumber)
            {
                switch (ruleNumber)
                {./

    $EndActions
    /.
                default:
                    break;
            }
            return;
        }./
%End

%Globals
    /.
    ./
%End

%Headers
    /.
    #pragma once
    #include <iostream>
    #include "IPrsStream.h"
    #include "Object.h"
    #include "ParseTable.h"
    #include "RuleAction.h"
    #include "stringex.h"
    #include "Token.h"
    #include "$sym_type.h"
    #include "$prs_type.h"
    #include "$kw_lexer_class.h"
    #include "LexParser.h"
    #include "LpgLexStream.h"
     struct $action_type :public $super_class ,public RuleAction$additional_interfaces
    {
         struct  $super_stream_class;
         $super_stream_class * lexStream = nullptr;

        ~$action_type(){
            delete lexStream;
            delete lexParser;
        }

         inline  static ParseTable* prs = new $prs_type();
         ParseTable* getParseTable() { return prs; }

         LexParser* lexParser = new LexParser();
         LexParser* getParser() { return lexParser; }

         int getToken(int i) { return lexParser->getToken(i); }
         int getRhsFirstTokenIndex(int i) { return lexParser->getFirstToken(i); }
         int getRhsLastTokenIndex(int i) { return lexParser->getLastToken(i); }

         int getLeftSpan() { return lexParser->getToken(1); }
         int getRightSpan() { return lexParser->getLastToken(); }

         void resetKeywordLexer()
        {
            if (kwLexer == nullptr)
                  this->kwLexer = new $kw_lexer_class(lexStream->getInputChars(), $_IDENTIFIER);
            else this->kwLexer->setInput(lexStream->getInputChars());
        }

         void reset(const std::wstring& filename, int tab)
        {
            delete lexStream;
            lexStream = new $super_stream_class(filename, tab);
            lexParser->reset((ILexStream*) lexStream, prs,  this);
            resetKeywordLexer();
        }

         void reset(shared_ptr_wstring input_chars, const std::wstring& filename)
        {
            reset(input_chars, filename, 1);
        }

         void reset(shared_ptr_wstring input_chars, const std::wstring& filename, int tab)
        {
             delete lexStream;
            lexStream = new $super_stream_class(input_chars, filename, tab);
            lexParser->reset((ILexStream*) lexStream, prs,  this);
            resetKeywordLexer();
        }

         $action_type(const std::wstring& filename, int tab)
        {
            reset(filename, tab);
        }

         $action_type(shared_ptr_wstring input_chars, const std::wstring& filename, int tab)
        {
            reset(input_chars, filename, tab);
        }

         $action_type(shared_ptr_wstring input_chars, const std::wstring& filename)
        {
            reset(input_chars, filename, 1);
        }

         $action_type() {}

         ILexStream* getILexStream() { return lexStream; }

        /**
         * @deprecated replaced by {@link #getILexStream()}
         */
         ILexStream* getLexStream() { return lexStream; }

         void initializeLexer($prs_stream_class *prsStream, int start_offset, int end_offset)
        {
            if (!lexStream->getInputChars())
                throw  std::exception("LexStream was not initialized");
            lexStream->setPrsStream(prsStream);
            prsStream->makeToken(start_offset, end_offset, 0); // Token list must start with a bad token
        }

         void addEOF($prs_stream_class *prsStream, int end_offset)
        {
            prsStream->makeToken(end_offset, end_offset, $eof_token); // and end with the end of file token
            prsStream->setStreamLength(prsStream->getSize());
        }

         void lexer($prs_stream_class *prsStream)
        {
            lexer(nullptr, prsStream);
        }

         void lexer(Monitor *monitor, $prs_stream_class *prsStream)
        {
            initializeLexer(prsStream, 0, -1);
            lexParser->parseCharacters(monitor);  // Lex the input characters
            addEOF(prsStream, lexStream->getStreamIndex());
        }

         void lexer($prs_stream_class *prsStream, int start_offset, int end_offset)
        {
            lexer(nullptr, prsStream, start_offset, end_offset);
        }

         void lexer(Monitor* monitor, $prs_stream_class *prsStream, int start_offset, int end_offset)
        {
            if (start_offset <= 1)
                 initializeLexer(prsStream, 0, -1);
            else initializeLexer(prsStream, start_offset - 1, start_offset - 1);

            lexParser->parseCharacters(monitor, start_offset, end_offset);

            addEOF(prsStream, (end_offset >= lexStream->getStreamIndex() ? lexStream->getStreamIndex() : end_offset + 1));
        }

         IPrsStream::Range *incrementalLexer(shared_ptr_wstring input_chars, int start_change_offset, int end_change_offset) {
            int offset_adjustment = input_chars.size() - lexStream->getStreamLength();
//*System.out.println("The offset adjustment is " + offset_adjustment);
            if (start_change_offset <= 0 && start_change_offset < input_chars.size())
            {
                std::string str = "The start offset ";
                std::stringex format;
                format.format("%d", (start_change_offset));
                str += format;
                str += " is out of bounds for range 0..";
                format.format("%d", (input_chars.size() - 1));
                str += format;
                throw  std::out_of_range(str);
            }

            if (end_change_offset <= 0 && end_change_offset < input_chars.size())
            {
                std::string str = "The end offset ";
                std::stringex format;
                format.format("%d", (end_change_offset));
                str += format;
                str += " is out of bounds for range 0..";
                format.format("%d", (input_chars.size() - 1));
                str += format;
            }
            //
            // Get the potential list of tokens to be rescanned
            //
           Tuple<IToken*> affected_tokens = lexStream->getIPrsStream()->incrementalResetAtCharacterOffset(start_change_offset);

            //
            // If the change occured between the first two affected tokens (or adjunct) and not immediately
            // on the characted after the first token (or adjunct), restart the scanning after the first
            // affected token. Otherwise, rescan the first token.
            //
            int affected_index = 0;
            int repair_offset = start_change_offset;
            if (affected_tokens.size() > 0) {
                auto _token_0 = affected_tokens.get(0);
                if (_token_0->getEndOffset() + 1 < start_change_offset)
                {
                     repair_offset = _token_0->getEndOffset() + 1;
                     if (dynamic_cast<Token*>(_token_0))
                    {
                           lexStream->getIPrsStream()->makeToken(_token_0, 0);
                    }
                    else {
                            lexStream->getIPrsStream()->makeAdjunct(_token_0, 0);
                    }

                    affected_index++;
                }
                else
                {
                    repair_offset = _token_0->getStartOffset();
                }
            }

            lexStream->setInputChars(input_chars);
            lexStream->setStreamLength(input_chars.size());
            lexStream->computeLineOffsets(repair_offset);

            int first_new_token_index = lexStream->getIPrsStream()->getTokens().size(),
                first_new_adjunct_index = lexStream->getIPrsStream()->getAdjuncts().size();

            resetKeywordLexer();
            lexParser->resetTokenStream(repair_offset);
            int next_offset;
            do {
//*System.out.println("Scanning token starting at " + (lexStream->peek() - 1));
                next_offset = lexParser->incrementalParseCharacters();
//*System.out.print("***Remaining string: \"");
//*for (int i = next_offset; i < input_chars.length; i++)
//*System.out.print(input_chars[i]);
//*System.out.println("\"");
                while (affected_index < affected_tokens.size() &&
                       affected_tokens.get(affected_index)->getStartOffset() + offset_adjustment < next_offset)
//*{
//*System.out.println("---Skipping token " + affected_index + ": \"" + affected_tokens.get(affected_index).toString() +
//*"\" starting at adjusted offset " + (affected_tokens.get(affected_index).getStartOffset() + offset_adjustment));
                    affected_index++;
//*}
            } while(next_offset <= end_change_offset &&          // still in the damage region and ...
                    (affected_index < affected_tokens.size() &&  // not resynchronized with a token in the list of affected tokens
                     affected_tokens.get(affected_index)->getStartOffset() + offset_adjustment != next_offset));

            //
            // If any new tokens were added, compute the first and the last one.
            //
            IToken* first_new_token = nullptr;
              IToken*      last_new_token = nullptr;
            if (first_new_token_index < lexStream->getIPrsStream()->getTokens().size()) {
                first_new_token = lexStream->getIPrsStream()->getTokenAt(first_new_token_index);
                last_new_token = lexStream->getIPrsStream()->getTokenAt(lexStream->getIPrsStream()->getTokens().size() - 1);
            }
            //
            // If an adjunct was added prior to the first real token, chose it instead as the first token.
            // Similarly, if adjucts were added after the last token, chose the last adjunct added as the last token.
            //
            if (first_new_adjunct_index < lexStream->getIPrsStream()->getAdjuncts().size()) {
                if (first_new_token == nullptr ||
                    lexStream->getIPrsStream()->getAdjunctAt(first_new_adjunct_index)->getStartOffset() <
                    first_new_token->getStartOffset()) {
                    first_new_token = lexStream->getIPrsStream()->getAdjunctAt(first_new_adjunct_index);
                }
                if (last_new_token == nullptr ||
                    lexStream->getIPrsStream()->getAdjunctAt(lexStream->getIPrsStream()->getAdjuncts().size() - 1)->getEndOffset() >
                    last_new_token->getEndOffset()) {
                    last_new_token = lexStream->getIPrsStream()->getAdjunctAt(lexStream->getIPrsStream()->getAdjuncts().size() - 1);
                }
            }

            //
            // For all remainng tokens (and adjuncts) in the list of affected tokens add them to the
            // list of tokens (and adjuncts).
            //
            for (int i = affected_index; i < affected_tokens.size(); i++) {
                if ( dynamic_cast< Token*>(affected_tokens.get(i)) )
                     lexStream->getIPrsStream()->makeToken(affected_tokens.get(i), offset_adjustment);
                else lexStream->getIPrsStream()->makeAdjunct(affected_tokens.get(i), offset_adjustment);
//*System.out.println("+++Added affected token " + i + ": \"" + affected_tokens.get(i).toString() +
//*"\" starting at adjusted offset " + (affected_tokens.get(i).getStartOffset() + offset_adjustment));
            }

            return new IPrsStream::Range(lexStream->getIPrsStream(), first_new_token, last_new_token);
        }

        /**
         * If a parse stream was not passed to this Lexical analyser then we
         * simply report a lexical error. Otherwise, we produce a bad token.
         */
         void reportLexicalError(int startLoc, int endLoc) {
            IPrsStream* prs_stream = lexStream->getIPrsStream();
            if (prs_stream == nullptr)
                lexStream->reportLexicalError(startLoc, endLoc);
            else {
                //
                // Remove any token that may have been processed that fall in the
                // range of the lexical error... then add one error token that spans
                // the error range.
                //
                for (int i = prs_stream->getSize() - 1; i > 0; i--) {
                    if (prs_stream->getStartOffset(i) >= startLoc)
                         prs_stream->removeLastToken();
                    else break;
                }
                prs_stream->makeToken(startLoc, endLoc, 0); // add an error token to the prsStream
            }
        }
    ./
%End

%Rules
    /.$BeginActions./
%End

%Trailers
    /.
        $EndActions
    };
    ./
%End

--
-- E N D   O F   T E M P L A T E
--


--
-- An instance of this template must have a $Export section and the export_terminals option
--
-- Macros that may be redefined in an instance of this template
--
--     $eof_token
--     $additional_interfaces
--     $super_stream_class -- subclass com.ibm.lpg.Utf8LpgLexStream for getKind
--     $prs_stream_class -- use /.PrsStream./ if not subclassing
--
-- B E G I N N I N G   O F   T E M P L A T E   LexerTemplateD
--
%Options programming_language=rt_cpp,margin=4
%Options table
%options action-block=("*.h", "/.", "./")
%options ParseTable=ParseTable
%Options prefix=Char_

--
-- This template requires that the name of the EOF token be set
-- to EOF and that the prefix be "Char_" to be consistent with
-- KeywordTemplateD.
--
%Eof
    EOF
%End

--
-- This template also requires that the name of the parser EOF
-- Token to be exported be set to EOF_TOKEN
--
%Export
    EOF_TOKEN
%End

%Define
    --
    -- Macros that are be needed in an instance of this template
    --
    $eof_token /.$_EOF_TOKEN./

    $additional_interfaces /../
    $super_stream_class /.$file_prefix$Utf8LpgLexStream./
    $prs_stream_class /.IPrsStream./
    $super_class /.Object./

    --
    -- Macros useful for specifying actions
    --
    $Header
    /.
                //
                // Rule $rule_number:  $rule_text
                //
                ./

    $DefaultAction
    /.$Header$case $rule_number: { ./

    $BeginAction /.$DefaultAction./

    $EndAction
    /.          break;
                }./

    $BeginJava
    /.$BeginAction
                $symbol_declarations./

    $EndJava /.$EndAction./

    $NoAction
    /.$Header$case $rule_number:
                    break; ./

    $BeginActions
    /.
         void ruleAction( int ruleNumber)
        {
            switch(ruleNumber)
            {./

    $SplitActions
    /.
	            default:
	                ruleAction$rule_number(ruleNumber);
	                break;
	        }
	        return;
	    }

	     void ruleAction$rule_number(int ruleNumber)
	    {
	        switch (ruleNumber)
	        {./

    $EndActions
    /.
                default:
                    break;
            }
            return;
        }./
%End

%Globals
    /.
    ./
%End

%Headers
    /.
	#pragma once
    #include <iostream>
    #include "IPrsStream.h"
    #include "Object.h"
    #include "ParseTable.h"
    #include "RuleAction.h"
    #include "stringex.h"
    #include "Token.h"
    #include "$sym_type.h"
    #include "$prs_type.h"
    #include "$kw_lexer_class.h"
    #include "LexParser.h"
    #include "Utf8LpgLexStream.h"
    struct $action_type :public $super_class,  public RuleAction$additional_interfaces
    {
		struct  $super_stream_class;
         $super_stream_class *lexStream= nullptr;
        ~$action_type(){
            delete lexStream;
            delete lexParser;
        }
         inline  static ParseTable* prs = new $prs_type();
         ParseTable* getParseTable() { return prs; }

         LexParser* lexParser = new LexParser();
         LexParser* getParser() { return lexParser; }

         int getToken(int i) { return lexParser->getToken(i); }
         int getRhsFirstTokenIndex(int i) { return lexParser->getFirstToken(i); }
         int getRhsLastTokenIndex(int i) { return lexParser->getLastToken(i); }

         int getLeftSpan() { return lexParser->getToken(1); }
         int getRightSpan() { return lexParser->getLastToken(); }

         void resetKeywordLexer()
        {
            if (kwLexer == nullptr)
                  this->kwLexer = new $kw_lexer_class(lexStream->getInputBytes(), $_IDENTIFIER);
            else this->kwLexer->setInput(lexStream->getInputBytes());
        }

         void reset(const std::wstring&  filename, int tab)
        {
			delete lexStream;
            lexStream = new $super_stream_class(filename, tab);
            lexParser->reset((ILexStream*) lexStream, prs,this);
            resetKeywordLexer();
        }

         void reset(shared_ptr_string input_bytes, const std::wstring& filename)
        {
            reset(input_bytes, filename, 1);
        }

         void reset(shared_ptr_string input_bytes, const std::wstring& filename, int tab)
        {
            lexStream = new $super_stream_class(input_bytes, filename, tab);
            lexParser->reset((ILexStream*) lexStream, prs,  this);
            resetKeywordLexer();
        }

         $action_type(const std::wstring& filename, int tab)
        {
            reset(filename, tab);
        }

         $action_type(shared_ptr_string input_bytes, const std::wstring&  filename, int tab)
        {
            reset(input_bytes, filename, tab);
        }

         $action_type(shared_ptr_string input_bytes, const std::wstring&  filename)
        {
            reset(input_bytes, filename, 1);
        }

         $action_type() {}

         ILexStream* getILexStream() { return lexStream; }

        /**
         * @deprecated replaced by {@link #getILexStream()}
         */
         ILexStream* getLexStream() { return lexStream; }

         void initializeLexer($prs_stream_class * prsStream, int start_offset, int end_offset)
        {
            if (lexStream->getInputBytes().size() == 0)
                throw  std::exception("LexStream was not initialized");
            lexStream->setPrsStream(prsStream);
            prsStream->makeToken(start_offset, end_offset, 0); // Token list must start with a bad token
        }

         void lexer($prs_stream_class* prsStream)
        {
            lexer(nullptr, prsStream);
        }

         void lexer(Monitor* monitor, $prs_stream_class* prsStream)
        {
            if (lexStream->getInputBytes().size() == 0)
                  throw  std::exception("lexStream was not initialized");

            lexStream->setPrsStream(prsStream);

            prsStream->makeToken(0, 0, 0); // Token list must start with a bad token

            lexParser->parseCharacters(monitor);  // Lex the input characters

            int i = lexStream->getStreamIndex();
            prsStream->makeToken(i, i, $eof_token); // and end with the end of file token
            prsStream->setStreamLength(prsStream->getSize());

            return;
        }
    ./
%End

%Rules
    /.$BeginActions./
%End

%Trailers
    /.
        $EndActions
    };
    ./
%End

--
-- E N D   O F   T E M P L A T E
--


%Headers
    --
    -- Additional methods for the action class not provided in the template
    --

	-- [cwd] Template provided by LPG defines a constructor that uses an Option
	--       class that does not exist in LPG Runtime.  Deleted this constructor

    /.
        final void makeToken(int kind)
        {
            int startOffset = getLeftSpan(),
                endOffset = getRightSpan();
            makeToken(startOffset, endOffset, kind);
            if (printTokens) printValue(startOffset, endOffset);
        }

        final void makeComment(int kind)
        {
            int startOffset = getLeftSpan(),
                endOffset = getRightSpan();
            super.getIPrsStream().makeAdjunct(startOffset, endOffset, kind);
        }

        final void skipToken()
        {
            if (printTokens) printValue(getLeftSpan(), getRightSpan());
        }

        final void checkForKeyWord()
        {
            int startOffset = getLeftSpan(),
                endOffset = getRightSpan(),
            kwKind = kwLexer.lexer(startOffset, endOffset);
            makeToken(startOffset, endOffset, kwKind);
            if (printTokens) printValue(startOffset, endOffset);
        }

        final void printValue(int startOffset, int endOffset)
        {
            String s = new String(getInputChars(), startOffset, endOffset - startOffset + 1);
            System.out.print(s);
        }

        //
        //
        //
        public final static int tokenKind[] =
        {
            Char_CtlCharNotWS,    // 000    0x00
            Char_CtlCharNotWS,    // 001    0x01
            Char_CtlCharNotWS,    // 002    0x02
            Char_CtlCharNotWS,    // 003    0x03
            Char_CtlCharNotWS,    // 004    0x04
            Char_CtlCharNotWS,    // 005    0x05
            Char_CtlCharNotWS,    // 006    0x06
            Char_CtlCharNotWS,    // 007    0x07
            Char_CtlCharNotWS,    // 008    0x08
            Char_HT,              // 009    0x09
            Char_LF,              // 010    0x0A
            Char_CtlCharNotWS,    // 011    0x0B
            Char_FF,              // 012    0x0C
            Char_CR,              // 013    0x0D
            Char_CtlCharNotWS,    // 014    0x0E
            Char_CtlCharNotWS,    // 015    0x0F
            Char_CtlCharNotWS,    // 016    0x10
            Char_CtlCharNotWS,    // 017    0x11
            Char_CtlCharNotWS,    // 018    0x12
            Char_CtlCharNotWS,    // 019    0x13
            Char_CtlCharNotWS,    // 020    0x14
            Char_CtlCharNotWS,    // 021    0x15
            Char_CtlCharNotWS,    // 022    0x16
            Char_CtlCharNotWS,    // 023    0x17
            Char_CtlCharNotWS,    // 024    0x18
            Char_CtlCharNotWS,    // 025    0x19
            Char_CtlCharNotWS,    // 026    0x1A
            Char_CtlCharNotWS,    // 027    0x1B
            Char_CtlCharNotWS,    // 028    0x1C
            Char_CtlCharNotWS,    // 029    0x1D
            Char_CtlCharNotWS,    // 030    0x1E
            Char_CtlCharNotWS,    // 031    0x1F
            Char_Space,           // 032    0x20
            Char_Exclamation,     // 033    0x21
            Char_DoubleQuote,     // 034    0x22
            Char_Sharp,           // 035    0x23
            Char_DollarSign,      // 036    0x24
            Char_Percent,         // 037    0x25
            Char_Ampersand,       // 038    0x26
            Char_SingleQuote,     // 039    0x27
            Char_LeftParen,       // 040    0x28
            Char_RightParen,      // 041    0x29
            Char_Star,            // 042    0x2A
            Char_Plus,            // 043    0x2B
            Char_Comma,           // 044    0x2C
            Char_Minus,           // 045    0x2D
            Char_Dot,             // 046    0x2E
            Char_Slash,           // 047    0x2F
            Char_0,               // 048    0x30
            Char_1,               // 049    0x31
            Char_2,               // 050    0x32
            Char_3,               // 051    0x33
            Char_4,               // 052    0x34
            Char_5,               // 053    0x35
            Char_6,               // 054    0x36
            Char_7,               // 055    0x37
            Char_8,               // 056    0x38
            Char_9,               // 057    0x39
            Char_Colon,           // 058    0x3A
            Char_SemiColon,       // 059    0x3B
            Char_LessThan,        // 060    0x3C
            Char_Equal,           // 061    0x3D
            Char_GreaterThan,     // 062    0x3E
            Char_QuestionMark,    // 063    0x3F
            Char_AtSign,          // 064    0x40
            Char_A,               // 065    0x41
            Char_B,               // 066    0x42
            Char_C,               // 067    0x43
            Char_D,               // 068    0x44
            Char_E,               // 069    0x45
            Char_F,               // 070    0x46
            Char_G,               // 071    0x47
            Char_H,               // 072    0x48
            Char_I,               // 073    0x49
            Char_J,               // 074    0x4A
            Char_K,               // 075    0x4B
            Char_L,               // 076    0x4C
            Char_M,               // 077    0x4D
            Char_N,               // 078    0x4E
            Char_O,               // 079    0x4F
            Char_P,               // 080    0x50
            Char_Q,               // 081    0x51
            Char_R,               // 082    0x52
            Char_S,               // 083    0x53
            Char_T,               // 084    0x54
            Char_U,               // 085    0x55
            Char_V,               // 086    0x56
            Char_W,               // 087    0x57
            Char_X,               // 088    0x58
            Char_Y,               // 089    0x59
            Char_Z,               // 090    0x5A
            Char_LeftBracket,     // 091    0x5B
            Char_BackSlash,       // 092    0x5C
            Char_RightBracket,    // 093    0x5D
            Char_Caret,           // 094    0x5E
            Char__,               // 095    0x5F
            Char_BackQuote,       // 096    0x60
            Char_a,               // 097    0x61
            Char_b,               // 098    0x62
            Char_c,               // 099    0x63
            Char_d,               // 100    0x64
            Char_e,               // 101    0x65
            Char_f,               // 102    0x66
            Char_g,               // 103    0x67
            Char_h,               // 104    0x68
            Char_i,               // 105    0x69
            Char_j,               // 106    0x6A
            Char_k,               // 107    0x6B
            Char_l,               // 108    0x6C
            Char_m,               // 109    0x6D
            Char_n,               // 110    0x6E
            Char_o,               // 111    0x6F
            Char_p,               // 112    0x70
            Char_q,               // 113    0x71
            Char_r,               // 114    0x72
            Char_s,               // 115    0x73
            Char_t,               // 116    0x74
            Char_u,               // 117    0x75
            Char_v,               // 118    0x76
            Char_w,               // 119    0x77
            Char_x,               // 120    0x78
            Char_y,               // 121    0x79
            Char_z,               // 122    0x7A
            Char_LeftBrace,       // 123    0x7B
            Char_VerticalBar,     // 124    0x7C
            Char_RightBrace,      // 125    0x7D
            Char_Tilde,           // 126    0x7E
            Char_CtlCharNotWS,    // 127    0x7F

            Char_Acute,           // for the acute accent 0xb4
            Char_AfterASCIINotAcute,  // for all chars in range 0x80..0xfffe excluding the acute accent
            Char_EOF              // for '\uffff' or 65535
        };

        @Override public final int getKind(int i)  // Classify character at ith location
        {
            char c = (i >= getStreamLength() ? '\uffff' : getCharValue(i));
            return (c < 128)? // ASCII Character
                      tokenKind[c] :
                      (c == '\uffff')?
                           Char_EOF :
                           (c == '\u00b4')?
                           Char_Acute :
                               Char_AfterASCIINotAcute;
        }
    ./
%End


# Comment (till end of line)


--
-- An LPG Parser Template Using lpg.jar
--
-- Macros that may be redefined in an instance of this template
--
--     $additional_interfaces
--     $super_stream_class
--
-- B E G I N N I N G   O F   T E M P L A T E   dtUnifiedTemplateF
--
%Options programming_language=csharp
%Options table
%Options margin=4
%Options prefix=Char_
%Options action-block=("*.cs", "/.", "./")
%Options ParseTable=LPG2.Runtime.ParseTable

--
-- The EOF and ERROR symbols are assigned a default here as a
-- convenience.
--
%EOF
    EOF
%End

%Define
    $Header
    /.
                //
                // Rule $rule_number:  $rule_text
                //
                ./

    $BeginAction
    /.$Header$case $rule_number: {./

    $EndAction
    /.          break;
                }./

    $BeginJava
    /.$BeginAction
                    $symbol_declarations./

    $EndJava /.$EndAction./

    $NoAction
    /.$Header$case $rule_number:
                    break;./

    $NullAction
    /.$Header$case $rule_number:
                    $setResult(null);
                    break;./

    $BeginActions
    /.
        public void ruleAction(int ruleNumber)
        {
            switch (ruleNumber)
            {./

    $SplitActions
    /.
	            default:
	                ruleAction$rule_number(ruleNumber);
	                break;
	        }
	        return;
	    }

	    public void ruleAction$rule_number(int ruleNumber)
	    {
	        switch (ruleNumber)
	        {./

    $EndActions
    /.
                default:
                    break;
            }
            return;
        }./

    $additional_interfaces /../
    $super_stream_class /.LpgLexStream./
%End

%Globals
    /.
      using LPG2.Runtime;
      using System;
    ./
%End

%Headers
    /.
    public class $action_type : $super_stream_class , $sym_type, RuleAction$additional_interfaces
    {
        private static ParseTable prs = new $prs_type();
        private DeterministicParser dtParser;

        private void setResult(object _object) { dtParser.setSym1(_object); }
        public DeterministicParser getParser() { return dtParser; }
        public object getRhsSym(int i) { return dtParser.getSym(i); }
        public int getRhsTokenIndex(int i) { return dtParser.getToken(i); }
        public int getRhsFirstTokenIndex(int i) { return dtParser.getFirstToken(i); }
        public int getRhsLastTokenIndex(int i) { return dtParser.getLastToken(i); }

        public int getLeftSpan() { return dtParser.getFirstToken(); }
        public int getRightSpan() { return dtParser.getLastToken(); }

        public $action_type(string filename, int tab) :  base(filename, tab)
        {

        }

        public override string[] orderedExportedSymbols() { return orderedTerminalSymbols; }
        public int getEOFTokenKind() { return $prs_type.EOFT_SYMBOL; }

        public ILexStream getILexStream() { return ($super_stream_class) this; }

        /**
         * @deprecated replaced by {@link #getILexStream()}
         */
        public ILexStream getLexStream() { return ($super_stream_class) this; }

        public $ast_type parser()
        {
            return parser(null, 0);
        }

        public $ast_type parser(Monitor monitor)
        {
            return parser(monitor, 0);
        }

        public $ast_type parser(int error_repair_count)
        {
            return parser(null, error_repair_count);
        }

        public $ast_type parser(Monitor monitor, int error_repair_count)
        {
            try
            {
                dtParser = new DeterministicParser(this, prs, this);
            }
            catch (NotDeterministicParseTableException e)
            {
                 Console.Out.WriteLine("****Error: Regenerate $prs_type.cs with -NOBACKTRACK option");
                 return null;
            }
            catch (BadParseSymFileException e)
            {
                 Console.Out.WriteLine("****Error: Bad Parser Symbol File -- $sym_type.cs. Regenerate $prs_type.cs");
                 return null;
            }
            dtParser.setMonitor(monitor);

            try
            {
                return ($ast_type) dtParser.parse();
            }
            catch (BadParseException e)
            {
                reset(e.error_token); // point to error token

                 Console.Out.Write("Error detected on character " + e.error_token);
                if (e.error_token < getStreamLength())
                      Console.Out.Write(" at line " + getLine(e.error_token) + ", column " + getColumn(e.error_token));
                else  Console.Out.Write(" at end of file ");
                 Console.Out.WriteLine(" with kind " + getKind(e.error_token));
            }

            return null;
        }

    ./

%End

%Rules
    /.$BeginActions./
%End

%Trailers
    /.
        $EndActions
    }
    ./
%End

--
-- E N D   O F   T E M P L A T E
--


--/**
-- * <copyright>
-- *
-- * Copyright (c) 2008 Eclipse.org and others.
-- * All rights reserved.   This program and the accompanying materials
-- * are made available under the terms of the Eclipse Public License v2.0
-- * which accompanies this distribution, and is available at
-- * http://www.eclipse.org/legal/epl-v20.html
-- *
-- * Contributors:
-- *   E.D. Willink - Initial API and implementation
-- *   Adolfo Sanchez-Barbudo Herrera (Open Canarias):
-- *        - 242153: LPG v 2.0.17 adoption.
-- *        - 299396: Introducing new LPG templates.
-- *        - 300534: Removing the use of deprecated macros.
-- *
-- * </copyright>
-- */
--
-- Additional ERROR_TOKEN rules for The OCL Parser
--

%Import
	OCLParser.g
%End

%Import
	EssentialOCLErrors.gi
%End

%Rules

-----------------------------------------------------------------------
--	Calls
-----------------------------------------------------------------------
	OclMessageExpCS ::= primaryExpCS '^^' simpleNameCS ERROR_TOKEN
		/.$NewCase./
	OclMessageExpCS ::= primaryExpCS '^' simpleNameCS ERROR_TOKEN
		/.$BeginCode
					reportErrorTokenMessage(getRhsTokenIndex(2), OCLParserErrors.MISSING_MESSAGE_ARGUMENTS);
					OCLExpressionCS target = (OCLExpressionCS)getRhsSym(1);
					MessageExpCS result = createMessageExpCS(
							target,
							getRhsIToken(2).getKind() == $sym_type.TK_CARET,
							(SimpleNameCS)getRhsSym(3),
							new BasicEList<OCLMessageArgCS>()
						);
					setOffsets(result, target, getRhsIToken(4));
					setResult(result);
		  $EndCode
		./

-----------------------------------------------------------------------
--	Contexts
-----------------------------------------------------------------------
	classifierContextDeclCS ::= context pathNameCS ERROR_TOKEN
		/.$BeginCode
					reportErrorTokenMessage(getRhsTokenIndex(3), OCLParserErrors.MISSING_INV_OR_DEF);
					ClassifierContextDeclCS result = createClassifierContextDeclCS(
							null,
							(PathNameCS)getRhsSym(2),
							new BasicEList<InvOrDefCS>()
						);
					setOffsets(result, getRhsIToken(1), getRhsIToken(3));
					setResult(result);
		  $EndCode
		./

	defExpressionCS ::= typedUninitializedVariableCS ERROR_TOKEN
		/.$BeginCode
					reportErrorTokenMessage(getRhsTokenIndex(2), OCLParserErrors.MISSING_EQUALS);
					VariableCS variableCS = (VariableCS)getRhsSym(1);
					DefExpressionCS result = createDefExpressionCS(
							variableCS,
							null,
							null
						);
					setOffsets(result, variableCS, getRhsIToken(2));
					setResult(result);
		  $EndCode
		./
	defExpressionCS ::= simpleNameCS ERROR_Colon
		/.$BeginCode
					SimpleNameCS name = (SimpleNameCS)getRhsSym(1);
					VariableCS variableCS = createVariableCS(name, null, null);
					setOffsets(variableCS, name, getRhsIToken(2));
					DefExpressionCS result = createDefExpressionCS(
							variableCS,
							null,
							null
						);
					setOffsets(result, variableCS, getRhsIToken(2));
					setResult(result);
		  $EndCode
		./

	invOrDefCS ::= inv unreservedSimpleNameCS ERROR_Colon
		/.$BeginCode
					InvCS result = createInvCS(
							(SimpleNameCS)getRhsSym(2),
							null
						);
					setOffsets(result, getRhsIToken(1), getRhsIToken(3));
					setResult(result);
		  $EndCode
		./
    invOrDefCS ::= def unreservedSimpleNameCS ERROR_Colon
        /.$BeginCode
                    DefCS result = createDefCS(
                            false,
                            (SimpleNameCS)getRhsSym(2),
                            null
                        );
                    setOffsets(result, getRhsIToken(1), getRhsIToken(3));
                    setResult(result);
          $EndCode
        ./
    invOrDefCS ::= static def unreservedSimpleNameCS ERROR_Colon
        /.$BeginCode
                    DefCS result = createDefCS(
                            true,
                            (SimpleNameCS)getRhsSym(3),
                            null
                        );
                    setOffsets(result, getRhsIToken(1), getRhsIToken(4));
                    setResult(result);
          $EndCode
        ./

	operationCS1 ::= simpleNameCS '(' parametersCSopt ')' ERROR_Colon
		/.$BeginCode
					OperationCS result = createOperationCS(
							getRhsIToken(1),
							new BasicEList<VariableCS>(),
							null
						);
					setOffsets(result, getRhsIToken(1), getRhsIToken(5));
					setResult(result);
		  $EndCode
		./
	operationCS1 ::= simpleNameCS ERROR_TOKEN
		/.$BeginCode
					reportErrorTokenMessage(getRhsTokenIndex(2), OCLParserErrors.MISSING_LPAREN);
					OperationCS result = createOperationCS(
							getRhsIToken(1),
							new BasicEList<VariableCS>(),
							null
						);
					setOffsets(result, getRhsIToken(1), getRhsIToken(2));
					setResult(result);
		  $EndCode
		./
	operationCS1 ::= ERROR_TOKEN
		/.$BeginCode
					reportErrorTokenMessage(getRhsTokenIndex(1), OCLParserErrors.MISSING_IDENTIFIER);
					OperationCS result = createOperationCS(
							getRhsIToken(1),
							new BasicEList<VariableCS>(),
							null
						);
					setOffsets(result, getRhsIToken(1));
					setResult(result);
		  $EndCode
		./
	operationCS2 ::= pathNameCS '::' unreservedSimpleNameCS '(' parametersCSopt ')' ERROR_Colon
		/.$BeginCode
					PathNameCS pathNameCS = (PathNameCS)getRhsSym(1);
					SimpleNameCS simpleNameCS = (SimpleNameCS)getRhsSym(3);
					OperationCS result = createOperationCS(
							pathNameCS,
							simpleNameCS,
							(EList<VariableCS>)getRhsSym(5),
							null
						);
					setOffsets(result, pathNameCS, getRhsIToken(7));
					setResult(result);
		  $EndCode
		./
	operationCS2 ::= pathNameCS '::' ERROR_SimpleNameCS
		/.$BeginCode
					PathNameCS pathNameCS = (PathNameCS)getRhsSym(1);
					SimpleNameCS simpleNameCS = (SimpleNameCS)getRhsSym(3);
					OperationCS result = createOperationCS(
							pathNameCS,
							simpleNameCS,
							new BasicEList<VariableCS>(),
							null
						);
					setOffsets(result, pathNameCS, simpleNameCS);
					setResult(result);
		  $EndCode
		./

	prePostOrBodyDeclCS ::= pre unreservedSimpleNameCS ERROR_Colon
		/.$BeginCode
					PrePostOrBodyDeclCS result = createPrePostOrBodyDeclCS(
							PrePostOrBodyEnum.PRE_LITERAL,
							(SimpleNameCS)getRhsSym(2),
							createInvalidLiteralExpCS(getRhsTokenText(3))
						);
					setOffsets(result, getRhsIToken(1), getRhsIToken(3));
					setResult(result);
		  $EndCode
		./
	prePostOrBodyDeclCS ::= post unreservedSimpleNameCS ERROR_Colon
		/.$BeginCode
					PrePostOrBodyDeclCS result = createPrePostOrBodyDeclCS(
							PrePostOrBodyEnum.POST_LITERAL,
							(SimpleNameCS)getRhsSym(2),
							createInvalidLiteralExpCS(getRhsTokenText(3))
						);
					setOffsets(result, getRhsIToken(1), getRhsIToken(3));
					setResult(result);
		  $EndCode
		./
	prePostOrBodyDeclCS ::= body unreservedSimpleNameCS ERROR_Colon
		/.$BeginCode
					PrePostOrBodyDeclCS result = createPrePostOrBodyDeclCS(
							PrePostOrBodyEnum.BODY_LITERAL,
							(SimpleNameCS)getRhsSym(2),
							createInvalidLiteralExpCS(getRhsTokenText(3))
						);
					setOffsets(result, getRhsIToken(1), getRhsIToken(3));
					setResult(result);
		  $EndCode
		./

	initOrDerValueCS ::= init ERROR_Colon
		/.$BeginCode
					InitValueCS result = createInitValueCS(null);
					setOffsets(result, getRhsIToken(2), getRhsIToken(3));
					setResult(result);
		  $EndCode
		./
	initOrDerValueCS ::= derive ERROR_Colon
		/.$BeginCode
					DerValueCS result = createDerValueCS(null);
					setOffsets(result, getRhsIToken(2), getRhsIToken(3));
					setResult(result);
		  $EndCode
		./

	packageDeclarationCS_A ::= package pathNameCS contextDeclsCSopt ERROR_Empty endpackage
		/.$BeginCode
					PackageDeclarationCS result = createPackageDeclarationCS(
							(PathNameCS)getRhsSym(2),
							(EList<ContextDeclCS>)getRhsSym(3)
						);
					setOffsets(result, getRhsIToken(1), getRhsIToken(5));
					setResult(result);
		  $EndCode
		./
	packageDeclarationCS_A ::= package pathNameCS contextDeclsCSopt ERROR_TOKEN
		/.$BeginCode
					reportErrorTokenMessage(getRhsTokenIndex(4), OCLParserErrors.MISSING_ENDPACKAGE);
					PackageDeclarationCS result = createPackageDeclarationCS(
							(PathNameCS)getRhsSym(2),
							(EList<ContextDeclCS>)getRhsSym(3)
						);
					setOffsets(result, getRhsIToken(1), getRhsIToken(4));
					setResult(result);
		  $EndCode
		./
%End


#
# francy: Interactive Discrete Mathematics in GAP
#

#############################################################################
##
#M  Menu( <title> ) . . . . . . . . . . . . . . . a new menu entry
##
InstallMethod(Menu,
  "a title string",
  true,
  [IsString,
   IsCallback],
  0,
function(title, callback)
  return Objectify(MenuObjectType, rec(
    id       := GenerateID(),
    title    := title,
    callback := callback,
    menus    := rec()
  ));
end);

InstallOtherMethod(Menu,
  "a title string",
  true,
  [IsString],
  0,
function(title)
  return Menu(title, NoopCallback());
end);

#############################################################################
##
#M  Add( <menu>, <menu> ) . . . . . add menu to canvas
##
InstallOtherMethod(Add,
  "a menu, a menu",
  true,
  [IsMenu,
   IsMenu],
  0,
function(menu, object)
  menu!.menus!.(object!.id) := object;
  return menu;
end);

InstallOtherMethod(Add,
  "a canvas, a list of francy objects",
  true,
  [IsMenu,
   IsList],
  0,
function(menu, objects)
  local object;
  for object in objects do
    Add(menu, object);
  od;
  return menu;
end);

#############################################################################
##
#M  Remove( <menu>, <menu> ) . . . . . remove menu from menu
##
InstallOtherMethod(Remove,
  "a menu, a menu",
  true,
  [IsMenu,
   IsMenu],
  0,
function(menu, object)
  Unbind(menu!.menus!.(object!.id));
  return menu;
end);

InstallOtherMethod(Remove,
  "a menu, a list of francy objects",
  true,
  [IsMenu,
   IsList],
  0,
function(menu, objects)
  local object;
  for object in objects do
    Remove(menu, object);
  od;
  return menu;
end);


--
-- The Java Lexer
--
%Options list
%Options fp=JavaLexer
%options single_productions
%options template=LexerTemplateF.gi
%options filter=GJavaKWLexer.gi
%options lalr=4
$Define
    --
    -- Definition of macro used in the included file LexerBasicMapB.g
    --
    $kw_lexer_class /.$GJavaKWLexer./

$End

$Include
    LexerBasicMapF.gi
$End

--$Include
--    Differ.g
--$End

$Export

    IDENTIFIER

    IntegerLiteral
    LongLiteral
    FloatingPointLiteral
    DoubleLiteral
    CharacterLiteral
    StringLiteral
    PLUS_PLUS
    MINUS_MINUS
    EQUAL_EQUAL
    LESS_EQUAL
    GREATER_EQUAL
    NOT_EQUAL
    LEFT_SHIFT
    RIGHT_SHIFT
    UNSIGNED_RIGHT_SHIFT
    PLUS_EQUAL
    MINUS_EQUAL
    MULTIPLY_EQUAL
    DIVIDE_EQUAL
    AND_EQUAL
    OR_EQUAL
    XOR_EQUAL
    REMAINDER_EQUAL
    LEFT_SHIFT_EQUAL
    RIGHT_SHIFT_EQUAL
    UNSIGNED_RIGHT_SHIFT_EQUAL
    OR_OR
    AND_AND
    PLUS
    MINUS
    NOT
    REMAINDER
    XOR
    AND
    MULTIPLY
    OR
    TWIDDLE
    DIVIDE
    GREATER
    LESS
    LPAREN
    RPAREN
    LBRACE
    RBRACE
    LBRACKET
    RBRACKET
    SEMICOLON
    QUESTION
    AT
    COLON
    COMMA
    DOT
    EQUAL
    ELLIPSIS

$End

$Terminals
    CtlCharNotWS

    LF   CR   HT   FF

    a    b    c    d    e    f    g    h    i    j    k    l    m
    n    o    p    q    r    s    t    u    v    w    x    y    z
    _

    A    B    C    D    E    F    G    H    I    J    K    L    M
    N    O    P    Q    R    S    T    U    V    W    X    Y    Z

    0    1    2    3    4    5    6    7    8    9

    AfterASCII   ::= '\u0080..\ufffe'
    Space        ::= ' '
    LF           ::= NewLine
    CR           ::= Return
    HT           ::= HorizontalTab
    FF           ::= FormFeed
    DoubleQuote  ::= '"'
    SingleQuote  ::= "'"
    Percent      ::= '%'
    VerticalBar  ::= '|'
    Exclamation  ::= '!'
    AtSign       ::= '@'
    BackQuote    ::= '`'
    Tilde        ::= '~'
    Sharp        ::= '#'
    DollarSign   ::= '$'
    Ampersand    ::= '&'
    Caret        ::= '^'
    Colon        ::= ':'
    SemiColon    ::= ';'
    BackSlash    ::= '\'
    LeftBrace    ::= '{'
    RightBrace   ::= '}'
    LeftBracket  ::= '['
    RightBracket ::= ']'
    QuestionMark ::= '?'
    Comma        ::= ','
    Dot          ::= '.'
    LessThan     ::= '<'
    GreaterThan  ::= '>'
    Plus         ::= '+'
    Minus        ::= '-'
    Slash        ::= '/'
    Star         ::= '*'
    LeftParen    ::= '('
    RightParen   ::= ')'
    Equal        ::= '='

$End

%Notice
/.
////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2007 IBM Corporation.
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// which accompanies this distribution, and is available at
// http://www.eclipse.org/legal/epl-v10.html
//
//Contributors:
//    Philippe Charles (pcharles@us.ibm.com) - initial API and implementation

////////////////////////////////////////////////////////////////////////////////
./
%End

$Rules

    Token ::= Identifier
        /.$BeginAction
                    checkForKeyWord();
          $EndAction
        ./
    Token ::= '"' SLBody '"'
        /.$BeginAction
                    makeToken($_StringLiteral);
          $EndAction
        ./
    Token ::= "'" NotSQ "'"
        /.$BeginAction
                    makeToken($_CharacterLiteral);
          $EndAction
        ./
    Token ::= IntegerLiteral
        /.$BeginAction
                    makeToken($_IntegerLiteral);
          $EndAction
        ./
    Token ::= FloatingPointLiteral
        /.$BeginAction
                    makeToken($_FloatingPointLiteral);
          $EndAction
        ./
    Token ::= DoubleLiteral
        /.$BeginAction
                    makeToken($_DoubleLiteral);
          $EndAction
        ./
    Token ::= '/' '*' Inside Stars '/'
        /.$BeginAction
                    skipToken();
          $EndAction
        ./
    Token ::= SLC
        /.$BeginAction
                    skipToken();
          $EndAction
        ./
    Token ::= WS -- White Space is scanned but not added to output vector
        /.$BeginAction
                    skipToken();
          $EndAction
        ./
    Token ::= '+'
        /.$BeginAction
                    makeToken($_PLUS);
          $EndAction
        ./
    Token ::= '-'
        /.$BeginAction
                    makeToken($_MINUS);
          $EndAction
        ./

    Token ::= '*'
        /.$BeginAction
                    makeToken($_MULTIPLY);
          $EndAction
        ./

    Token ::= '/'
        /.$BeginAction
                    makeToken($_DIVIDE);
          $EndAction
        ./

    Token ::= '('
        /.$BeginAction
                    makeToken($_LPAREN);
          $EndAction
        ./

    Token ::= ')'
        /.$BeginAction
                    makeToken($_RPAREN);
          $EndAction
        ./

    Token ::= '='
        /.$BeginAction
                    makeToken($_EQUAL);
          $EndAction
        ./

    Token ::= ','
        /.$BeginAction
                    makeToken($_COMMA);
          $EndAction
        ./

    Token ::= ':'
        /.$BeginAction
                    makeToken($_COLON);
          $EndAction
        ./

    Token ::= ';'
        /.$BeginAction
                    makeToken($_SEMICOLON);
          $EndAction
        ./

    Token ::= '^'
        /.$BeginAction
                    makeToken($_XOR);
          $EndAction
        ./

    Token ::= '%'
        /.$BeginAction
                    makeToken($_REMAINDER);
          $EndAction
        ./

    Token ::= '~'
        /.$BeginAction
                    makeToken($_TWIDDLE);
          $EndAction
        ./

    Token ::= '|'
        /.$BeginAction
                    makeToken($_OR);
          $EndAction
        ./

    Token ::= '&'
        /.$BeginAction
                    makeToken($_AND);
          $EndAction
        ./

    Token ::= '<'
        /.$BeginAction
                    makeToken($_LESS);
          $EndAction
        ./

    Token ::= '>'
        /.$BeginAction
                    makeToken($_GREATER);
          $EndAction
        ./

    Token ::= '.'
        /.$BeginAction
                    makeToken($_DOT);
          $EndAction
        ./

    Token ::= '!'
        /.$BeginAction
                    makeToken($_NOT);
          $EndAction
        ./

    Token ::= '['
        /.$BeginAction
                    makeToken($_LBRACKET);
          $EndAction
        ./

    Token ::= ']'
        /.$BeginAction
                    makeToken($_RBRACKET);
          $EndAction
        ./

    Token ::= '{'
        /.$BeginAction
                    makeToken($_LBRACE);
          $EndAction
        ./

    Token ::= '}'
        /.$BeginAction
                    makeToken($_RBRACE);
          $EndAction
        ./

    Token ::= '?'
        /.$BeginAction
                    makeToken($_QUESTION);
          $EndAction
        ./

    Token ::= '@'
        /.$BeginAction
                    makeToken($_AT);
          $EndAction
        ./

    Token ::= '+' '+'
        /.$BeginAction
                    makeToken($_PLUS_PLUS);
          $EndAction
        ./

    Token ::= '-' '-'
        /.$BeginAction
                    makeToken($_MINUS_MINUS);
          $EndAction
        ./

    Token ::= '=' '='
        /.$BeginAction
                    makeToken($_EQUAL_EQUAL);
          $EndAction
        ./

    Token ::= '<' '='
        /.$BeginAction
                    makeToken($_LESS_EQUAL);
          $EndAction
        ./

    Token ::= '!' '='
        /.$BeginAction
                    makeToken($_NOT_EQUAL);
          $EndAction
        ./

    Token ::= '<' '<'
        /.$BeginAction
                    makeToken($_LEFT_SHIFT);
          $EndAction
        ./

    Token ::= '+' '='
        /.$BeginAction
                    makeToken($_PLUS_EQUAL);
          $EndAction
        ./

    Token ::= '-' '='
        /.$BeginAction
                    makeToken($_MINUS_EQUAL);
          $EndAction
        ./

    Token ::= '*' '='
        /.$BeginAction
                    makeToken($_MULTIPLY_EQUAL);
          $EndAction
        ./

    Token ::= '/' '='
        /.$BeginAction
                    makeToken($_DIVIDE_EQUAL);
          $EndAction
        ./

    Token ::= '&' '='
        /.$BeginAction
                    makeToken($_AND_EQUAL);
          $EndAction
        ./

    Token ::= '|' '='
        /.$BeginAction
                    makeToken($_OR_EQUAL);
          $EndAction
        ./

    Token ::= '^' '='
        /.$BeginAction
                    makeToken($_XOR_EQUAL);
          $EndAction
        ./

    Token ::= '%' '='
        /.$BeginAction
                    makeToken($_REMAINDER_EQUAL);
          $EndAction
        ./

    Token ::= '<' '<' '='
        /.$BeginAction
                    makeToken($_LEFT_SHIFT_EQUAL);
          $EndAction
        ./

    Token ::= '|' '|'
        /.$BeginAction
                    makeToken($_OR_OR);
          $EndAction
        ./

    Token ::= '&' '&'
        /.$BeginAction
                    makeToken($_AND_AND);
          $EndAction
        ./

    Token ::= '.' '.' '.'
        /.$BeginAction
                    makeToken($_ELLIPSIS);
          $EndAction
        ./

    IntegerLiteral -> Integer
                    | Integer LetterLl
                    | '0' LetterXx HexDigits
                    | '0' LetterXx HexDigits LetterLl

    DoubleLiteral -> Decimal
                   | Decimal LetterForD
                   | Decimal Exponent
                   | Decimal Exponent LetterForD
                   | Integer Exponent
                   | Integer Exponent LetterForD
                   | Integer LetterForD

    FloatingPointLiteral -> Decimal LetterForF
                          | Decimal Exponent LetterForF
                          | Integer Exponent LetterForF
                          | Integer LetterForF

    Inside ::= Inside Stars NotSlashOrStar
             | Inside '/'
             | Inside NotSlashOrStar
             | $empty

    Stars -> '*'
           | Stars '*'

    SLC ::= '/' '/'
          | SLC NotEol

    SLBody -> $empty
            | SLBody NotDQ

    Integer -> Digit
             | Integer Digit

    HexDigits -> HexDigit
               | HexDigits HexDigit

    Decimal ::= '.' Integer
              | Integer '.'
              | Integer '.' Integer

    Exponent ::= LetterEe Integer
               | LetterEe '+' Integer
               | LetterEe '-' Integer

    WSChar -> Space
            | LF
            | CR
            | HT
            | FF

    Letter -> LowerCaseLetter
            | UpperCaseLetter
            | _
            | '$'
            | '\u0080..\ufffe'

    LowerCaseLetter -> a | b | c | d | e | f | g | h | i | j | k | l | m |
                       n | o | p | q | r | s | t | u | v | w | x | y | z

    UpperCaseLetter -> A | B | C | D | E | F | G | H | I | J | K | L | M |
                       N | O | P | Q | R | S | T | U | V | W | X | Y | Z

    Digit -> 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9

    OctalDigit -> 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7

    a..f -> a | b | c | d | e | f | A | B | C | D | E | F

    HexDigit -> Digit
              | a..f

    OctalDigits3 -> OctalDigit
                  | OctalDigit OctalDigit
                  | OctalDigit OctalDigit OctalDigit

    LetterForD -> 'D'
                | 'd'

    LetterForF -> 'F'
                | 'f'

    LetterLl ->  'L'
              | 'l'

    LetterEe -> 'E'
              | 'e'

    LetterXx -> 'X'
              | 'x'

    WS -> WSChar
        | WS WSChar

    Identifier -> Letter
                | Identifier Letter
                | Identifier Digit

    SpecialNotStar -> '+' | '-' | '/' | '(' | ')' | '"' | '!' | '@' | '`' | '~' |
                      '%' | '&' | '^' | ':' | ';' | "'" | '\' | '|' | '{' | '}' |
                      '[' | ']' | '?' | ',' | '.' | '<' | '>' | '=' | '#'

    SpecialNotSlash -> '+' | '-' | -- exclude the star as well
                       '(' | ')' | '"' | '!' | '@' | '`' | '~' |
                       '%' | '&' | '^' | ':' | ';' | "'" | '\' | '|' | '{' | '}' |
                       '[' | ']' | '?' | ',' | '.' | '<' | '>' | '=' | '#'

    SpecialNotDQ -> '+' | '-' | '/' | '(' | ')' | '*' | '!' | '@' | '`' | '~' |
                    '%' | '&' | '^' | ':' | ';' | "'" | '|' | '{' | '}' |
                    '[' | ']' | '?' | ',' | '.' | '<' | '>' | '=' | '#'

    SpecialNotSQ -> '+' | '-' | '*' | '(' | ')' | '"' | '!' | '@' | '`' | '~' |
                    '%' | '&' | '^' | ':' | ';' | '/' | '|' | '{' | '}' |
                    '[' | ']' | '?' | ',' | '.' | '<' | '>' | '=' | '#'

    NotSlashOrStar -> Letter
                    | Digit
                    | SpecialNotSlash
                    | WSChar

    Eol -> LF
         | CR

    NotEol -> Letter
            | Digit
            | Space
            | '*'
            | SpecialNotStar
            | HT
            | FF
            | CtlCharNotWS

    NotDQ -> Letter
           | Digit
           | SpecialNotDQ
           | Space
           | HT
           | FF
           | EscapeSequence
           | '\' u HexDigit HexDigit HexDigit HexDigit
           | '\' OctalDigit

    NotSQ -> Letter
           | Digit
           | SpecialNotSQ
           | Space
           | HT
           | FF
           | EscapeSequence
           | '\' u HexDigit HexDigit HexDigit HexDigit
           | '\' OctalDigits3

    EscapeSequence -> '\' b
                    | '\' t
                    | '\' n
                    | '\' f
                    | '\' r
                    | '\' '"'
                    | '\' "'"
                    | '\' '\'
$End


%Define
    $kw_lexer_class /.NoKWLexer./
    $_IDENTIFIER /.0./
%End
%Headers
    --
    -- Additional methods for the action class not provided in the template
    --
    /.
         public class NoKWLexer
        {
            public int[] getKeywordKinds() { return null; }

            public int lexer(int curtok, int lasttok) { return 0; }

            public void setInputChars(char[] inputChars) { }

             int getKind(int c) { return 0; }

            public NoKWLexer(char[] inputChars, int identifierKind) { }
        }
    ./
%End

%Import
    LexerBasicMapF.gi
%End


--
-- In a parser using this template, the following macro may be redefined:
--
--     $additional_interfaces
--     $ast_class
--
-- B E G I N N I N G   O F   T E M P L A T E   btParserTemplateF
--
%Options programming_language=rt_cpp,margin=4,backtrack
%Options table,error_maps,scopes
%options prefix=TK_
%options action-block=("*.h", "/.", "./")
%options action-block=("*.cpp", "/!", "!/")
%options ast-block=("/!", "!/")
%options ParseTable=ParseTable
%options nt-check

--
-- This template requires that the name of the EOF token be set
-- to EOF_TOKEN to be consistent with LexerTemplateD and LexerTemplateE
--
%EOF
    EOF_TOKEN
%End

%ERROR
    ERROR_TOKEN
%End

%Define

    $Header
    /.
                //
                // Rule $rule_number:  $rule_text
                //
                ./

    $BeginAction
    /!$Header$case $rule_number: {
                   //#line $next_line "$input_file$"!/

    $EndAction
    /!            break;
                }!/

    $BeginJava
    /!$Header$case $rule_number: {
                    $symbol_declarations
                    //#line $next_line "$input_file$"!/

    $EndJava /!$EndAction!/

    $NoAction
    /!$Header$case $rule_number:
                    break;!/

    $BadAction
    /!$Header$case $rule_number:
                    throw  std::exception("No action specified for rule " + $rule_number);!/

    $NullAction
    /!$Header$case $rule_number:
                    setResult(nullptr);
                    break;!/

    $BeginActions
    /!
         #include "$action_type.h"
         void $action_type::ruleAction(int ruleNumber)
        {
            switch (ruleNumber)
            {!/

    $SplitActions
    /!
                    default:
                        ruleAction$rule_number(ruleNumber);
                        break;
                }
                return;
            }

             void ruleAction$rule_number(int ruleNumber)
            {
                switch (ruleNumber)
                {
                    //#line $next_line "$input_file$"!/

    $EndActions
    /!
                default:
                    break;
            }
            return;
        }!/

    $entry_declarations
    /.
         $ast_class * parse$entry_name()
        {
            return parse$entry_name(nullptr, 0);
        }

         $ast_class * parse$entry_name(Monitor* monitor)
        {
            return parse$entry_name(monitor, 0);
        }

         $ast_class * parse$entry_name(int error_repair_count)
        {
            return parse$entry_name(nullptr, error_repair_count);
        }

         $ast_class * parse$entry_name(Monitor *monitor, int error_repair_count)
        {
            btParser->setMonitor(monitor);

            try
            {
                return ($ast_class *) btParser->fuzzyParseEntry($sym_type::$entry_marker, error_repair_count);
            }
            catch (BadParseException& e)
            {
                prsStream->reset(e.error_token); // point to error token

                 std::shared_ptr< DiagnoseParser> diagnoseParser = std::make_shared<DiagnoseParser>(prsStream, prsTable);
                diagnoseParser->diagnoseEntry($sym_type::$entry_marker, e.error_token);
            }

            return nullptr;
        }
    ./

    --
    -- Macros that may be needed in a parser using this template
    --
    $additional_interfaces /../
    $ast_class /.$ast_type./
    $super_class /.Object./
    $unimplemented_symbols_warning /.false./

    --
    -- Old deprecated macros that should NEVER be used.
    --
    $setSym1 /. // macro setSym1 is deprecated. Use function setResult
                getParser().setSym1./
    $setResult /. // macro setResult is deprecated. Use function setResult
                 getParser().setSym1./
    $getSym /. // macro getSym is deprecated. Use function getRhsSym
              getParser().getSym./
    $getToken /. // macro getToken is deprecated. Use function getRhsTokenIndex
                getParser().getToken./
    $getIToken /. // macro getIToken is deprecated. Use function getRhsIToken
                 prsStream->getIToken./
    $getLeftSpan /. // macro getLeftSpan is deprecated. Use function getLeftSpan
                   getParser().getFirstToken./
    $getRightSpan /. // macro getRightSpan is deprecated. Use function getRightSpan
                    getParser().getLastToken./
%End

%Globals
    /.
#pragma once

#include <iostream>
#include "AstPoolHolder.h"
#include "BacktrackingParser.h"
#include "DeterministicParser.h"
#include "diagnose.h"
#include "ErrorToken.h"
#include "Exception.h"
#include "IAbstractArrayList.h"
#include "IAst.h"
#include "IAstVisitor.h"
#include "ILexStream.h"
#include "$sym_type.h"
#include "$prs_type.h"
#include "Object.h"
#include "ParseTable.h"
#include "PrsStream.h"
#include "RuleAction.h"
#include "IcuUtil.h"
#include "stringex.h"
#include "Any.h"
    ./
%End

%Headers
    /.
     struct $action_type :public $super_class ,public RuleAction$additional_interfaces
    {

        PrsStream* prsStream = nullptr;
        ~$action_type (){
            delete prsStream;
            delete btParser;
        }
         bool unimplementedSymbolsWarning = $unimplemented_symbols_warning;

         inline static ParseTable* prsTable = new $prs_type();
         ParseTable* getParseTable() { return prsTable; }

         BacktrackingParser* btParser = nullptr;
         BacktrackingParser* getParser() { return btParser; }

         void setResult(Object* object) { btParser->setSym1(object); }
         Object* getRhsSym(int i) { return btParser->getSym(i); }

         int getRhsTokenIndex(int i) { return btParser->getToken(i); }
         IToken* getRhsIToken(int i) { return prsStream->getIToken(getRhsTokenIndex(i)); }

         int getRhsFirstTokenIndex(int i) { return btParser->getFirstToken(i); }
         IToken* getRhsFirstIToken(int i) { return prsStream->getIToken(getRhsFirstTokenIndex(i)); }

         int getRhsLastTokenIndex(int i) { return btParser->getLastToken(i); }
         IToken* getRhsLastIToken(int i) { return prsStream->getIToken(getRhsLastTokenIndex(i)); }

         int getLeftSpan() { return btParser->getFirstToken(); }
         IToken* getLeftIToken()  { return prsStream->getIToken(getLeftSpan()); }

         int getRightSpan() { return btParser->getLastToken(); }
         IToken* getRightIToken() { return prsStream->getIToken(getRightSpan()); }

         int getRhsErrorTokenIndex(int i)
        {
            int index = btParser->getToken(i);
            IToken* err = prsStream->getIToken(index);
            return ( dynamic_cast<ErrorToken*>(err) ? index : 0);
        }
         ErrorToken * getRhsErrorIToken(int i)
        {
            int index = btParser->getToken(i);
            IToken* err = prsStream->getIToken(index);
            return (ErrorToken*) ( dynamic_cast<ErrorToken*>(err) ? err : nullptr);
        }

         void reset(ILexStream* lexStream)
        {
            delete prsStream;
            prsStream = new PrsStream(lexStream);
            btParser->reset(prsStream);

            try
            {
                prsStream->remapTerminalSymbols(orderedTerminalSymbols(), prsTable->getEoftSymbol());
            }
            catch (NullExportedSymbolsException& e) {
            }
            catch (NullTerminalSymbolsException& e) {
            }
            catch (UnimplementedTerminalsException& e)
            {
                if (unimplementedSymbolsWarning) {
                   auto unimplemented_symbols = e.getSymbols();
                    std::cout << "The Lexer will not scan the following token(s):" << std::endl;
                    for (int i = 0; i < unimplemented_symbols.size(); i++)
                    {
                        auto id = unimplemented_symbols.at(i);
                        std::wcout <<L"    " << $sym_type::orderedTerminalSymbols[id] << std::endl;
                    }
                   std::cout <<std::endl;
                }
            }
            catch (UndefinedEofSymbolException& e)
            {
                std::stringex str= "The Lexer does not implement the Eof symbol ";
                str += IcuUtil::ws2s($sym_type::orderedTerminalSymbols[prsTable->getEoftSymbol()]);
                throw  UndefinedEofSymbolException(str);
            }
        }

         $action_type(ILexStream* lexStream = nullptr)
        {
            try
            {
                btParser = new BacktrackingParser(prsStream, prsTable,  this);
            }
            catch (NotBacktrackParseTableException& e)
            {
                throw ( NotBacktrackParseTableException
                                    ("Regenerate $prs_type.java with -BACKTRACK option"));
            }
            catch (BadParseSymFileException& e)
            {
                throw ( BadParseSymFileException("Bad Parser Symbol File -- $sym_type::java"));
            }

            if(lexStream)
            {
                reset(lexStream);
            }
        }

         int numTokenKinds() { return $sym_type::numTokenKinds; }
         std::vector<std::wstring> orderedTerminalSymbols() {
             return $sym_type::orderedTerminalSymbols;
        }
         std::wstring getTokenKindName(int kind) { return $sym_type::orderedTerminalSymbols[kind]; }
         int getEOFTokenKind() { return prsTable->getEoftSymbol(); }
         IPrsStream* getIPrsStream() { return prsStream; }

        /**
         * @deprecated replaced by {@link #getIPrsStream()}
         *
         */
         PrsStream* getPrsStream() { return prsStream; }

        /**
         * @deprecated replaced by {@link #getIPrsStream()}
         *
         */
         PrsStream* getParseStream() { return prsStream; }

         $ast_class* parser()
        {
            return parser(nullptr, 0);
        }

         $ast_class* parser(Monitor* monitor)
        {
            return parser(monitor, 0);
        }

         $ast_class * parser(int error_repair_count)
        {
            return parser(nullptr, error_repair_count);
        }

         $ast_class * parser(Monitor* monitor, int error_repair_count)
        {
            btParser->setMonitor(monitor);

            try
            {
                return ($ast_class *) btParser->fuzzyParse(error_repair_count);
            }
            catch (BadParseException& e)
            {
                prsStream->reset(e.error_token); // point to error token

                std::shared_ptr< DiagnoseParser> diagnoseParser = std::make_shared<DiagnoseParser>(prsStream, prsTable);
                diagnoseParser->diagnose(e.error_token);
            }

            return nullptr;
        }
         void ruleAction(int ruleNumber);
        //
        // Additional entry points, if any
        //
        $entry_declarations
    ./

%End

%Rules
    /!$BeginActions!/
%End

%Trailers
    /.
    };
    ./

     /!
        $EndActions
    !/
%End

--
-- E N D   O F   T E M P L A T E
--


--
-- In a parser using this template, the following macro may be redefined:
--
--     $additional_interfaces
--     $ast_class
--
-- B E G I N N I N G   O F   T E M P L A T E   btParserTemplateF
--
%Options programming_language=csharp,margin=4,backtrack
%Options table,error_maps,scopes
%options prefix=TK_
%options action-block=("*.cs", "/.", "./")
%options ParseTable=LPG2.Runtime.ParseTable
%options nt-check

--
-- This template requires that the name of the EOF token be set
-- to EOF_TOKEN to be consistent with LexerTemplateD and LexerTemplateE
--
%EOF
    EOF_TOKEN
%End

%ERROR
    ERROR_TOKEN
%End

%Define

    $Header
    /.
                //
                // Rule $rule_number:  $rule_text
                //
                ./

    $BeginAction
    /.$Header$case $rule_number: {
                   //#line $next_line "$input_file$"./

    $EndAction
    /.            break;
                }./

    $BeginJava
    /.$Header$case $rule_number: {
                    $symbol_declarations
                    //#line $next_line "$input_file$"./

    $EndJava /.$EndAction./

    $NoAction
    /.$Header$case $rule_number:
                    break;./

    $BadAction
    /.$Header$case $rule_number:
                    throw ("No action specified for rule " + $rule_number);./

    $NullAction
    /.$Header$case $rule_number:
                    setResult(null);
                    break;./

    $BeginActions
    /.
         // Casting object to various generic types
        public void ruleAction(int ruleNumber)
        {
            switch (ruleNumber)
            {./

    $SplitActions
    /.
                    default:
                        ruleAction$rule_number(ruleNumber);
                        break;
                }
                return;
            }

            public void ruleAction$rule_number(int ruleNumber)
            {
                switch (ruleNumber)
                {
                    //#line $next_line "$input_file$"./

    $EndActions
    /.
                default:
                    break;
            }
            return;
        }./

    $entry_declarations
    /.
        public $ast_class parse$entry_name()
        {
            return parse$entry_name(null, 0);
        }

        public $ast_class parse$entry_name(Monitor monitor)
        {
            return parse$entry_name(monitor, 0);
        }

        public $ast_class parse$entry_name(int error_repair_count)
        {
            return parse$entry_name(null, error_repair_count);
        }

        public $ast_class parse$entry_name(Monitor monitor, int error_repair_count)
        {
            btParser.setMonitor(monitor);

            try
            {
                return ($ast_class) btParser.fuzzyParseEntry($sym_type.$entry_marker, error_repair_count);
            }
            catch (BadParseException e)
            {
                prsStream.reset(e.error_token); // point to error token

                DiagnoseParser diagnoseParser = new DiagnoseParser(prsStream, prsTable);
                diagnoseParser.diagnoseEntry($sym_type.$entry_marker, e.error_token);
            }

            return null;
        }
    ./

    --
    -- Macros that may be needed in a parser using this template
    --
    $additional_interfaces /../
    $ast_class /.$ast_type./
    $super_class /.object./
    $unimplemented_symbols_warning /.false./

    --
    -- Old deprecated macros that should NEVER be used.
    --
    $setSym1 /. // macro setSym1 is deprecated. Use function setResult
                getParser().setSym1./
    $setResult /. // macro setResult is deprecated. Use function setResult
                 getParser().setSym1./
    $getSym /. // macro getSym is deprecated. Use function getRhsSym
              getParser().getSym./
    $getToken /. // macro getToken is deprecated. Use function getRhsTokenIndex
                getParser().getToken./
    $getIToken /. // macro getIToken is deprecated. Use function getRhsIToken
                 prsStream.getIToken./
    $getLeftSpan /. // macro getLeftSpan is deprecated. Use function getLeftSpan
                   getParser().getFirstToken./
    $getRightSpan /. // macro getRightSpan is deprecated. Use function getRightSpan
                    getParser().getLastToken./
%End

%Globals
    /.
    using  LPG2.Runtime;
    using System;
    ./
%End

%Headers
    /.
    public class $action_type : $super_class , RuleAction$additional_interfaces
    {
        private PrsStream prsStream = null;

        private bool unimplementedSymbolsWarning = $unimplemented_symbols_warning;

        private static ParseTable prsTable = new $prs_type();
        public ParseTable getParseTable() { return prsTable; }

        private BacktrackingParser btParser = null;
        public BacktrackingParser getParser() { return btParser; }

        private void setResult(object _object) { btParser.setSym1(_object); }
        public object getRhsSym(int i) { return btParser.getSym(i); }

        public int getRhsTokenIndex(int i) { return btParser.getToken(i); }
        public IToken getRhsIToken(int i) { return prsStream.getIToken(getRhsTokenIndex(i)); }

        public int getRhsFirstTokenIndex(int i) { return btParser.getFirstToken(i); }
        public IToken getRhsFirstIToken(int i) { return prsStream.getIToken(getRhsFirstTokenIndex(i)); }

        public int getRhsLastTokenIndex(int i) { return btParser.getLastToken(i); }
        public IToken getRhsLastIToken(int i) { return prsStream.getIToken(getRhsLastTokenIndex(i)); }

        public int getLeftSpan() { return btParser.getFirstToken(); }
        public IToken getLeftIToken()  { return prsStream.getIToken(getLeftSpan()); }

        public int getRightSpan() { return btParser.getLastToken(); }
        public IToken getRightIToken() { return prsStream.getIToken(getRightSpan()); }

        public int getRhsErrorTokenIndex(int i)
        {
            int index = btParser.getToken(i);
            IToken err = prsStream.getIToken(index);
            return (err is ErrorToken ? index : 0);
        }
        public ErrorToken getRhsErrorIToken(int i)
        {
            int index = btParser.getToken(i);
            IToken err = prsStream.getIToken(index);
            return (ErrorToken) (err is ErrorToken ? err : null);
        }

        public void reset(ILexStream lexStream)
        {
            prsStream = new PrsStream(lexStream);
            btParser.reset(prsStream);

            try
            {
                prsStream.remapTerminalSymbols(orderedTerminalSymbols(), prsTable.getEoftSymbol());
            }
            catch (NullExportedSymbolsException e) {
            }
            catch (NullTerminalSymbolsException e) {
            }
            catch (UnimplementedTerminalsException e)
            {
                if (unimplementedSymbolsWarning) {
                    ArrayListHelper<int> unimplemented_symbols =  new ArrayListHelper<int>( e.getSymbols());
                    Console.Out.WriteLine("The Lexer will not scan the following token(s):");
                    for (int i = 0; i < unimplemented_symbols.Count; i++)
                    {
                        int  id = unimplemented_symbols.get(i);
                        Console.Out.WriteLine("    " + $sym_type.orderedTerminalSymbols[id]);
                    }
                    Console.Out.WriteLine();
                }
            }
            catch (UndefinedEofSymbolException e)
            {
                throw (new UndefinedEofSymbolException
                                    ("The Lexer does not implement the Eof symbol " +
                                     $sym_type.orderedTerminalSymbols[prsTable.getEoftSymbol()]));
            }
        }

        public $action_type()
        {
            try
            {
                btParser = new BacktrackingParser(prsStream, prsTable, (RuleAction) this);
            }
            catch (NotBacktrackParseTableException e)
            {
                throw (new NotBacktrackParseTableException
                                    ("Regenerate $prs_type.cs with -BACKTRACK option"));
            }
            catch (BadParseSymFileException e)
            {
                throw (new BadParseSymFileException("Bad Parser Symbol File -- $sym_type.cs"));
            }
        }

        public $action_type(ILexStream lexStream):this()
        {

            reset(lexStream);
        }

        public int numTokenKinds() { return $sym_type.numTokenKinds; }
        public string[] orderedTerminalSymbols() { return $sym_type.orderedTerminalSymbols; }
        public string getTokenKindName(int kind) { return $sym_type.orderedTerminalSymbols[kind]; }
        public int getEOFTokenKind() { return prsTable.getEoftSymbol(); }
        public IPrsStream getIPrsStream() { return prsStream; }

        /**
         * @deprecated replaced by {@link #getIPrsStream()}
         *
         */
        public PrsStream getPrsStream() { return prsStream; }

        /**
         * @deprecated replaced by {@link #getIPrsStream()}
         *
         */
        public PrsStream getParseStream() { return prsStream; }

        public $ast_class parser()
        {
            return parser(null, 0);
        }

        public $ast_class parser(Monitor monitor)
        {
            return parser(monitor, 0);
        }

        public $ast_class parser(int error_repair_count)
        {
            return parser(null, error_repair_count);
        }

        public $ast_class parser(Monitor monitor, int error_repair_count)
        {
            btParser.setMonitor(monitor);

            try
            {
                return ($ast_class) btParser.fuzzyParse(error_repair_count);
            }
            catch (BadParseException e)
            {
                prsStream.reset(e.error_token); // point to error token

                DiagnoseParser diagnoseParser = new DiagnoseParser(prsStream, prsTable);
                diagnoseParser.diagnose(e.error_token);
            }

            return null;
        }

        //
        // Additional entry points, if any
        //
        $entry_declarations
    ./

%End

%Rules
    /.$BeginActions./
%End

%Trailers
    /.
        $EndActions
    }
    ./
%End

--
-- E N D   O F   T E M P L A T E
--


>1apf
GVPCLCDSDGPRPRGNTLSGILWFYPSGCPS2GWH1NCKAHGPNIGWCCKK2
>1ahl
GVSCLCDSDGPSVRGNTLSGTLWLYPSGCPS2GWH1NCKAHGPTIGWCCKQ2
>1atx
GAACLCKSDGPNTRGNSMSGTIWVF2GCPS2GWN1NCEGRA1IIGYCCKQ2
>1sh1
1AACKCDDEGPDIRTAPLTGTVDLG2SCNA2GWE1KCASYYTIIADCCRKKK
>1bds
AAPCFCSGKP7GRGDLWILRGTCPGGYGYTSNCYK2WPNICCYPH2


--
-- The Java Lexer
--
%Options fp=CncLexer
%options single-productions
%options package=CnCParser
%options template=LexerTemplateF.gi
%options filter=cncKWLexer.gi

%Notice
/.
//
// This file is part of the CNC-C implementation and
// distributed under the Modified BSD License.
// See LICENSE for details.
//
// I AM A GENERATED FILE. PLEASE DO NOT CHANGE ME!!!
//
./
%End

%Define
    --
    -- Definition of macro used in the included file LexerBasicMapB.g
    --
    $kw_lexer_class /.$cncKWLexer./
    $_IDENTIFIER    /.$_T_NAME./

%End

%Include
    LexerBasicMapF.gi
%End

%Export

    T_NAME
    T_NUMBER
    T_QUOTEDVAL

    SEMICOLON
    RIGHT_ARROW
    LEFT_ARROW
    COLON_COLON
    COMMA
    LESS_THAN
    GREATER_THAN
    COLON
    LEFT_PARENTHESIS
    RIGHT_PARENTHESIS
    LEFT_BRACKET
    RIGHT_BRACKET
    LEFT_BRACE
    RIGHT_BRACE
    EQUAL
    AMPERSAND
    STAR
    DOT
    DOT_DOT
    PLUS
    MINUS
    SLASH
    SHARP
    ATSIGN
	--UNSIGNED
    --STRUCT

%End

%Terminals
    CtlCharNotWS

    LF   CR   HT   FF

    a    b    c    d    e    f    g    h    i    j    k    l    m
    n    o    p    q    r    s    t    u    v    w    x    y    z
    _

    A    B    C    D    E    F    G    H    I    J    K    L    M
    N    O    P    Q    R    S    T    U    V    W    X    Y    Z

    0    1    2    3    4    5    6    7    8    9

    AfterASCII   ::= '\u0080..\ufffe'
    Space        ::= ' '
    LF           ::= NewLine
    CR           ::= Return
    HT           ::= HorizontalTab
    FF           ::= FormFeed
    DoubleQuote  ::= '"'
    SingleQuote  ::= "'"
    Percent      ::= '%'
    VerticalBar  ::= '|'
    Exclamation  ::= '!'
    AtSign       ::= '@'
    BackQuote    ::= '`'
    Tilde        ::= '~'
    Sharp        ::= '#'
    DollarSign   ::= '$'
    Ampersand    ::= '&'
    Caret        ::= '^'
    Colon        ::= ':'
    SemiColon    ::= ';'
    BackSlash    ::= '\'
    LeftBrace    ::= '{'
    RightBrace   ::= '}'
    LeftBracket  ::= '['
    RightBracket ::= ']'
    QuestionMark ::= '?'
    Comma        ::= ','
    Dot          ::= '.'
    LessThan     ::= '<'
    GreaterThan  ::= '>'
    Plus         ::= '+'
    Minus        ::= '-'
    Slash        ::= '/'
    Star         ::= '*'
    LeftParen    ::= '('
    RightParen   ::= ')'
    Equal        ::= '='
    -- Unsigned	 ::= "unsigned"
    -- Struct		 ::= "struct"

%End

%Start
    Token
%End

%Rules

    ---------------------  Rules for Scanned Tokens --------------------------------
    -- The lexer creates an array list of tokens which is defined in the PrsStream class.
    -- A token has three attributes: a start offset, an end offset and a kind.
    --
    -- Only rules that produce complete tokens have actions to create token objects.
    -- When making a token, calls to the methods, $getToken(1) and $getRightSpan(),
    -- provide the offsets (i.e. the span) of a rule's right hand side (rhs) and thus of the token.
    -- For a rule of the form A ::= A1 A2 ... An, the start offset of the rhs of A is given by
    -- $getToken(1) or by $getLeftSpan() and the end offset by $getRightSpan().
    --
    -- Regarding rules for parsing in general, note that for a rhs symbol Ai, the
    -- method $getToken(i) returns the location of the leftmost character derived from Ai.
    -- The method $getLeftSpan(i) returns the same location unless Ai produces %Empty in which case
    -- it returns the location of the last character derived before reducing Ai to %Empty.
    -- The method $getRightSpan(i) returns the location of the rightmost character derived from Ai
    -- unless Ai produces %Empty in which case it returns the location of the last character
    -- derived before reducing Ai to %Empty.
    --------------------------------------------------------------------------------
    Token ::= ';'
        /.
                    makeToken($_SEMICOLON);
        ./

    Token ::= '-' '>'
        /.
                    makeToken($_RIGHT_ARROW);
        ./

    Token ::= '<' '-'
        /.
                    makeToken($_LEFT_ARROW);
        ./

    Token ::= ':' ':'
        /.
                    makeToken($_COLON_COLON);
        ./

    Token ::= ','
        /.
                    makeToken($_COMMA);
        ./

    Token ::= '<'
        /.
                    makeToken($_LESS_THAN);
        ./

    Token ::= '>'
        /.
                    makeToken($_GREATER_THAN);
        ./

    Token ::= ':'
        /.
                    makeToken($_COLON);
        ./

    Token ::= '('
        /.
                    makeToken($_LEFT_PARENTHESIS);
        ./

    Token ::= ')'
        /.
                    makeToken($_RIGHT_PARENTHESIS);
        ./

    Token ::= '['
        /.
                    makeToken($_LEFT_BRACKET);
        ./

    Token ::= ']'
        /.
                    makeToken($_RIGHT_BRACKET);
        ./

	Token ::= '{'
        /.
                    makeToken($_LEFT_BRACE);
        ./

    Token ::= '}'
        /.
                    makeToken($_RIGHT_BRACE);
        ./

    Token ::= '='
        /.
                    makeToken($_EQUAL);
        ./

	Token ::= '@'
        /.
                    makeToken($_ATSIGN);
        ./

    Token ::= Identifier
        /.
                    checkForKeyWord();
        ./

    Token ::= '&'
        /.
                    makeToken($_AMPERSAND);
        ./

    Token ::= '*'
        /.
                    makeToken($_STAR);
        ./

    Token ::= '/'
        /.
                    makeToken($_SLASH);
        ./

	Token ::= '+'
        /.
                    makeToken($_PLUS);
        ./

    Token ::= '-'
        /.
                    makeToken($_MINUS);
        ./

    Token ::= '.'
        /.
                    makeToken($_DOT);
        ./

	Token ::= '.' '.'
        /.
                    makeToken($_DOT_DOT);
        ./

   	Token ::= '#'
        /.
                    makeToken($_SHARP);
        ./
    --Token ::= 'u' 'n' 's' 'i' 'g' 'n' 'e' 'd'
      --  /.
       --             makeToken($_UNSIGNED);
       -- ./
    --Token ::= 's' 't' 'r' 'u' 'c' 't'
      --  /.
        --            makeToken($_STRUCT);
        --./

    Token ::= '"' SLBody '"'
        /.
                    makeToken($_T_QUOTEDVAL);
        ./

    Token ::= '"' SLBody Eol -- TODO: remove the Eol from the string
        /.
                    makeToken($_T_QUOTEDVAL);
        ./

    Token ::= Integer
        /.
                    makeToken($_T_NUMBER);
        ./
    Token ::= WS -- White Space is scanned but not added to output vector
        /.
                    skipToken();
        ./

    Token ::= SLC
        /.
                    skipToken();
        ./

    SLBody ::= %Empty
             | SLBody NotDQ

    SLC ::= '/' '/'
          | SLC NotEol

    NotEol -> Letter
            | Digit
            | Special
            | Space
            | HT
            | FF
            | CtlCharNotWS

    Special -> '+' | '-' | '*' | '/' | '(' | ')' | '"' | '!' | '@' | '`' | '~' |
               '%' | '&' | '^' | ':' | ';' | "'" | '\' | '|' | '{' | '}' |
               '[' | ']' | '?' | ',' | '.' | '<' | '>' | '=' | '#'

    SpecialNotDQ -> '+' | '-' | '*' | '/' | '(' | ')' | '!' | '@' | '`' | '~' |
                    '%' | '&' | '^' | ':' | ';' | "'" | '\' | '|' | '{' | '}' |
                    '[' | ']' | '?' | ',' | '.' | '<' | '>' | '=' | '#'

    Integer -> Digit
             | Integer Digit

    WSChar -> Space
            | Eol
            | HT
            | FF

    Eol -> LF
         | CR

    Letter -> LowerCaseLetter
            | UpperCaseLetter
            | _
            | '$'
            | '\u0080..\ufffe'

    LowerCaseLetter -> a | b | c | d | e | f | g | h | i | j | k | l | m |
                       n | o | p | q | r | s | t | u | v | w | x | y | z

    UpperCaseLetter -> A | B | C | D | E | F | G | H | I | J | K | L | M |
                       N | O | P | Q | R | S | T | U | V | W | X | Y | Z

    Digit -> 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9

    WS -> WSChar
        | WS WSChar

    Identifier -> Letter
                | Identifier Letter
                | Identifier Digit

    NotDQ -> Letter
           | Digit
           | SpecialNotDQ
           | Space
           | HT
           | FF
%End