%Terminals
    u0000
    u0001
    u0002
    u0003
    u0004
    u0005
    u0006
    u0007
    u0008
    u0009 -- HT
    u000A -- LF
    u000B
    u000C -- FF
    u000D -- CR
    u000E
    u000F
    u0010
    u0011
    u0012
    u0013
    u0014
    u0015
    u0016
    u0017
    u0018
    u0019
    u001A
    u001B
    u001C
    u001D
    u001E
    u001F
    u0020 ::= ' '
    u0021 ::= '!'
    u0022 ::= '"'
    u0023 ::= '%'
    u0024 ::= '%'
    u0025 ::= '%'
    u0026 ::= '&'
    u0027 ::= "'"
    u0028 ::= '('
    u0029 ::= ')'
    u002A ::= '*'
    u002B ::= '+'
    u002C ::= ','
    u002D ::= '-'
    u002E ::= '.'
    u002F ::= '/'
    u0030 ::= '0'
    u0031 ::= '1'
    u0032 ::= '2'
    u0033 ::= '3'
    u0034 ::= '4'
    u0035 ::= '5'
    u0036 ::= '6'
    u0037 ::= '7'
    u0038 ::= '8'
    u0039 ::= '9'
    u003A ::= ':'
    u003B ::= ';'
    u003C ::= '<'
    u003D ::= '='
    u003E ::= '>'
    u003F ::= '?'
    u0040 ::= '@'
    u0041 ::= 'A'
    u0042 ::= 'B'
    u0043 ::= 'C'
    u0044 ::= 'D'
    u0045 ::= 'E'
    u0046 ::= 'F'
    u0047 ::= 'G'
    u0048 ::= 'H'
    u0049 ::= 'I'
    u004A ::= 'J'
    u004B ::= 'K'
    u004C ::= 'L'
    u004D ::= 'M'
    u004E ::= 'N'
    u004F ::= 'O'
    u0050 ::= 'P'
    u0051 ::= 'Q'
    u0052 ::= 'R'
    u0053 ::= 'S'
    u0054 ::= 'T'
    u0055 ::= 'U'
    u0056 ::= 'V'
    u0057 ::= 'W'
    u0058 ::= 'X'
    u0059 ::= 'Y'
    u005A ::= 'Z'
    u005B ::= '['
    u005C ::= '\'
    u005D ::= ']'
    u005E ::= '^'
    u005F ::= '_'
    u0060 ::= '`'
    u0061 ::= 'a'
    u0062 ::= 'b'
    u0063 ::= 'c'
    u0064 ::= 'd'
    u0065 ::= 'e'
    u0066 ::= 'f'
    u0067 ::= 'g'
    u0068 ::= 'h'
    u0069 ::= 'i'
    u006A ::= 'j'
    u006B ::= 'k'
    u006C ::= 'l'
    u006D ::= 'm'
    u006E ::= 'n'
    u006F ::= 'o'
    u0070 ::= 'p'
    u0071 ::= 'q'
    u0072 ::= 'r'
    u0073 ::= 's'
    u0074 ::= 't'
    u0075 ::= 'u'
    u0076 ::= 'v'
    u0077 ::= 'w'
    u0078 ::= 'x'
    u0079 ::= 'y'
    u007A ::= 'z'
    u007B ::= '{'
    u007C ::= '|'
    u007D ::= '}'
    u007E ::= '~'
    u007F

    UNUSED
%End
%Trailers
/.
        //
        //
        //
       export   class %super_stream_class extends LpgLexStream
        {

         //
        //
        //
        static   tokenKind : number[]=  new Array(0x10000)  ; // 0x10000 == 65536
        static  __b_init : boolean = %super_stream_class.init_block(%super_stream_class.tokenKind);
        static  init_block(tokenKind : number[]) : boolean
        {
            for (let i = 0; i < tokenKind.length; ++i) {
                tokenKind[i] = 0;
            }
            tokenKind[0x0000] = %sym_type.%prefix%u0000%suffix%;           // 000    0x00
            tokenKind[0x0001] = %sym_type.%prefix%u0001%suffix%;           // 001    0x01
            tokenKind[0x0002] = %sym_type.%prefix%u0002%suffix%;           // 002    0x02
            tokenKind[0x0003] = %sym_type.%prefix%u0003%suffix%;           // 003    0x03
            tokenKind[0x0004] = %sym_type.%prefix%u0004%suffix%;           // 004    0x04
            tokenKind[0x0005] = %sym_type.%prefix%u0005%suffix%;           // 005    0x05
            tokenKind[0x0006] = %sym_type.%prefix%u0006%suffix%;           // 006    0x06
            tokenKind[0x0007] = %sym_type.%prefix%u0007%suffix%;           // 007    0x07
            tokenKind[0x0008] = %sym_type.%prefix%u0008%suffix%;           // 008    0x08
            tokenKind[0x0009] = %sym_type.%prefix%HT%suffix%;              // 009    0x09
            tokenKind[0x000A] = %sym_type.%prefix%LF%suffix%;              // 010    0x0A
            tokenKind[0x000B] = %sym_type.%prefix%u000B%suffix%;           // 011    0x0B
            tokenKind[0x000C] = %sym_type.%prefix%FF%suffix%;              // 012    0x0C
            tokenKind[0x000D] = %sym_type.%prefix%CR%suffix%;              // 013    0x0D
            tokenKind[0x000E] = %sym_type.%prefix%u000E%suffix%;           // 014    0x0E
            tokenKind[0x000F] = %sym_type.%prefix%u000F%suffix%;           // 015    0x0F
            tokenKind[0x0010] = %sym_type.%prefix%u0010%suffix%;           // 016    0x10
            tokenKind[0x0011] = %sym_type.%prefix%u0011%suffix%;           // 017    0x11
            tokenKind[0x0012] = %sym_type.%prefix%u0012%suffix%;           // 018    0x12
            tokenKind[0x0013] = %sym_type.%prefix%u0013%suffix%;           // 019    0x13
            tokenKind[0x0014] = %sym_type.%prefix%u0014%suffix%;           // 020    0x14
            tokenKind[0x0015] = %sym_type.%prefix%u0015%suffix%;           // 021    0x15
            tokenKind[0x0016] = %sym_type.%prefix%u0016%suffix%;           // 022    0x16
            tokenKind[0x0017] = %sym_type.%prefix%u0017%suffix%;           // 023    0x17
            tokenKind[0x0018] = %sym_type.%prefix%u0018%suffix%;           // 024    0x18
            tokenKind[0x0019] = %sym_type.%prefix%u0019%suffix%;           // 025    0x19
            tokenKind[0x001A] = %sym_type.%prefix%u001A%suffix%;           // 026    0x1A
            tokenKind[0x001B] = %sym_type.%prefix%u001B%suffix%;           // 027    0x1B
            tokenKind[0x001C] = %sym_type.%prefix%u001C%suffix%;           // 028    0x1C
            tokenKind[0x001D] = %sym_type.%prefix%u001D%suffix%;           // 029    0x1D
            tokenKind[0x001E] = %sym_type.%prefix%u001E%suffix%;           // 030    0x1E
            tokenKind[0x001F] = %sym_type.%prefix%u001F%suffix%;           // 031    0x1F
            tokenKind[0x0020] = %sym_type.%prefix%u0020%suffix%;           // 032    0x20
            tokenKind[0x0021] = %sym_type.%prefix%u0021%suffix%;           // 033    0x21
            tokenKind[0x0022] = %sym_type.%prefix%u0022%suffix%;           // 034    0x22
            tokenKind[0x0023] = %sym_type.%prefix%u0023%suffix%;           // 035    0x23
            tokenKind[0x0024] = %sym_type.%prefix%u0024%suffix%;           // 036    0x24
            tokenKind[0x0025] = %sym_type.%prefix%u0025%suffix%;           // 037    0x25
            tokenKind[0x0026] = %sym_type.%prefix%u0026%suffix%;           // 038    0x26
            tokenKind[0x0027] = %sym_type.%prefix%u0027%suffix%;           // 039    0x27
            tokenKind[0x0028] = %sym_type.%prefix%u0028%suffix%;           // 040    0x28
            tokenKind[0x0029] = %sym_type.%prefix%u0029%suffix%;           // 041    0x29
            tokenKind[0x002A] = %sym_type.%prefix%u002A%suffix%;           // 042    0x2A
            tokenKind[0x002B] = %sym_type.%prefix%u002B%suffix%;           // 043    0x2B
            tokenKind[0x002C] = %sym_type.%prefix%u002C%suffix%;           // 044    0x2C
            tokenKind[0x002D] = %sym_type.%prefix%u002D%suffix%;           // 045    0x2D
            tokenKind[0x002E] = %sym_type.%prefix%u002E%suffix%;           // 046    0x2E
            tokenKind[0x002F] = %sym_type.%prefix%u002F%suffix%;           // 047    0x2F
            tokenKind[0x0030] = %sym_type.%prefix%u0030%suffix%;           // 048    0x30
            tokenKind[0x0031] = %sym_type.%prefix%u0031%suffix%;           // 049    0x31
            tokenKind[0x0032] = %sym_type.%prefix%u0032%suffix%;           // 050    0x32
            tokenKind[0x0033] = %sym_type.%prefix%u0033%suffix%;           // 051    0x33
            tokenKind[0x0034] = %sym_type.%prefix%u0034%suffix%;           // 052    0x34
            tokenKind[0x0035] = %sym_type.%prefix%u0035%suffix%;           // 053    0x35
            tokenKind[0x0036] = %sym_type.%prefix%u0036%suffix%;           // 054    0x36
            tokenKind[0x0037] = %sym_type.%prefix%u0037%suffix%;           // 055    0x37
            tokenKind[0x0038] = %sym_type.%prefix%u0038%suffix%;           // 056    0x38
            tokenKind[0x0039] = %sym_type.%prefix%u0039%suffix%;           // 057    0x39
            tokenKind[0x003A] = %sym_type.%prefix%u003A%suffix%;           // 058    0x3A
            tokenKind[0x003B] = %sym_type.%prefix%u003B%suffix%;           // 059    0x3B
            tokenKind[0x003C] = %sym_type.%prefix%u003C%suffix%;           // 060    0x3C
            tokenKind[0x003D] = %sym_type.%prefix%u003D%suffix%;           // 061    0x3D
            tokenKind[0x003E] = %sym_type.%prefix%u003E%suffix%;           // 062    0x3E
            tokenKind[0x003F] = %sym_type.%prefix%u003F%suffix%;           // 063    0x3F
            tokenKind[0x0040] = %sym_type.%prefix%u0040%suffix%;           // 064    0x40
            tokenKind[0x0041] = %sym_type.%prefix%u0041%suffix%;           // 065    0x41
            tokenKind[0x0042] = %sym_type.%prefix%u0042%suffix%;           // 066    0x42
            tokenKind[0x0043] = %sym_type.%prefix%u0043%suffix%;           // 067    0x43
            tokenKind[0x0044] = %sym_type.%prefix%u0044%suffix%;           // 068    0x44
            tokenKind[0x0045] = %sym_type.%prefix%u0045%suffix%;           // 069    0x45
            tokenKind[0x0046] = %sym_type.%prefix%u0046%suffix%;           // 070    0x46
            tokenKind[0x0047] = %sym_type.%prefix%u0047%suffix%;           // 071    0x47
            tokenKind[0x0048] = %sym_type.%prefix%u0048%suffix%;           // 072    0x48
            tokenKind[0x0049] = %sym_type.%prefix%u0049%suffix%;           // 073    0x49
            tokenKind[0x004A] = %sym_type.%prefix%u004A%suffix%;           // 074    0x4A
            tokenKind[0x004B] = %sym_type.%prefix%u004B%suffix%;           // 075    0x4B
            tokenKind[0x004C] = %sym_type.%prefix%u004C%suffix%;           // 076    0x4C
            tokenKind[0x004D] = %sym_type.%prefix%u004D%suffix%;           // 077    0x4D
            tokenKind[0x004E] = %sym_type.%prefix%u004E%suffix%;           // 078    0x4E
            tokenKind[0x004F] = %sym_type.%prefix%u004F%suffix%;           // 079    0x4F
            tokenKind[0x0050] = %sym_type.%prefix%u0050%suffix%;           // 080    0x50
            tokenKind[0x0051] = %sym_type.%prefix%u0051%suffix%;           // 081    0x51
            tokenKind[0x0052] = %sym_type.%prefix%u0052%suffix%;           // 082    0x52
            tokenKind[0x0053] = %sym_type.%prefix%u0053%suffix%;           // 083    0x53
            tokenKind[0x0054] = %sym_type.%prefix%u0054%suffix%;           // 084    0x54
            tokenKind[0x0055] = %sym_type.%prefix%u0055%suffix%;           // 085    0x55
            tokenKind[0x0056] = %sym_type.%prefix%u0056%suffix%;           // 086    0x56
            tokenKind[0x0057] = %sym_type.%prefix%u0057%suffix%;           // 087    0x57
            tokenKind[0x0058] = %sym_type.%prefix%u0058%suffix%;           // 088    0x58
            tokenKind[0x0059] = %sym_type.%prefix%u0059%suffix%;           // 089    0x59
            tokenKind[0x005A] = %sym_type.%prefix%u005A%suffix%;           // 090    0x5A
            tokenKind[0x005B] = %sym_type.%prefix%u005B%suffix%;           // 091    0x5B
            tokenKind[0x005C] = %sym_type.%prefix%u005C%suffix%;           // 092    0x5C
            tokenKind[0x005D] = %sym_type.%prefix%u005D%suffix%;           // 093    0x5D
            tokenKind[0x005E] = %sym_type.%prefix%u005E%suffix%;           // 094    0x5E
            tokenKind[0x005F] = %sym_type.%prefix%u005F%suffix%;           // 095    0x5F
            tokenKind[0x0060] = %sym_type.%prefix%u0060%suffix%;           // 096    0x60
            tokenKind[0x0061] = %sym_type.%prefix%u0061%suffix%;           // 097    0x61
            tokenKind[0x0062] = %sym_type.%prefix%u0062%suffix%;           // 098    0x62
            tokenKind[0x0063] = %sym_type.%prefix%u0063%suffix%;           // 099    0x63
            tokenKind[0x0064] = %sym_type.%prefix%u0064%suffix%;           // 100    0x64
            tokenKind[0x0065] = %sym_type.%prefix%u0065%suffix%;           // 101    0x65
            tokenKind[0x0066] = %sym_type.%prefix%u0066%suffix%;           // 102    0x66
            tokenKind[0x0067] = %sym_type.%prefix%u0067%suffix%;           // 103    0x67
            tokenKind[0x0068] = %sym_type.%prefix%u0068%suffix%;           // 104    0x68
            tokenKind[0x0069] = %sym_type.%prefix%u0069%suffix%;           // 105    0x69
            tokenKind[0x006A] = %sym_type.%prefix%u006A%suffix%;           // 106    0x6A
            tokenKind[0x006B] = %sym_type.%prefix%u006B%suffix%;           // 107    0x6B
            tokenKind[0x006C] = %sym_type.%prefix%u006C%suffix%;           // 108    0x6C
            tokenKind[0x006D] = %sym_type.%prefix%u006D%suffix%;           // 109    0x6D
            tokenKind[0x006E] = %sym_type.%prefix%u006E%suffix%;           // 110    0x6E
            tokenKind[0x006F] = %sym_type.%prefix%u006F%suffix%;           // 111    0x6F
            tokenKind[0x0070] = %sym_type.%prefix%u0070%suffix%;           // 112    0x70
            tokenKind[0x0071] = %sym_type.%prefix%u0071%suffix%;           // 113    0x71
            tokenKind[0x0072] = %sym_type.%prefix%u0072%suffix%;           // 114    0x72
            tokenKind[0x0073] = %sym_type.%prefix%u0073%suffix%;           // 115    0x73
            tokenKind[0x0074] = %sym_type.%prefix%u0074%suffix%;           // 116    0x74
            tokenKind[0x0075] = %sym_type.%prefix%u0075%suffix%;           // 117    0x75
            tokenKind[0x0076] = %sym_type.%prefix%u0076%suffix%;           // 118    0x76
            tokenKind[0x0077] = %sym_type.%prefix%u0077%suffix%;           // 119    0x77
            tokenKind[0x0078] = %sym_type.%prefix%u0078%suffix%;           // 120    0x78
            tokenKind[0x0079] = %sym_type.%prefix%u0079%suffix%;           // 121    0x79
            tokenKind[0x007A] = %sym_type.%prefix%u007A%suffix%;           // 122    0x7A
            tokenKind[0x007B] = %sym_type.%prefix%u007B%suffix%;           // 123    0x7B
            tokenKind[0x007C] = %sym_type.%prefix%u007C%suffix%;           // 124    0x7C
            tokenKind[0x007D] = %sym_type.%prefix%u007D%suffix%;           // 125    0x7D
            tokenKind[0x007E] = %sym_type.%prefix%u007E%suffix%;           // 126    0x7E
            tokenKind[0x007F] = %sym_type.%prefix%u007F%suffix%;           // 127    0x7F

            tokenKind[0xFFFF] = %sym_type.%prefix%EOF%suffix%;

            //
            // Every other character not yet assigned is treated initially as unused
            //
            for (let i = 0x007F; i < 0xFFFF; i++)
                if (tokenKind[i] == 0) tokenKind[i] = %sym_type.%prefix%UNUSED%suffix%;
            return true;
        }

        public    getKind(number i) : number // Classify character at ith location
        {
            return (i >= this.getStreamLength()
                       ? 0xffff
                       : %super_stream_class.tokenKind[getIntValue(i)]);
        }

        public  orderedExportedSymbols() : string[] { return %exp_type.orderedTerminalSymbols; }

        constructor(fileName: string, inputChars?: string, tab: number=4) {
             super(fileName, inputChars, tab);
         }
        }
./
%End
%Headers
    --
    -- Additional methods for the action class not provided in the template
    --
    /.
        //
        // The Lexer contains an array of characters as the input stream to be parsed.
        // There are methods to retrieve and classify characters.
        // The lexparser "token" is implemented simply as the index of the next character in the array.
        // The Lexer : the abstract class LpgLexStream with an implementation of the abstract
        // method getKind.  The template defines the Lexer class and the lexer() method.
        // A driver creates the action class, "Lexer", passing an Option object to the constructor.
        //
       kwLexer :  %kw_lexer_class;
       public   printTokens : boolean =false;

       private static  readonly   ECLIPSE_TAB_VALUE: number = 4;

        public  getKeywordKinds() : number[] { return this.kwLexer.getKeywordKinds(); }

        constructor(filename : string) : this(filename, ECLIPSE_TAB_VALUE)
        {

            this.kwLexer = new %kw_lexer_class(this.getInputChars(), %_IDENTIFIER);
        }

        public  initialize(filename : string,content? : string) : void
        {
            super.initialize(filename,content);
            if (this.kwLexer == null)
                 this.kwLexer = new %kw_lexer_class(this.getInputChars(), %_IDENTIFIER);
            else this.kwLexer.setInputChars(this.getInputChars());
        }

         void makeToken(kind : number)
        {
            let startOffset = this.getLeftSpan(),
                endOffset = this.getRightSpan();
            this.makeToken(startOffset, endOffset, kind);
            if (this.printTokens) this.printValue(startOffset, endOffset);
        }

         void makeComment(kind : number)
        {
            let startOffset = this.getLeftSpan(),
                endOffset = this.getRightSpan();
            super.getPrsStream().makeAdjunct(startOffset, endOffset, kind);
        }

         skipToken() : void
        {
            if (this.printTokens) this.printValue(this.getLeftSpan(), this.getRightSpan());
        }

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

         printValue(startOffset : number, endOffset : number) : void
        {
             let s = lexStream.getInputChars().substr(startOffset, endOffset - startOffset + 1);
             console.Out.Write(s);
        }

    ./
%End


%Terminals
    DollarSign ::= '$'
    Percent ::= '%'
    _
    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
%End

%Headers
    /.
        //
        // Each upper case letter is mapped into its corresponding
        // lower case counterpart. For example, if an 'A' appears
        // in the input, it is mapped into %sym_type.%prefix%a%suffix% just
        // like 'a'.
        //
       public  static   tokenKind : number[]=  new Array(128)  ;
         static  __b_init : boolean = %action_type.init_block(%action_type.tokenKind);
        static  init_block(tokenKind : number[]) : boolean
        {
            for (let i = 0; i < tokenKind.length; ++i) {
                tokenKind[i] = 0;
            }
            tokenKind['$'.charCodeAt(0)] = %sym_type.%prefix%DollarSign%suffix%;
            tokenKind['%'.charCodeAt(0)] = %sym_type.%prefix%Percent%suffix%;
            tokenKind['_'.charCodeAt(0)] = %sym_type.%prefix%_%suffix%;

            tokenKind['a'.charCodeAt(0)] = %sym_type.%prefix%a%suffix%;
            tokenKind['b'.charCodeAt(0)] = %sym_type.%prefix%b%suffix%;
            tokenKind['c'.charCodeAt(0)] = %sym_type.%prefix%c%suffix%;
            tokenKind['d'.charCodeAt(0)] = %sym_type.%prefix%d%suffix%;
            tokenKind['e'.charCodeAt(0)] = %sym_type.%prefix%e%suffix%;
            tokenKind['f'.charCodeAt(0)] = %sym_type.%prefix%f%suffix%;
            tokenKind['g'.charCodeAt(0)] = %sym_type.%prefix%g%suffix%;
            tokenKind['h'.charCodeAt(0)] = %sym_type.%prefix%h%suffix%;
            tokenKind['i'.charCodeAt(0)] = %sym_type.%prefix%i%suffix%;
            tokenKind['j'.charCodeAt(0)] = %sym_type.%prefix%j%suffix%;
            tokenKind['k'.charCodeAt(0)] = %sym_type.%prefix%k%suffix%;
            tokenKind['l'.charCodeAt(0)] = %sym_type.%prefix%l%suffix%;
            tokenKind['m'.charCodeAt(0)] = %sym_type.%prefix%m%suffix%;
            tokenKind['n'.charCodeAt(0)] = %sym_type.%prefix%n%suffix%;
            tokenKind['o'.charCodeAt(0)] = %sym_type.%prefix%o%suffix%;
            tokenKind['p'.charCodeAt(0)] = %sym_type.%prefix%p%suffix%;
            tokenKind['q'.charCodeAt(0)] = %sym_type.%prefix%q%suffix%;
            tokenKind['r'.charCodeAt(0)] = %sym_type.%prefix%r%suffix%;
            tokenKind['s'.charCodeAt(0)] = %sym_type.%prefix%s%suffix%;
            tokenKind['t'.charCodeAt(0)] = %sym_type.%prefix%t%suffix%;
            tokenKind['u'.charCodeAt(0)] = %sym_type.%prefix%u%suffix%;
            tokenKind['v'.charCodeAt(0)] = %sym_type.%prefix%v%suffix%;
            tokenKind['w'.charCodeAt(0)] = %sym_type.%prefix%w%suffix%;
            tokenKind['x'.charCodeAt(0)] = %sym_type.%prefix%x%suffix%;
            tokenKind['y'.charCodeAt(0)] = %sym_type.%prefix%y%suffix%;
            tokenKind['z'.charCodeAt(0)] = %sym_type.%prefix%z%suffix%;

            tokenKind['A'.charCodeAt(0)] = %sym_type.%prefix%a%suffix%;
            tokenKind['B'.charCodeAt(0)] = %sym_type.%prefix%b%suffix%;
            tokenKind['C'.charCodeAt(0)] = %sym_type.%prefix%c%suffix%;
            tokenKind['D'.charCodeAt(0)] = %sym_type.%prefix%d%suffix%;
            tokenKind['E'.charCodeAt(0)] = %sym_type.%prefix%e%suffix%;
            tokenKind['F'.charCodeAt(0)] = %sym_type.%prefix%f%suffix%;
            tokenKind['G'.charCodeAt(0)] = %sym_type.%prefix%g%suffix%;
            tokenKind['H'.charCodeAt(0)] = %sym_type.%prefix%h%suffix%;
            tokenKind['I'.charCodeAt(0)] = %sym_type.%prefix%i%suffix%;
            tokenKind['J'.charCodeAt(0)] = %sym_type.%prefix%j%suffix%;
            tokenKind['K'.charCodeAt(0)] = %sym_type.%prefix%k%suffix%;
            tokenKind['L'.charCodeAt(0)] = %sym_type.%prefix%l%suffix%;
            tokenKind['M'.charCodeAt(0)] = %sym_type.%prefix%m%suffix%;
            tokenKind['N'.charCodeAt(0)] = %sym_type.%prefix%n%suffix%;
            tokenKind['O'.charCodeAt(0)] = %sym_type.%prefix%o%suffix%;
            tokenKind['P'.charCodeAt(0)] = %sym_type.%prefix%p%suffix%;
            tokenKind['Q'.charCodeAt(0)] = %sym_type.%prefix%q%suffix%;
            tokenKind['R'.charCodeAt(0)] = %sym_type.%prefix%r%suffix%;
            tokenKind['S'.charCodeAt(0)] = %sym_type.%prefix%s%suffix%;
            tokenKind['T'.charCodeAt(0)] = %sym_type.%prefix%t%suffix%;
            tokenKind['U'.charCodeAt(0)] = %sym_type.%prefix%u%suffix%;
            tokenKind['V'.charCodeAt(0)] = %sym_type.%prefix%v%suffix%;
            tokenKind['W'.charCodeAt(0)] = %sym_type.%prefix%w%suffix%;
            tokenKind['X'.charCodeAt(0)] = %sym_type.%prefix%x%suffix%;
            tokenKind['Y'.charCodeAt(0)] = %sym_type.%prefix%y%suffix%;
            tokenKind['Z'.charCodeAt(0)] = %sym_type.%prefix%z%suffix%;
            return true;
        }

       public  static    getKind(c :number ):number
        {
            return (c < 128 ? %action_type.tokenKind[c] : 0);
        }
    ./
%End


--/**
-- * <copyright>
-- *
-- * Copyright (c) 2005, 2009 IBM Corporation 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:
-- *   See (or edit) Notice Declaration below
-- *
-- * </copyright>
-- */
--
-- The EssentialOCL Parser
--

%Define
    -- Redefinition of macros used in the parser template
    --
    $default_repair_count /.getDefaultRepairCount()./
	$super_parser_class /.AbstractOCLParser./
    $prs_stream_class /.DerivedPrsStream./

	-- Definition of new macros used by the grammar file
	-- which may be redefined by extended files.
    $copyright_contributions /.*./

	-- Definition of new macros used by the grammar file
	-- which are not intended to be extended.
	$lpg_ns /.lpg.runtime./ -- package namespace of the LPG Runtime API

	-- Some useful macros
    $NewCase
    /. $Header
                case $rule_number:./

    $EmptyListAction -- Deprecated, code inline with correct generic parameter type
    /. $Header
                case $rule_number:
                    setResult(new BasicEList<Object>());
                    break;./

    -- BeginJava and EndJava need to be reworked in order to be able to properly use $NewCase macro

    -- BeginJava does nothing
	-- block-actions should call BeginCode, instead
    $BeginJava /../

  	-- EndJava does nothing
	-- block-actions should call EndCode, instead
	$EndJava /../

	$BeginCode
	/.$BeginAction
					$symbol_declarations./

	$EndCode /.$EndAction./

%End

%Notice
    /./**
 * Essential OCL Grammar
 * <copyright>
 *
 * Copyright (c) 2005, 2010 IBM Corporation 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:
 *   IBM - Initial API and implementation
 *   E.D.Willink - Elimination of some shift-reduce conflicts
 *   E.D.Willink - Remove unnecessary warning suppression
 *   E.D.Willink - Bugs 184048, 225493, 243976, 259818, 282882, 287993, 288040, 292112, 295166
 *   Borland - Bug 242880
 *   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.
 *******************************************************************************/
    ./
%End

%Globals
    /.import org.eclipse.emf.common.util.BasicEList;
	import org.eclipse.emf.common.util.EList;
	import org.eclipse.ocl.cst.BooleanLiteralExpCS;
	import org.eclipse.ocl.cst.CSTNode;
	import org.eclipse.ocl.cst.CallExpCS;
	import org.eclipse.ocl.cst.CollectionLiteralExpCS;
	import org.eclipse.ocl.cst.CollectionLiteralPartCS;
	import org.eclipse.ocl.cst.CollectionTypeCS;
	import org.eclipse.ocl.cst.CollectionTypeIdentifierEnum;
	import org.eclipse.ocl.cst.FeatureCallExpCS;
	import org.eclipse.ocl.cst.IfExpCS;
	import org.eclipse.ocl.cst.IntegerLiteralExpCS;
	import org.eclipse.ocl.cst.InvalidLiteralExpCS;
	import org.eclipse.ocl.cst.IsMarkedPreCS;
	import org.eclipse.ocl.cst.IterateExpCS;
	import org.eclipse.ocl.cst.IteratorExpCS;
	import org.eclipse.ocl.cst.LetExpCS;
	import org.eclipse.ocl.cst.NullLiteralExpCS;
	import org.eclipse.ocl.cst.OCLExpressionCS;
	import org.eclipse.ocl.cst.OperationCallExpCS;
	import org.eclipse.ocl.cst.PathNameCS;
	import org.eclipse.ocl.cst.PrimitiveTypeCS;
	import org.eclipse.ocl.cst.RealLiteralExpCS;
	import org.eclipse.ocl.cst.SimpleNameCS;
	import org.eclipse.ocl.cst.SimpleTypeEnum;
	import org.eclipse.ocl.cst.StringLiteralExpCS;
	import org.eclipse.ocl.cst.TupleLiteralExpCS;
	import org.eclipse.ocl.cst.TupleTypeCS;
	import org.eclipse.ocl.cst.TypeCS;
	import org.eclipse.ocl.cst.UnlimitedNaturalLiteralExpCS;
	import org.eclipse.ocl.cst.VariableCS;
	import org.eclipse.ocl.cst.VariableExpCS;
	import org.eclipse.ocl.lpg.DerivedPrsStream;

	import $lpg_ns.BadParseException;
	import $lpg_ns.BadParseSymFileException;
	import $lpg_ns.DiagnoseParser;
	import $lpg_ns.ErrorToken;
	import $lpg_ns.IToken;
	import $lpg_ns.ILexStream;
	import $lpg_ns.Monitor;
	import $lpg_ns.NullExportedSymbolsException;
	import $lpg_ns.NullTerminalSymbolsException;
	import $lpg_ns.ParseTable;
	import $lpg_ns.RuleAction;
	import $lpg_ns.UndefinedEofSymbolException;
	import $lpg_ns.UnimplementedTerminalsException;
    ./
%End

%KeyWords
-- Reserved keywords
    and implies not or xor
    if then else endif
    let in
    false true
    null invalid
    self

-- Restricted keywords
    Bag Collection OrderedSet Sequence Set
    Tuple
    Boolean Integer Real String UnlimitedNatural
    OclAny OclInvalid OclVoid
%End

-- Terminals
%Identifier
    IDENTIFIER
%End

%Terminals

    QUOTED_IDENTIFIER INTEGER_LITERAL REAL_LITERAL STRING_LITERAL

    PLUS     ::= '+'
    MINUS    ::= '-'
    MULTIPLY ::= '*'
    DIVIDE   ::= '/'

    GREATER       ::= '>'
    LESS          ::= '<'
    EQUAL         ::= '='
    GREATER_EQUAL ::= '>='
    LESS_EQUAL    ::= '<='
    NOT_EQUAL     ::= '<>'

    LPAREN   ::= '('
    RPAREN   ::= ')'
    LBRACE   ::= '{'
    RBRACE   ::= '}'
    LBRACKET ::= '['
    RBRACKET ::= ']'

    ARROW      ::= '->'
    BAR        ::= '|'
    COMMA      ::= ','
    COLON      ::= ':'
    COLONCOLON ::= '::'
    SEMICOLON  ::= ';'
    DOT        ::= '.'
    DOTDOT     ::= '..'
%End

%Headers
	/.

	public $environment_class getOCLEnvironment() {
		return getLexer().getOCLEnvironment();
	}

	@Override
	public $super_lexer_class getLexer() {
		return ($super_lexer_class) super.getLexer();
	}

	// Some methods for backwards compatibility
	/**
	*

	* Before 3.0, this method was used with the now-deprecated  "dollar"getToken macro (which
	* provided token index in the prsStream) to obtain an IToken f a rule given the index of the
	* right hand side token in the said rule. In 3.0 a convenience method has been introduced
	* in order to directly return the IToken, given the index of the right hand side token in the rule.
	*

	*
	*

	* In an action-block of a rule, instead of doing getIToken("dollar"getToken(i))
	* you should do getRhsTokenText(i)
	*

	* @param i the right hand side token index
	* @return the correspondent IToken.
	*
	* @since 3.0
	*/
	@Deprecated
	protected IToken getIToken(int i) {
		return prsStream.getIToken(i);
	}

	/**
	*

	* Before 3.0, this method was used with the now-deprecated "dollar"getToken macro (which
	* provided token index in the prsStream) to obtain an IToken f a rule given the index of the
	* right hand side token in the said rule. In 3.0 a convenience method has been introduced
	* in order to directly return the IToken, given the index of the right hand side token in the rule.
	*

	*
	*

	* In an action-block of a rule, instead of doing getTokenText("dollar"getToken(i))
	* you should do getRhsTokenText(i)
	*

	* @param i the right hand side token index
	* @result the text of the correspondent right hand side IToken.
	*/
	@Deprecated
	protected String getTokenText(int i) {
		return prsStream.getTokenText(i);
	}

	/**
	* A convenience method to obtain the text of a right hand side IToken.
	*
	* @param i the right hand side token index
	* @result the text of the correspondent right hand side IToken.
	*
	* @since 3.0
	*/
	protected String getRhsTokenText(int i) {
		return prsStream.getTokenText(getRhsTokenIndex(i));
	}
	./
%End

%Rules

-----------------------------------------------------------------------
--  Names
-----------------------------------------------------------------------
--  Temporary backward compatibility support for 7.4.8 conceptual usage
    conceptualOperationName -> and
    conceptualOperationName -> implies
    conceptualOperationName -> not
    conceptualOperationName -> or
    conceptualOperationName -> xor
    conceptualOperationName -> '<'
    conceptualOperationName -> '<='
    conceptualOperationName -> '>='
    conceptualOperationName -> '>'
    conceptualOperationName -> '='
    conceptualOperationName -> '<>'
    conceptualOperationName -> '+'
    conceptualOperationName -> '-'
    conceptualOperationName -> '*'
    conceptualOperationName -> '/'
    conceptualOperationNameCS ::= conceptualOperationName
        /.$BeginCode
                    IToken iToken = getRhsIToken(1);
                    SimpleNameCS result = createConceptualOperationNameCS(iToken);
                    setOffsets(result, iToken);
                    setResult(result);
          $EndCode
        ./

    reservedKeyword -> and
    reservedKeyword -> else
    reservedKeyword -> endif
    reservedKeyword -> if
    reservedKeyword -> implies
    reservedKeyword -> in
    reservedKeyword -> let
    reservedKeyword -> not
    reservedKeyword -> or
    reservedKeyword -> then
    reservedKeyword -> xor

    tupleKeywordCS ::= Tuple
        /.$NewCase./
    reservedKeywordCS ::= reservedKeyword
        /.$BeginCode
                    IToken iToken = getRhsIToken(1);
                    SimpleNameCS result = createSimpleNameCS(
                                SimpleTypeEnum.KEYWORD_LITERAL,
                                iToken
                            );
                    setOffsets(result, iToken);
                    setResult(result);
          $EndCode
        ./
    restrictedKeywordCS -> CollectionTypeIdentifierCS
--  restrictedKeywordCS -> BooleanLiteralExpCS
--  restrictedKeywordCS -> InvalidLiteralExpCS
--  restrictedKeywordCS -> NullLiteralExpCS
--  restrictedKeywordCS -> selfKeywordCS
    restrictedKeywordCS -> primitiveTypeCS
    restrictedKeywordCS -> tupleKeywordCS

    selfKeywordCS ::= self
        /.$BeginCode
                    IToken iToken = getRhsIToken(1);
                    SimpleNameCS result = createSimpleNameCS(
                            SimpleTypeEnum.SELF_LITERAL,
                            iToken
                        );
                    setOffsets(result, iToken);
                    setResult(result);
          $EndCode
        ./

    simpleNameCS ::= IDENTIFIER
        /.$BeginCode
                    IToken iToken = getRhsIToken(1);
                    SimpleNameCS result = createSimpleNameCS(
                            SimpleTypeEnum.IDENTIFIER_LITERAL,
                            iToken
                        );
                    setOffsets(result, iToken);
                    setResult(result);
          $EndCode
        ./
    simpleNameCS -> QuotedSimpleNameCS
    QuotedSimpleNameCS ::= QUOTED_IDENTIFIER
        /.$BeginCode
                    IToken iToken = getRhsIToken(1);
                    SimpleNameCS result = createQuotedSimpleNameCS(
                            SimpleTypeEnum.IDENTIFIER_LITERAL,
                            iToken
                        );
                    setOffsets(result, iToken);
                    setResult(result);
          $EndCode
        ./
    QuotedSimpleNameCS ::= QuotedSimpleNameCS STRING_LITERAL
        /.$BeginCode
                    SimpleNameCS string = (SimpleNameCS)getRhsSym(1);
                    IToken literalToken = getRhsIToken(2);
                    SimpleNameCS result = extendQuotedSimpleNameCS(string, literalToken);
                    setOffsets(result, string, literalToken);
                    setResult(result);
          $EndCode
        ./

    unreservedSimpleNameCS -> simpleNameCS
    unreservedSimpleNameCS -> restrictedKeywordCS

    pathNameCS ::= simpleNameCS
        /.$BeginCode
                    SimpleNameCS simpleName = (SimpleNameCS)getRhsSym(1);
                    PathNameCS result = createPathNameCS(simpleName);
                    setOffsets(result, simpleName);
                    setResult(result);
          $EndCode
        ./
    pathNameCS ::= pathNameCS '::' unreservedSimpleNameCS
        /.$BeginCode
                    PathNameCS result = (PathNameCS)getRhsSym(1);
                    SimpleNameCS simpleNameCS = (SimpleNameCS)getRhsSym(3);
                    result = extendPathNameCS(result, simpleNameCS);
                    setOffsets(result, result, simpleNameCS);
                    setResult(result);
          $EndCode
        ./

-----------------------------------------------------------------------
--  Types
-----------------------------------------------------------------------
    primitiveTypeCS ::= Boolean
        /.$BeginCode
                    PrimitiveTypeCS result = createPrimitiveTypeCS(
                            SimpleTypeEnum.BOOLEAN_LITERAL,
                            getRhsTokenText(1)
                        );
                    setOffsets(result, getRhsIToken(1));
                    setResult(result);
          $EndCode
        ./
    primitiveTypeCS ::= Integer
        /.$BeginCode
                    PrimitiveTypeCS result = createPrimitiveTypeCS(
                            SimpleTypeEnum.INTEGER_LITERAL,
                            getRhsTokenText(1)
                        );
                    setOffsets(result, getRhsIToken(1));
                    setResult(result);
          $EndCode
        ./
    primitiveTypeCS ::= Real
        /.$BeginCode
                    PrimitiveTypeCS result = createPrimitiveTypeCS(
                            SimpleTypeEnum.REAL_LITERAL,
                            getRhsTokenText(1)
                        );
                    setOffsets(result, getRhsIToken(1));
                    setResult(result);
          $EndCode
        ./
    primitiveTypeCS ::= String
        /.$BeginCode
                    PrimitiveTypeCS result = createPrimitiveTypeCS(
                            SimpleTypeEnum.STRING_LITERAL,
                            getRhsTokenText(1)
                        );
                    setOffsets(result, getRhsIToken(1));
                    setResult(result);
          $EndCode
        ./
    primitiveTypeCS ::= UnlimitedNatural
        /.$BeginCode
                    PrimitiveTypeCS result = createPrimitiveTypeCS(
                            SimpleTypeEnum.UNLIMITED_NATURAL_LITERAL,
                            getRhsTokenText(1)
                        );
                    setOffsets(result, getRhsIToken(1));
                    setResult(result);
          $EndCode
        ./

    primitiveTypeCS ::= OclAny
        /.$BeginCode
                    PrimitiveTypeCS result = createPrimitiveTypeCS(
                            SimpleTypeEnum.OCL_ANY_LITERAL,
                            getRhsTokenText(1)
                        );
                    setOffsets(result, getRhsIToken(1));
                    setResult(result);
          $EndCode
        ./
    primitiveTypeCS ::= OclInvalid
        /.$BeginCode
                    PrimitiveTypeCS result = createPrimitiveTypeCS(
                            SimpleTypeEnum.OCL_INVALID_LITERAL,
                            getRhsTokenText(1)
                        );
                    setOffsets(result, getRhsIToken(1));
                    setResult(result);
          $EndCode
        ./
    primitiveTypeCS ::= OclVoid
        /.$BeginCode
                    PrimitiveTypeCS result = createPrimitiveTypeCS(
                            SimpleTypeEnum.OCL_VOID_LITERAL,
                            getRhsTokenText(1)
                        );
                    setOffsets(result, getRhsIToken(1));
                    setResult(result);
          $EndCode
        ./

    CollectionTypeIdentifierCS ::= Set
        /.$BeginCode
                    SimpleNameCS result = createCollectionTypeCS(
                                CollectionTypeIdentifierEnum.SET_LITERAL,
                                getRhsTokenText(1)
                            );
                    setOffsets(result, getRhsIToken(1));
                    setResult(result);
          $EndCode
        ./
    CollectionTypeIdentifierCS ::= Bag
        /.$BeginCode
                    SimpleNameCS result = createCollectionTypeCS(
                                CollectionTypeIdentifierEnum.BAG_LITERAL,
                                getRhsTokenText(1)
                            );
                    setOffsets(result, getRhsIToken(1));
                    setResult(result);
          $EndCode
        ./
    CollectionTypeIdentifierCS ::= Sequence
        /.$BeginCode
                    SimpleNameCS result = createCollectionTypeCS(
                                CollectionTypeIdentifierEnum.SEQUENCE_LITERAL,
                                getRhsTokenText(1)
                            );
                    setOffsets(result, getRhsIToken(1));
                    setResult(result);
          $EndCode
        ./
    CollectionTypeIdentifierCS ::= Collection
        /.$BeginCode
                    SimpleNameCS result = createCollectionTypeCS(
                                CollectionTypeIdentifierEnum.COLLECTION_LITERAL,
                                getRhsTokenText(1)
                            );
                    setOffsets(result, getRhsIToken(1));
                    setResult(result);
          $EndCode
        ./
    CollectionTypeIdentifierCS ::= OrderedSet
        /.$BeginCode
                    SimpleNameCS result = createCollectionTypeCS(
                                CollectionTypeIdentifierEnum.ORDERED_SET_LITERAL,
                                getRhsTokenText(1)
                            );
                    setOffsets(result, getRhsIToken(1));
                    setResult(result);
          $EndCode
        ./

    typeCS -> primitiveTypeCS
    typeCS -> pathNameCS
    typeCS -> collectionTypeCS
    typeCS -> tupleTypeCS

    collectionTypeCS ::= CollectionTypeIdentifierCS '(' typeCS ')'
        /.$BeginCode
                    CollectionTypeCS result = (CollectionTypeCS)getRhsSym(1);
                    result.setTypeCS((TypeCS)getRhsSym(3));
                    setOffsets(result, result, getRhsIToken(4));
                    setResult(result);
          $EndCode
        ./

    tupleTypeCS ::= Tuple '(' tupleTypePartsCSopt ')'
        /.$BeginCode
                     TupleTypeCS result = createTupleTypeCS((EList<VariableCS>)getRhsSym(3));
                    setOffsets(result, getRhsIToken(1), getRhsIToken(4));
                    setResult(result);
          $EndCode
        ./

    tupleTypePartsCSopt ::= %empty
        /.$BeginCode
                    setResult(new BasicEList<VariableCS>());
          $EndCode
        ./
    tupleTypePartsCSopt -> tupleTypePartsCS

    tupleTypePartsCS ::= typedUninitializedVariableCS
        /.$BeginCode
                    EList<VariableCS> result = new BasicEList<VariableCS>();
                    result.add((VariableCS)getRhsSym(1));
                    setResult(result);
          $EndCode
        ./
    tupleTypePartsCS ::= tupleTypePartsCS ',' typedUninitializedVariableCS
        /.$BeginCode
                    EList<VariableCS> result = (EList<VariableCS>)getRhsSym(1);
                    result.add((VariableCS)getRhsSym(3));
                    setResult(result);
          $EndCode
        ./

-----------------------------------------------------------------------
--  Declarations
-----------------------------------------------------------------------
    untypedUninitializedVariableCS ::= simpleNameCS
        /.$BeginCode
                    SimpleNameCS name = (SimpleNameCS)getRhsSym(1);
                    VariableCS result = createVariableCS(name, null, null);
                    setOffsets(result, name);
                    setResult(result);
          $EndCode
        ./

    typedUninitializedVariableCS ::= simpleNameCS ':' typeCS
        /.$BeginCode
                    SimpleNameCS name = (SimpleNameCS)getRhsSym(1);
                    TypeCS type = (TypeCS)getRhsSym(3);
                    VariableCS result = createVariableCS(name, type, null);
                    setOffsets(result, name, type);
                    setResult(result);
          $EndCode
        ./

    untypedInitializedVariableCS ::= simpleNameCS '=' OclExpressionCS
        /.$BeginCode
                    SimpleNameCS name = (SimpleNameCS)getRhsSym(1);
                    OCLExpressionCS initExpression = (OCLExpressionCS)getRhsSym(3);
                    VariableCS result = createVariableCS(name, null, initExpression);
                    setOffsets(result, name, initExpression);
                    setResult(result);
          $EndCode
        ./

    typedInitializedVariableCS ::= simpleNameCS ':' typeCS '=' OclExpressionCS
        /.$BeginCode
                    SimpleNameCS name = (SimpleNameCS)getRhsSym(1);
                    TypeCS type = (TypeCS)getRhsSym(3);
                    OCLExpressionCS initExpression = (OCLExpressionCS)getRhsSym(5);
                    VariableCS result = createVariableCS(name, type, initExpression);
                    setOffsets(result, name, initExpression);
                    setResult(result);
          $EndCode
        ./

    initializedVariableCS -> untypedInitializedVariableCS
    initializedVariableCS -> typedInitializedVariableCS

    uninitializedVariableCS -> untypedUninitializedVariableCS
    uninitializedVariableCS -> typedUninitializedVariableCS

    VariableDeclarationCS -> untypedUninitializedVariableCS
    VariableDeclarationCS -> untypedInitializedVariableCS
    VariableDeclarationCS -> typedUninitializedVariableCS
    VariableDeclarationCS -> typedInitializedVariableCS

-----------------------------------------------------------------------
--  Literals
-----------------------------------------------------------------------
-- EnumLiteralExpCS is parsed as a PropertyCallExpCS[C]
--  LiteralExpCS -> EnumLiteralExpCS
    LiteralExpCS -> CollectionLiteralExpCS
    LiteralExpCS -> TupleLiteralExpCS
    LiteralExpCS -> PrimitiveLiteralExpCS
    LiteralExpCS -> TypeLiteralExpCS

    CollectionLiteralExpCS ::= CollectionTypeIdentifierCS
       '{' CollectionLiteralPartsCSopt '}'
        /.$BeginCode
                    CollectionTypeCS typeCS = (CollectionTypeCS)getRhsSym(1);
                    CollectionLiteralExpCS result = createCollectionLiteralExpCS(
                            typeCS,
                            (EList<CollectionLiteralPartCS>)getRhsSym(3)
                        );
                    setOffsets(result, typeCS, getRhsIToken(4));
                    setResult(result);
          $EndCode
        ./
    CollectionLiteralExpCS ::= collectionTypeCS '{' CollectionLiteralPartsCSopt '}'
        /.$BeginCode
                    CollectionTypeCS typeCS = (CollectionTypeCS)getRhsSym(1);
                    CollectionLiteralExpCS result = createCollectionLiteralExpCS(
                            typeCS,
                            (EList<CollectionLiteralPartCS>)getRhsSym(3)
                        );
                    setOffsets(result, typeCS, getRhsIToken(4));
                    setResult(result);
          $EndCode
        ./

    CollectionLiteralPartsCSopt ::= %empty
        /.$BeginCode
                    setResult(new BasicEList<CollectionLiteralPartCS>());
          $EndCode
        ./
    CollectionLiteralPartsCSopt -> CollectionLiteralPartsCS

    CollectionLiteralPartsCS ::= CollectionLiteralPartCS
        /.$BeginCode
                    EList<CollectionLiteralPartCS> result = new BasicEList<CollectionLiteralPartCS>();
                    result.add((CollectionLiteralPartCS)getRhsSym(1));
                    setResult(result);
          $EndCode
        ./
    CollectionLiteralPartsCS ::= CollectionLiteralPartsCS ',' CollectionLiteralPartCS
        /.$BeginCode
                    EList<CollectionLiteralPartCS> result = (EList<CollectionLiteralPartCS>)getRhsSym(1);
                    result.add((CollectionLiteralPartCS)getRhsSym(3));
                    setResult(result);
          $EndCode
        ./

    CollectionLiteralPartCS -> CollectionRangeCS
    CollectionLiteralPartCS ::= OclExpressionCS
        /.$BeginCode
                    CollectionLiteralPartCS result = createCollectionLiteralPartCS(
                            (OCLExpressionCS)getRhsSym(1)
                        );
                    setOffsets(result, (CSTNode)getRhsSym(1));
                    setResult(result);
          $EndCode
        ./

    CollectionRangeCS ::= OclExpressionCS '..' OclExpressionCS
        /.$BeginCode
                    CollectionLiteralPartCS result = createCollectionRangeCS(
                            (OCLExpressionCS)getRhsSym(1),
                            (OCLExpressionCS)getRhsSym(3)
                        );
                    setOffsets(result, (CSTNode)getRhsSym(1), (CSTNode)getRhsSym(3));
                    setResult(result);
          $EndCode
        ./

    PrimitiveLiteralExpCS -> IntegerLiteralExpCS
    PrimitiveLiteralExpCS -> RealLiteralExpCS
    PrimitiveLiteralExpCS -> StringLiteralExpCS
    PrimitiveLiteralExpCS -> BooleanLiteralExpCS
    PrimitiveLiteralExpCS -> UnlimitedNaturalLiteralExpCS
    PrimitiveLiteralExpCS -> InvalidLiteralExpCS
    PrimitiveLiteralExpCS -> NullLiteralExpCS

    TupleLiteralExpCS ::= Tuple '{' TupleLiteralPartsCS '}'
        /.$BeginCode
                    TupleLiteralExpCS result = createTupleLiteralExpCS((EList<VariableCS>)getRhsSym(3));
                    setOffsets(result, getRhsIToken(1), getRhsIToken(4));
                    setResult(result);
          $EndCode
        ./

    TupleLiteralPartsCS ::= initializedVariableCS
        /.$BeginCode
                    EList<VariableCS> result = new BasicEList<VariableCS>();
                    result.add((VariableCS)getRhsSym(1));
                    setResult(result);
          $EndCode
        ./
    TupleLiteralPartsCS ::= TupleLiteralPartsCS ',' initializedVariableCS
        /.$BeginCode
                    EList<VariableCS> result = (EList<VariableCS>)getRhsSym(1);
                    result.add((VariableCS)getRhsSym(3));
                    setResult(result);
          $EndCode
        ./

    IntegerLiteralExpCS ::= INTEGER_LITERAL
        /.$BeginCode
                    IntegerLiteralExpCS result = createIntegerLiteralExpCS(getRhsTokenText(1));
                    setOffsets(result, getRhsIToken(1));
                    setResult(result);
          $EndCode
        ./

    RealLiteralExpCS ::= REAL_LITERAL
        /.$BeginCode
                    RealLiteralExpCS result = createRealLiteralExpCS(getRhsTokenText(1));
                    setOffsets(result, getRhsIToken(1));
                    setResult(result);
          $EndCode
        ./

    StringLiteralExpCS ::= STRING_LITERAL
        /.$BeginCode
                    IToken literalToken = getRhsIToken(1);
                    StringLiteralExpCS result = createStringLiteralExpCS(literalToken);
                    setOffsets(result, literalToken);
                    setResult(result);
          $EndCode
        ./
    StringLiteralExpCS ::= StringLiteralExpCS STRING_LITERAL
        /.$BeginCode
                    StringLiteralExpCS string = (StringLiteralExpCS)getRhsSym(1);
                    IToken literalToken = getRhsIToken(2);
                    StringLiteralExpCS result = extendStringLiteralExpCS(string, literalToken);
                    setOffsets(result, string, literalToken);
                    setResult(result);
          $EndCode
        ./

    BooleanLiteralExpCS ::= true
        /.$BeginCode
                    BooleanLiteralExpCS result = createBooleanLiteralExpCS(getRhsTokenText(1));
                    setOffsets(result, getRhsIToken(1));
                    setResult(result);
          $EndCode
        ./
    BooleanLiteralExpCS ::= false
        /.$BeginCode
                    BooleanLiteralExpCS result = createBooleanLiteralExpCS(getRhsTokenText(1));
                    setOffsets(result, getRhsIToken(1));
                    setResult(result);
          $EndCode
        ./

    UnlimitedNaturalLiteralExpCS ::= '*'
        /.$BeginCode
                    UnlimitedNaturalLiteralExpCS result = createUnlimitedNaturalLiteralExpCS(getRhsTokenText(1));
                    setOffsets(result, getRhsIToken(1));
                    setResult(result);
          $EndCode
        ./

    InvalidLiteralExpCS ::= invalid
        /.$BeginCode
                    InvalidLiteralExpCS result = createInvalidLiteralExpCS(getRhsTokenText(1));
                    setOffsets(result, getRhsIToken(1));
                    setResult(result);
          $EndCode
        ./

    NullLiteralExpCS ::= null
        /.$BeginCode
                    NullLiteralExpCS result = createNullLiteralExpCS(getRhsTokenText(1));
                    setOffsets(result, getRhsIToken(1));
                    setResult(result);
          $EndCode
        ./

    -- unqualified pathNameCS is parsed as SimpleNameExpCS
    -- qualified pathNameCS is parsed as PropertyCallExpCS[C]
    TypeLiteralExpCS ::= primitiveTypeCS
        /.$NewCase./
    TypeLiteralExpCS ::= collectionTypeCS
        /.$NewCase./
    TypeLiteralExpCS ::= tupleTypeCS
        /.$BeginCode
                    SimpleNameCS simpleNameCS = (SimpleNameCS)getRhsSym(1);
                    VariableExpCS result = createVariableExpCS(
                            simpleNameCS,
                            new BasicEList<OCLExpressionCS>(),
                            null
                        );
                    setOffsets(result, simpleNameCS);
                    setResult(result);
          $EndCode
        ./

-----------------------------------------------------------------------
--  Calls
-----------------------------------------------------------------------
    CallExpCS -> FeatureCallExpCS
    CallExpCS -> LoopExpCS

    LoopExpCS -> IteratorExpCS
    LoopExpCS -> IterateExpCS

--  IteratorExpCS[A.1] is parsed as OperationCallExpCS[B]
    IteratorExpCS ::=                          -- [A.2]
        primaryExpCS '->' simpleNameCS
        '(' uninitializedVariableCS '|' OclExpressionCS ')'
        /.$BeginCode
                    OCLExpressionCS source = (OCLExpressionCS)getRhsSym(1);
                    SimpleNameCS simpleNameCS = (SimpleNameCS)getRhsSym(3);
                    IteratorExpCS result = createIteratorExpCS(
                            source,
                            simpleNameCS,
                            (VariableCS)getRhsSym(5),
                            null,
                            (OCLExpressionCS)getRhsSym(7)
                        );
                    setOffsets(result, source, getRhsIToken(8));
                    setResult(result);
          $EndCode
        ./
    IteratorExpCS ::=                          -- [A.3.1]
        primaryExpCS '->' simpleNameCS
        '(' simpleNameCS ',' uninitializedVariableCS '|' OclExpressionCS ')'
        /.$BeginCode
                    SimpleNameCS name = (SimpleNameCS)getRhsSym(5);
                    VariableCS variableCS = createVariableCS(name, null, null);
                    setOffsets(variableCS, name);
                    OCLExpressionCS source = (OCLExpressionCS)getRhsSym(1);
                    SimpleNameCS simpleNameCS = (SimpleNameCS)getRhsSym(3);
                    IteratorExpCS result = createIteratorExpCS(
                            source,
                            simpleNameCS,
                            variableCS,
                            (VariableCS)getRhsSym(7),
                            (OCLExpressionCS)getRhsSym(9)
                        );
                    setOffsets(result, source, getRhsIToken(10));
                    setResult(result);
          $EndCode
        ./
    IteratorExpCS ::=                          -- [A.3.2]
        primaryExpCS '->' simpleNameCS '(' typedUninitializedVariableCS ','
        uninitializedVariableCS '|' OclExpressionCS ')'
        /.$BeginCode
                    OCLExpressionCS source = (OCLExpressionCS)getRhsSym(1);
                    SimpleNameCS simpleNameCS = (SimpleNameCS)getRhsSym(3);
                    IteratorExpCS result = createIteratorExpCS(
                            source,
                            simpleNameCS,
                            (VariableCS)getRhsSym(5),
                            (VariableCS)getRhsSym(7),
                            (OCLExpressionCS)getRhsSym(9)
                        );
                    setOffsets(result, source, getRhsIToken(10));
                    setResult(result);
          $EndCode
        ./
--  IteratorExpCS[B] is parsed as OperationCallExpCS[C]
--  IteratorExpCS[C] is parsed as AssociationClassCallExpCS[A.1]
--  IteratorExpCS[D] is parsed as AssociationClassCallExpCS[A]
--  IteratorExpCS[E] is parsed as AssociationClassCallExpCS[A]

    IterateExpCS ::= primaryExpCS '->' simpleNameCS
        '(' typedInitializedVariableCS '|' OclExpressionCS ')'
        /.$BeginCode
                    OCLExpressionCS source = (OCLExpressionCS)getRhsSym(1);
                    SimpleNameCS simpleNameCS = (SimpleNameCS)getRhsSym(3);
                    IterateExpCS result = createIterateExpCS(
                            source,
                            simpleNameCS,
                            (VariableCS)getRhsSym(5),
                            null,
                            (OCLExpressionCS)getRhsSym(7)
                        );
                    setOffsets(result, source, getRhsIToken(8));
                    setResult(result);
          $EndCode
        ./
    IterateExpCS ::= primaryExpCS '->' simpleNameCS
        '(' uninitializedVariableCS ';' typedInitializedVariableCS '|' OclExpressionCS ')'
        /.$BeginCode
                    OCLExpressionCS source = (OCLExpressionCS)getRhsSym(1);
                    SimpleNameCS simpleNameCS = (SimpleNameCS)getRhsSym(3);
                    IterateExpCS result = createIterateExpCS(
                            source,
                            simpleNameCS,
                            (VariableCS)getRhsSym(5),
                            (VariableCS)getRhsSym(7),
                            (OCLExpressionCS)getRhsSym(9)
                        );
                    setOffsets(result, source, getRhsIToken(10));
                    setResult(result);
          $EndCode
        ./

    FeatureCallExpCS -> OperationCallExpCS
    FeatureCallExpCS -> PropertyCallExpCS
    FeatureCallExpCS -> NavigationCallExpCS

--  OperationCallExpCS[A] is realized by the infix OclExpressionCS productions
    OperationCallExpCS ::= -- [B.1]
        primaryExpCS '->' simpleNameCS '(' ')'
        /.$BeginCode
                    OCLExpressionCS source = (OCLExpressionCS)getRhsSym(1);
                    OperationCallExpCS result = createArrowOperationCallExpCS(
                            source,
                            (SimpleNameCS)getRhsSym(3),
                            null,
                            new BasicEList<OCLExpressionCS>()
                        );
                    setOffsets(result, source, getRhsIToken(5));
                    setResult(result);
          $EndCode
        ./
    OperationCallExpCS ::= -- [B.2],IteratorExpCS[A.1]
        primaryExpCS '->' simpleNameCS '(' OclExpressionCS ')'
        /.$BeginCode
                    OCLExpressionCS source = (OCLExpressionCS)getRhsSym(1);
                    SimpleNameCS simpleNameCS = (SimpleNameCS)getRhsSym(3);
                    OCLExpressionCS arg = (OCLExpressionCS)getRhsSym(5);
                    OCLExpressionCS result;
                    if (isIterator(simpleNameCS.getValue())) {
                        result = createIteratorExpCS(
                                source,
                                simpleNameCS,
                                null,
                                null,
                                arg
                            );
                    }
                    else {
                        EList<OCLExpressionCS> args = new BasicEList<OCLExpressionCS>();
                        args.add(arg);
                        result = createArrowOperationCallExpCS(
                                source,
                                simpleNameCS,
                                null,
                                args
                            );
                    }
                    setOffsets(result, source, getRhsIToken(6));
                    setResult(result);
          $EndCode
        ./
    OperationCallExpCS ::= -- [B.3.1]
        primaryExpCS '->' simpleNameCS '(' notNameExpressionCS ',' argumentsCS ')'
        /.$BeginCode
                    EList<OCLExpressionCS> args = (EList<OCLExpressionCS>)getRhsSym(7);
                    args.add(0, (OCLExpressionCS)getRhsSym(5));
                    OCLExpressionCS source = (OCLExpressionCS)getRhsSym(1);
                    OperationCallExpCS result = createArrowOperationCallExpCS(
                            source,
                            (SimpleNameCS)getRhsSym(3),
                            null,
                            args
                        );
                    setOffsets(result, source, getRhsIToken(8));
                    setResult(result);
          $EndCode
        ./
    OperationCallExpCS ::= -- [B.3.2]
        primaryExpCS '->' simpleNameCS '(' simpleNameCS ',' argumentsCS ')'
        /.$BeginCode
                    SimpleNameCS simpleNameCS = (SimpleNameCS)getRhsSym(5);
                    OCLExpressionCS variableExpCS = createVariableExpCS(
                            simpleNameCS,
                            new BasicEList<OCLExpressionCS>(),
                            null
                        );
                    setOffsets(variableExpCS, simpleNameCS);
                    EList<OCLExpressionCS> args = (EList<OCLExpressionCS>)getRhsSym(7);
                    args.add(0, variableExpCS);
                    OCLExpressionCS source = (OCLExpressionCS)getRhsSym(1);
                    OperationCallExpCS result = createArrowOperationCallExpCS(
                            source,
                            (SimpleNameCS)getRhsSym(3),
                            null,
                            args
                        );
                    setOffsets(result, source, getRhsIToken(8));
                    setResult(result);
          $EndCode
        ./
    OperationCallExpCS ::=
        primaryExpCS '.' conceptualOperationNameCS isMarkedPreCSopt '(' argumentsCSopt ')'
        /.$NewCase./
    OperationCallExpCS ::= -- [C],[E],IteratorExpCS[B]
        primaryExpCS '.' simpleNameCS isMarkedPreCSopt '(' argumentsCSopt ')'
        /.$BeginCode
                    SimpleNameCS simpleNameCS = (SimpleNameCS)getRhsSym(3);
                    OCLExpressionCS source = (OCLExpressionCS)getRhsSym(1);
                    CallExpCS result = createDotOperationCallExpCS(
                            source,
                            null,
                            simpleNameCS,
                            (IsMarkedPreCS)getRhsSym(4),
                            (EList<OCLExpressionCS>)getRhsSym(6)
                        );
                    setOffsets(result, source, getRhsIToken(7));
                    setResult(result);
          $EndCode
        ./
    OperationCallExpCS ::= -- [D],[F],[G.1]
        simpleNameCS isMarkedPreCSopt '(' argumentsCSopt ')'
        /.$BeginCode
                    OperationCallExpCS result = createDotOperationCallExpCS(
                            null,
                            null,
                            (SimpleNameCS)getRhsSym(1),
                            (IsMarkedPreCS)getRhsSym(2),
                            (EList<OCLExpressionCS>)getRhsSym(4)
                        );
                    setOffsets(result, getRhsIToken(1), getRhsIToken(5));
                    setResult(result);
          $EndCode
        ./
    OperationCallExpCS ::= -- [G.2]
        pathNameCS '::' unreservedSimpleNameCS '(' argumentsCSopt ')'
        /.$BeginCode
                    PathNameCS pathNameCS = (PathNameCS)getRhsSym(1);
                    SimpleNameCS simpleNameCS = (SimpleNameCS)getRhsSym(3);
                    OperationCallExpCS result = createDotOperationCallExpCS(
                            null,
                            pathNameCS,
                            simpleNameCS,
                            null,
                            (EList<OCLExpressionCS>)getRhsSym(5)
                        );
                    setOffsets(result, pathNameCS, getRhsIToken(6));
                    setResult(result);
          $EndCode
        ./
--  OperationCallExpCS[H] is realized by the prefix OclExpressionCS productions
    OperationCallExpCS ::= -- [I],[J]
        primaryExpCS '.' pathNameCS '::' unreservedSimpleNameCS isMarkedPreCSopt
        '(' argumentsCSopt ')'
        /.$BeginCode
                    PathNameCS pathNameCS = (PathNameCS)getRhsSym(3);
                    SimpleNameCS simpleNameCS = (SimpleNameCS)getRhsSym(5);
                    OCLExpressionCS source = (OCLExpressionCS)getRhsSym(1);
                    CallExpCS result = createDotOperationCallExpCS(
                            source,
                            pathNameCS,
                            simpleNameCS,
                            (IsMarkedPreCS)getRhsSym(6),
                            (EList<OCLExpressionCS>)getRhsSym(8)
                        );
                    setOffsets(result, source, getRhsIToken(9));
                    setResult(result);
          $EndCode
        ./

--  NavigationCallExpCS -> PropertyCallExpCS -- parsed as FeatureCallExpCS
    NavigationCallExpCS -> AssociationClassCallExpCS

--  PropertyCallExpCS[A] is parsed as AssociationClassCallExpCS[A.1]
--  PropertyCallExpCS[B.1] is parsed as a SimpleNameExpCS
--  PropertyCallExpCS[B.2] is parsed as a AssociationClassCallExpCS[B.1]
    PropertyCallExpCS ::= -- [C] excluding [B]
        pathNameCS '::' unreservedSimpleNameCS isMarkedPreCSopt
        /.$BeginCode
                    PathNameCS pathNameCS = (PathNameCS)getRhsSym(1);
                    SimpleNameCS simpleNameCS = (SimpleNameCS)getRhsSym(3);
                    IsMarkedPreCS isMarkedPreCS = (IsMarkedPreCS)getRhsSym(4);
                    FeatureCallExpCS result = createFeatureCallExpCS(
                            null,
                            pathNameCS,
                            simpleNameCS,
                            new BasicEList<OCLExpressionCS>(),
                            isMarkedPreCS
                        );
                    if (isMarkedPreCS != null) {
                        setOffsets(result, pathNameCS, isMarkedPreCS);
                    } else {
                        setOffsets(result, pathNameCS, simpleNameCS);
                    }
                    setResult(result);
          $EndCode
        ./
    PropertyCallExpCS ::= -- [D]
        primaryExpCS '.' pathNameCS '::' unreservedSimpleNameCS isMarkedPreCSopt
        /.$BeginCode
                    OCLExpressionCS source = (OCLExpressionCS)getRhsSym(1);
                    PathNameCS pathNameCS = (PathNameCS)getRhsSym(3);
                    SimpleNameCS simpleNameCS = (SimpleNameCS)getRhsSym(5);
                    IsMarkedPreCS isMarkedPreCS = (IsMarkedPreCS)getRhsSym(6);
                    FeatureCallExpCS result = createFeatureCallExpCS(
                            source,
                            pathNameCS,
                            simpleNameCS,
                            new BasicEList<OCLExpressionCS>(),
                            isMarkedPreCS
                        );
                    if (isMarkedPreCS != null) {
                        setOffsets(result, source, isMarkedPreCS);
                    } else {
                        setOffsets(result, source, simpleNameCS);
                    }
                    setResult(result);
          $EndCode
        ./

    AssociationClassCallExpCS ::= -- [A.1],PropertyCallExpCS[A],IteratorExpCS[C,D,E]
        primaryExpCS '.' simpleNameCS isMarkedPreCSopt
        /.$BeginCode
                    OCLExpressionCS source = (OCLExpressionCS)getRhsSym(1);
                    SimpleNameCS simpleNameCS = (SimpleNameCS)getRhsSym(3);
                    IsMarkedPreCS isMarkedPreCS = (IsMarkedPreCS)getRhsSym(4);
                    FeatureCallExpCS result = createFeatureCallExpCS(
                            source,
                            null,
                            simpleNameCS,
                            new BasicEList<OCLExpressionCS>(),
                            isMarkedPreCS
                        );
                    if (isMarkedPreCS != null) {
                        setOffsets(result, source, isMarkedPreCS);
                    } else {
                        setOffsets(result, source, simpleNameCS);
                    }
                    setResult(result);
          $EndCode
        ./
    AssociationClassCallExpCS ::= -- [A.2],IteratorExpCS[D,E]
        primaryExpCS '.' simpleNameCS '[' argumentsCS ']' isMarkedPreCSopt
        /.$BeginCode
                    OCLExpressionCS source = (OCLExpressionCS)getRhsSym(1);
                    SimpleNameCS simpleNameCS = (SimpleNameCS)getRhsSym(3);
                    IsMarkedPreCS isMarkedPreCS = (IsMarkedPreCS)getRhsSym(7);
                    FeatureCallExpCS result = createFeatureCallExpCS(
                            source,
                            null,
                            simpleNameCS,
                            (EList<OCLExpressionCS>)getRhsSym(5),
                            isMarkedPreCS
                        );
                    if (isMarkedPreCS != null) {
                        setOffsets(result, source, isMarkedPreCS);
                    } else {
                        setOffsets(result, source, getRhsIToken(6));
                    }
                    setResult(result);
          $EndCode
        ./
--  AssociationClassCallExpCS[B.1.1] parsed as SimpleNameExpCS
--  AssociationClassCallExpCS[B.1.2] is added by Complete OCL
    AssociationClassCallExpCS ::=  -- [B.2]
        simpleNameCS '[' argumentsCS ']' isMarkedPreCSopt
        /.$BeginCode
                    SimpleNameCS simpleNameCS = (SimpleNameCS)getRhsSym(1);
                    IsMarkedPreCS isMarkedPreCS = (IsMarkedPreCS)getRhsSym(5);
                    VariableExpCS result = createVariableExpCS(
                            simpleNameCS,
                            (EList<OCLExpressionCS>)getRhsSym(3),
                            isMarkedPreCS
                        );
                    if (isMarkedPreCS != null) {
                        setOffsets(result, simpleNameCS, isMarkedPreCS);
                    } else {
                        setOffsets(result, simpleNameCS, getRhsIToken(4));
                    }
                    setResult(result);
          $EndCode
        ./

    isMarkedPreCSopt ::= %empty
        /.$BeginCode
                    setResult(null);
          $EndCode
        ./

    argumentsCSopt ::= %empty
        /.$BeginCode
                    setResult(new BasicEList<OCLExpressionCS>());
          $EndCode
        ./
    argumentsCSopt -> argumentsCS

    argumentsCS ::= OclExpressionCS
        /.$BeginCode
                    EList<OCLExpressionCS> result = new BasicEList<OCLExpressionCS>();
                    result.add((OCLExpressionCS)getRhsSym(1));
                    setResult(result);
          $EndCode
        ./
    argumentsCS ::= argumentsCS ',' OclExpressionCS
        /.$BeginCode
                    EList<OCLExpressionCS> result = (EList<OCLExpressionCS>)getRhsSym(1);
                    result.add((OCLExpressionCS)getRhsSym(3));
                    setResult(result);
          $EndCode
        ./

-----------------------------------------------------------------------
--  Expressions
-----------------------------------------------------------------------
    -- An OclExpressionCS comprising just a SimpleNameCS is kept separate as
    --  SimpleNameExpCS to avoid ambiguity when parsing "a->b(c,d" until the next
    --  letter resolves the usage as a two iterator  or as a two or more argument
    --  OperationCallExpCS.
    -- An OclExpressionCS comprising one or more LetExpCS is kept separate to ensure
    --  that let is right associative, whereas infix operators are left associative.
    --   a = 64 / 16 / let b : Integer in 8 / let c : Integer in 4
    -- is
    --   a = (64 / 16) / (let b : Integer in 8 / (let c : Integer in 4 ))
    OclExpressionCS -> notNameExpressionCS
    OclExpressionCS -> SimpleNameExpCS

--  VariableExpCS[.1] simpleNameCS parsed as SimpleNameExpCS
    VariableExpCS ::= -- [.2]
        selfKeywordCS
        /.$BeginCode
                    SimpleNameCS simpleNameCS = (SimpleNameCS)getRhsSym(1);
                    VariableExpCS result = createVariableExpCS(
                            simpleNameCS,
                            new BasicEList<OCLExpressionCS>(),
                            null
                        );
                    setOffsets(result, simpleNameCS);
                    setResult(result);
          $EndCode
        ./

    SimpleNameExpCS ::= -- AssociationClassCallExpCS[B.1.1],
                        -- PropertyCallExpCS[B],VariableExpCS[.1]
        simpleNameCS
        /.$BeginCode
                    SimpleNameCS simpleNameCS = (SimpleNameCS)getRhsSym(1);
                    VariableExpCS result = createVariableExpCS(
                            simpleNameCS,
                            new BasicEList<OCLExpressionCS>(),
                            null
                        );
                    setOffsets(result, simpleNameCS);
                    setResult(result);
          $EndCode
        ./

    notNameExpressionCS -> impliesNotNameNotLetCS
    notNameExpressionCS -> impliesWithLetCS

    impliesNotLetCS -> impliesNotNameNotLetCS
    impliesNotLetCS -> SimpleNameExpCS
    impliesNotNameNotLetCS -> xorNotNameNotLetCS
    impliesNotNameNotLetCS ::= impliesNotLetCS implies xorNotLetCS
        /.$NewCase./
    impliesWithLetCS -> xorWithLetCS
    impliesWithLetCS ::= impliesNotLetCS implies xorWithLetCS
        /.$NewCase./

    xorNotLetCS -> xorNotNameNotLetCS
    xorNotLetCS -> SimpleNameExpCS
    xorNotNameNotLetCS -> orNotNameNotLetCS
    xorNotNameNotLetCS ::= xorNotLetCS xor orNotLetCS
        /.$NewCase./
    xorWithLetCS -> orWithLetCS
    xorWithLetCS ::= xorNotLetCS xor orWithLetCS
        /.$NewCase./

    orNotLetCS -> orNotNameNotLetCS
    orNotLetCS -> SimpleNameExpCS
    orNotNameNotLetCS -> andNotNameNotLetCS
    orNotNameNotLetCS ::= orNotLetCS or andNotLetCS
        /.$NewCase./
    orWithLetCS -> andWithLetCS
    orWithLetCS ::= orNotLetCS or andWithLetCS
        /.$NewCase./

    andNotLetCS -> andNotNameNotLetCS
    andNotLetCS -> SimpleNameExpCS
    andNotNameNotLetCS -> equalityNotNameNotLetCS
    andNotNameNotLetCS ::= andNotLetCS and equalityNotLetCS
        /.$NewCase./
    andWithLetCS -> equalityWithLetCS
    andWithLetCS ::= andNotLetCS and equalityWithLetCS
        /.$NewCase./

    equalityNotLetCS -> equalityNotNameNotLetCS
    equalityNotLetCS -> SimpleNameExpCS
    equalityNotNameNotLetCS -> relationalNotNameNotLetCS
    equalityNotNameNotLetCS ::= equalityNotLetCS '=' relationalNotLetCS
        /.$NewCase./
    equalityNotNameNotLetCS ::= equalityNotLetCS '<>' relationalNotLetCS
        /.$NewCase./
    equalityWithLetCS -> relationalWithLetCS
    equalityWithLetCS ::= equalityNotLetCS '=' relationalWithLetCS
        /.$NewCase./
    equalityWithLetCS ::= equalityNotLetCS '<>' relationalWithLetCS
        /.$NewCase./

    relationalNotLetCS -> relationalNotNameNotLetCS
    relationalNotLetCS -> SimpleNameExpCS
    relationalNotNameNotLetCS -> additiveNotNameNotLetCS
    relationalNotNameNotLetCS ::= relationalNotLetCS '>' additiveNotLetCS
        /.$NewCase./
    relationalNotNameNotLetCS ::= relationalNotLetCS '<' additiveNotLetCS
        /.$NewCase./
    relationalNotNameNotLetCS ::= relationalNotLetCS '>=' additiveNotLetCS
        /.$NewCase./
    relationalNotNameNotLetCS ::= relationalNotLetCS '<=' additiveNotLetCS
        /.$NewCase./
    relationalWithLetCS -> additiveWithLetCS
    relationalWithLetCS ::= relationalNotLetCS '>' additiveWithLetCS
        /.$NewCase./
    relationalWithLetCS ::= relationalNotLetCS '<' additiveWithLetCS
        /.$NewCase./
    relationalWithLetCS ::= relationalNotLetCS '>=' additiveWithLetCS
        /.$NewCase./
    relationalWithLetCS ::= relationalNotLetCS '<=' additiveWithLetCS
        /.$NewCase./

    additiveNotLetCS -> additiveNotNameNotLetCS
    additiveNotLetCS -> SimpleNameExpCS
    additiveNotNameNotLetCS -> multiplicativeNotNameNotLetCS
    additiveNotNameNotLetCS ::= additiveNotLetCS '+' multiplicativeNotLetCS
        /.$NewCase./
    additiveNotNameNotLetCS ::= additiveNotLetCS '-' multiplicativeNotLetCS
        /.$NewCase./
    additiveWithLetCS -> multiplicativeWithLetCS
    additiveWithLetCS ::= additiveNotLetCS '+' multiplicativeWithLetCS
        /.$NewCase./
    additiveWithLetCS ::= additiveNotLetCS '-' multiplicativeWithLetCS
        /.$NewCase./

    multiplicativeNotLetCS -> multiplicativeNotNameNotLetCS
    multiplicativeNotLetCS -> SimpleNameExpCS
    multiplicativeNotNameNotLetCS -> unaryNotNameNotLetCS
    multiplicativeNotNameNotLetCS ::= multiplicativeNotLetCS '*' unaryNotLetCS
        /.$NewCase./
    multiplicativeNotNameNotLetCS ::= multiplicativeNotLetCS '/' unaryNotLetCS
        /.$NewCase./
    multiplicativeWithLetCS -> unaryWithLetCS
    multiplicativeWithLetCS ::= multiplicativeNotLetCS '*' unaryWithLetCS
        /.$NewCase./
    multiplicativeWithLetCS ::= multiplicativeNotLetCS '/' unaryWithLetCS
        /.$BeginCode
                    SimpleNameCS simpleNameCS = createSimpleNameCS(
                                SimpleTypeEnum.KEYWORD_LITERAL,
                                getRhsIToken(2)
                            );
                    setOffsets(simpleNameCS, getRhsIToken(2));
                    OCLExpressionCS left = (OCLExpressionCS)getRhsSym(1);
                    OCLExpressionCS right = (OCLExpressionCS)getRhsSym(3);
                    EList<OCLExpressionCS> args = new BasicEList<OCLExpressionCS>();
                    args.add(right);
                    OperationCallExpCS result = createOperationCallExpCS(
                            left,
                            simpleNameCS,
                            args
                        );
                    setOffsets(result, left, right);
                    setResult(result);
          $EndCode
        ./

    unaryNotLetCS -> unaryNotNameNotLetCS
    unaryNotLetCS -> SimpleNameExpCS
    unaryNotNameNotLetCS -> primaryNotNameCS
    unaryNotNameNotLetCS ::= '-' unaryNotLetCS
        /.$NewCase./
    unaryNotNameNotLetCS ::= not unaryNotLetCS
        /.$NewCase./
    unaryWithLetCS -> LetExpCS             -- OclExpressionCS[D]
    unaryWithLetCS ::= '-' unaryWithLetCS
        /.$NewCase./
    unaryWithLetCS ::= not unaryWithLetCS
        /.$BeginCode
                    SimpleNameCS simpleNameCS = createSimpleNameCS(
                                SimpleTypeEnum.KEYWORD_LITERAL,
                                getRhsIToken(1)
                            );
                    setOffsets(simpleNameCS, getRhsIToken(1));
                    OCLExpressionCS expr = (OCLExpressionCS)getRhsSym(2);
                    OperationCallExpCS result = createOperationCallExpCS(
                            expr,
                            simpleNameCS,
                            new BasicEList<OCLExpressionCS>()
                        );
                    setOffsets(result, simpleNameCS, expr);
                    setResult(result);
          $EndCode
        ./

    primaryExpCS -> primaryNotNameCS
    primaryExpCS -> SimpleNameExpCS

    primaryNotNameCS -> CallExpCS       -- OclExpressionCS[A]
    primaryNotNameCS -> VariableExpCS   -- OclExpressionCS[B]
    primaryNotNameCS -> LiteralExpCS    -- OclExpressionCS[C]
--  primaryNotNameCS -> OclMessageExpCS -- OclExpressionCS[E] is added by Complete OCL
    primaryNotNameCS -> IfExpCS         -- OclExpressionCS[F]
    primaryNotNameCS ::= '(' OclExpressionCS ')'
        /.$BeginCode
                    OCLExpressionCS result = (OCLExpressionCS)getRhsSym(2);
                    if (result instanceof OperationCallExpCS) {
                        ((OperationCallExpCS)result).setIsAtomic(true);
                    }
                    setOffsets(result, getRhsIToken(1), getRhsIToken(3));
                    setResult(result);
          $EndCode
        ./

    IfExpCS ::= if OclExpressionCS then OclExpressionCS else OclExpressionCS endif
        /.$BeginCode
                    IfExpCS result = createIfExpCS(
                            (OCLExpressionCS)getRhsSym(2),
                            (OCLExpressionCS)getRhsSym(4),
                            (OCLExpressionCS)getRhsSym(6)
                        );
                    setOffsets(result, getRhsIToken(1), getRhsIToken(7));
                    setResult(result);
          $EndCode
        ./

    LetExpCS ::= let letVariablesCS in OclExpressionCS
        /.$BeginCode
                    OCLExpressionCS expr = (OCLExpressionCS)getRhsSym(4);
                    LetExpCS result = createLetExpCS(
                            (EList<VariableCS>)getRhsSym(2),
                            expr
                        );
                    setOffsets(result, getRhsIToken(1), expr);
                    setResult(result);
          $EndCode
        ./

    letVariablesCS ::= typedInitializedVariableCS
        /.$BeginCode
                    EList<VariableCS> result = new BasicEList<VariableCS>();
                    result.add((VariableCS)getRhsSym(1));
                    setResult(result);
          $EndCode
        ./
    letVariablesCS ::= letVariablesCS ',' typedInitializedVariableCS
        /.$BeginCode
                    EList<VariableCS> result = (EList<VariableCS>)getRhsSym(1);
                    result.add((VariableCS)getRhsSym(3));
                    setResult(result);
          $EndCode
        ./
%End


--
-- 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=typescript,margin=4
%Options table
%options action-block=("*.ts", "/.", "./")
%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
    /.
        public void ruleAction( ruleNumber : number )
        {
            switch(ruleNumber)
            {./

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

	    public void ruleAction%rule_number(ruleNumber : number )
	    {
	        switch (ruleNumber)
	        {./

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

%Globals
    /.
    import { RuleAction, ParseTable, LexParser, ILexStream, IPrsStream, Monitor, LpgLexStream } from "lpg2ts";
    ./
%End

%Headers
    /.
    export class %action_type extends %super_class implements RuleAction%additional_interfaces
    {
        private %super_stream_class utf8LexStream;

        private static ParseTable prs = new %prs_type();
        public ParseTable getParseTable() { return prs; }

        private LexParser lexParser = new LexParser();
        public LexParser getParser() { return lexParser; }

        public number getToken(i : number) { return lexParser.getToken(i); }
        public number getRhsFirstTokenIndex(i : number) { return lexParser.getFirstToken(i); }
        public number getRhsLastTokenIndex(i : number) { return lexParser.getLastToken(i); }

        public number getLeftSpan() { return lexParser.getToken(1); }
        public number getRightSpan() { return lexParser.getLastToken(); }

        public void resetKeywordLexer()
        {
            if (!this.kwLexer)
                  this.kwLexer = new %kw_lexer_class(utf8LexStream.getInputBytes(), %_IDENTIFIER);
            else this.kwLexer.setInputBytes(utf8LexStream.getInputBytes());
        }

        public void reset(filename : string, number tab)
        {
            utf8LexStream = new %super_stream_class(filename, tab);
            lexParser.reset((ILexStream) utf8LexStream, prs, (RuleAction) this);
            resetKeywordLexer();
        }

        public void reset(byte[] input_bytes, filename : string)
        {
            reset(input_bytes, filename, 1);
        }

        public void reset(byte[] input_bytes, filename : string, number tab)
        {
            utf8LexStream = new %super_stream_class(input_bytes, filename, tab);
            lexParser.reset((ILexStream) utf8LexStream, prs, (RuleAction) this);
            resetKeywordLexer();
        }

        public %action_type(filename : string, number tab)
        {
            reset(filename, tab);
        }

        public %action_type(byte[] input_bytes, filename : string, number tab)
        {
            reset(input_bytes, filename, tab);
        }

        public %action_type(byte[] input_bytes, filename : string)
        {
            reset(input_bytes, filename, 1);
        }

        public %action_type() {}

        public ILexStream getILexStream() { return utf8LexStream; }

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

        private void initializeLexer(%prs_stream_class this.prsStream, number start_offset, number end_offset)
        {
            if (utf8LexStream.getInputBytes() == null)
                throw new ReferenceError("LexStream was not initialized");
            utf8LexStream.setPrsStream(this.prsStream);
            this.prsStream.makeToken(start_offset, end_offset, 0); // Token list must start with a bad token
        }

        public void lexer(%prs_stream_class this.prsStream)
        {
            lexer(null, this.prsStream);
        }

        public void lexer(Monitor monitor, %prs_stream_class this.prsStream)
        {
            if (utf8LexStream.getInputBytes() == null)
                throw new ReferenceError("Utf8LexStream was not initialized");

            utf8LexStream.setPrsStream(this.prsStream);

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

            lexParser.parseCharacters(monitor);  // Lex the input characters

            i : number = utf8LexStream.getStreamIndex();
            this.prsStream.makeToken(i, i, %eof_token); // and end with the end of file token
            this.prsStream.setStreamLength(this.prsStream.getSize());

            return;
        }
    ./
%End

%Rules
    /.%BeginActions./
%End

%Trailers
    /.
        %EndActions
    }
    ./
%End

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