BNF Grammar

From Rosetta Code
Task
BNF Grammar
You are encouraged to solve this task according to the task description, using any language you may know.

In computer science, Backus–Naur Form (BNF) is a metasyntax used to express context-free grammars: that is, a formal way to describe formal languages. John Backus and Peter Naur developed a context free grammar to define the syntax of a programming language by using two sets of rules: i.e., lexical rules and syntactic rules.

BNF is widely used as a notation for the grammars of computer programming languages, instruction sets and communication protocols, as well as a notation for representing parts of natural language grammars. Many textbooks for programming language theory and/or semantics document the programming language in BNF.

There are many extensions and variants of BNF, including Extended and Augmented Backus–Naur Forms (EBNF and ABNF).

The task here is establish a BNF grammar for as many languages as possible to facilitate language categorization and translation.

Ada

A BNF description of the language syntax is a part of its standard, see Ada Reference Manual, Annex P.

ALGOL 60

A BNF description of the language syntax is a part of following, ALGOL 60 -Syntax of ALGOL 60

BASIC

! -----------------------------------------------------------------------
! BASIC '64 
!
! Beginner's All-purpose Symbolic Instruction Code 
!
!    "It is practically impossible to teach good programming style to students 
!     that have had prior exposure to BASIC; as potential programmers they are 
!     mentally mutilated beyond hope of regeneration." 
!
!     - Edsger W. Dijkstra 
!
! BASIC is one of the oldest programming language and one of the most popular. 
! It was developed in 1964 by John G. Kemeny and Thomas E. Kurtz to teach 
! students the basics of programming concepts. At the advent of the microcomputer,
! BASIC was implemented on numerous platforms such as the Commodore, Atari, 
! Apple II, Altair, IBM PC computers. Over time, BASIC evolved into GW-BASIC, 
! QBasic, Visual Basic, and recently Visual Basic .NET.
!
! In practically all programming languages, the reserved word/symbol that denotes
! a comment is treated as a form of whitespace - having no effect in the manner in
! which the program runs. Once such type of comment is used to indicate the remainder
! of the line is to be ignored. These can be added to the end of any line without
! changing the meaning of the program. In C++, it is the '//' symbol;
! in BASIC '64 it is 'REM'.
!
! However, in the BASIC programming language, the line comment is treated like a 
! statement. For instance, if 'REM' was a normal line comment:
!
!    10  PRINT "Hello World" REM Common first program
!
! would be a valid statement. However, in BASIC, this is illegal. In the example 
! above, the comment must be added as an additional statement.
!
!    10  PRINT "Hello World" : REM Common first program
!
! As a result, the Line Comment terminal that is used in the GOLD Parser cannot be
! used here. In the grammar below, a 'Remark' terminal was created that accepts all 
! series of printable characters starting with the characters "REM ". In some 
! implementations of BASIC, any string starting with "REM" is a comment statement.
! Examples include "REMARK", "REMARKABLE" and "REMODEL". This grammar requires the space.
!
! This grammar does not include the editor statements such as NEW, SAVE, LOAD, etc...
!
! Note: This is an ad hoc version of the language. If there are any flaws, please 
! e-mail GOLDParser@DevinCook.com and I will update the grammar. Most likely I have
! included features not available in BASIC '64.
! -----------------------------------------------------------------------


"Name"    = 'BASIC (Beginners All-purpose Symbolic Instruction Code)'
"Author"  = 'John G. Kemeny and Thomas E. Kurtz' 
"Version" = '1964 - Original - before Microsoft enhanced the language for the IBM PC.'
"About"   = 'BASIC is one of most common and popular teaching languages ever created. '

"Case Sensitive" = False 
"Start Symbol"   = <Lines>

{String Chars} = {Printable} - ["]
{WS}           = {Whitespace} - {CR} - {LF}

NewLine        = {CR}{LF}|{CR}
Whitespace     = {WS}+

Remark         = REM{Space}{Printable}*
ID             = {Letter}[$%]? 
String         = '"'{String Chars}*'"' 
Integer        = {digit}+ 
Real           = {digit}+.{digit}+ 

<Lines>       ::= Integer <Statements> NewLine <Lines> 
                | Integer <Statements> NewLine

<Statements>  ::= <Statement> ':' <Statements>
                | <Statement>

<Statement>   ::= CLOSE '#' Integer
                | DATA <Constant List> 
                | DIM ID '(' <Integer List> ')'
                | END          
                | FOR ID '=' <Expression> TO <Expression>     
                | FOR ID '=' <Expression> TO <Expression> STEP Integer      
                | GOTO <Expression> 
                | GOSUB <Expression> 
                | IF <Expression> THEN <Statement>         
                | INPUT <ID List>       
                | INPUT '#' Integer ',' <ID List>       
                | LET Id '=' <Expression> 
                | NEXT <ID List>               
                | OPEN <Value> FOR <Access> AS '#' Integer
                | POKE <Value List>
                | PRINT <Print list>
                | PRINT '#' Integer ',' <Print List>
                | READ <ID List>           
                | RETURN
                | RESTORE
                | RUN
                | STOP
                | SYS <Value>
                | WAIT <Value List>
                | Remark

<Access>   ::= INPUT
             | OUPUT
                   
<ID List>  ::= ID ',' <ID List> 
             | ID 

<Value List>      ::= <Value> ',' <Value List> 
                    | <Value> 

<Constant List>   ::= <Constant> ',' <Constant List> 
                    | <Constant> 

<Integer List>    ::= Integer ',' <Integer List>
                    | Integer
                 
<Expression List> ::= <Expression> ',' <Expression List> 
                    | <Expression> 

<Print List>      ::= <Expression> ';' <Print List>
                    | <Expression> 
                    |  

<Expression>  ::= <And Exp> OR <Expression> 
                | <And Exp> 

<And Exp>     ::= <Not Exp> AND <And Exp> 
                | <Not Exp> 
 
<Not Exp>     ::= NOT <Compare Exp> 
                | <Compare Exp> 

<Compare Exp> ::= <Add Exp> '='  <Compare Exp> 
                | <Add Exp> '<>' <Compare Exp> 
                | <Add Exp> '><' <Compare Exp> 
                | <Add Exp> '>'  <Compare Exp> 
                | <Add Exp> '>=' <Compare Exp> 
                | <Add Exp> '<'  <Compare Exp> 
                | <Add Exp> '<=' <Compare Exp> 
                | <Add Exp> 

<Add Exp>     ::= <Mult Exp> '+' <Add Exp> 
                | <Mult Exp> '-' <Add Exp> 
                | <Mult Exp> 

<Mult Exp>    ::= <Negate Exp> '*' <Mult Exp> 
                | <Negate Exp> '/' <Mult Exp> 
                | <Negate Exp> 

<Negate Exp>  ::= '-' <Power Exp> 
                | <Power Exp> 

<Power Exp>   ::= <Power Exp> '^' <Value> 
                | <Value> 

<Value>       ::= '(' <Expression> ')'
                | ID 
                | ID '(' <Expression List> ')'
                | <Constant> 

<Constant> ::= Integer 
             | String 
             | Real 
! -----------------------------------------------------------------------
! Commodore PET BASIC 
!
! Beginner's All-purpose Symbolic Instruction Code 
!
!    "It is practically impossible to teach good programming style to students 
!    that have had prior exposure to BASIC; as potential programmers they are 
!    mentally mutilated beyond hope of regeneration."    
!
!    - Edsger W. Dijkstra 
!
!
! BASIC is one of the oldest programming language and one of the most popular. 
! It was developed in 1964 by John G. Kemeny and Thomas E. Kurtz to teach 
! students the basics of programming concepts. At the advent of the microcomputer,
! BASIC was implemented on numerous platforms such as the Commodore, Atari, 
! Apple II, Altair, IBM PC computers. Over time, BASIC evolved into GW-BASIC, 
! QBasic, Visual Basic, and recently Visual Basic .NET.
!
! In practically all programming languages, the reserved word/symbol that denotes
! a comment is treated as a form of whitespace - having no effect in the manner in
! which the program runs. Once such type of comment is used to indicate the remainder
! of the line is to be ignored. These can be added to the end of any line without
! changing the meaning of the program. In C++, it is the '//' symbol.
!
! However, in the BASIC programming language, the line comment is treated like a 
! statement. For instance, if 'REM' was a normal line comment:
!
!    10  PRINT "Hello World" REM Common first program
!
! would be a valid statement. However, in BASIC, this is illegal. In the example 
! above, the comment must be added as an additional statement.
!
!    10  PRINT "Hello World" : REM Common first program
!
! As a result, the Line Comment terminal that is used in the GOLD Parser cannot be
! used here. In the grammar below, a 'Remark' terminal was created that accepts all 
! series of printable characters starting with the characters "REM ". In some 
! implementations of BASIC, any string starting with "REM" is a comment statement.
! Examples include "REMARK", "REMARKABLE" and "REMODEL". This grammar requires the space.
!
! -----------------------------------------------------------------------


"Name"    = 'Commodore PET BASIC'
"Author"  = 'Commodore Business Machines'
"Version" = '2.0'
"About"   = 'This is the version of BASIC that was used on the Commodore 64.'

"Case Sensitive" = False 
"Start Symbol"   = <Lines>

{String Chars} = {Printable} - ["]
{WS}           = {Whitespace} - {CR} - {LF}

NewLine        = {CR}{LF}|{CR}
Whitespace     = {WS}+

Remark         = REM{Space}{Printable}*
ID             = {Letter}{Alphanumeric}?[$%]?      !IDs are can only have a maximum of 2 characters
FunctionID     = FN {Letter}{Letter}?

String         = '"'{String Chars}*'"' 
Integer        = {Digit}+ 
Real           = {Digit}+'.'{Digit}+ 

<Lines>       ::= <Lines> <Line>
                | <Line>

<Line>        ::= Integer <Statements> NewLine 
                                
<Statements>  ::= <Statements> ':' <Statement>
                | <Statement>

<Statement>   ::= CLOSE Integer
                | CLR
                | CMD  <Expression>
                | CONT                                          !Continue
                | DATA <Constant List> 
                | DEF FunctionID '(' <ID List> ')' '=' <Expression>    !The ID must start with FN
                | DIM ID '(' <Expression List> ')'
                | END          
                | FOR ID '=' <Expression> TO <Expression> <Step Opt>     
                | GET ID
                | GET '#' Integer ',' ID
                | GOSUB <Expression> 
                | GOTO <Expression>                 
                | IF <Expression> THEN <Then Clause>                
                | INPUT <ID List>       
                | INPUT '#' Integer ',' <ID List>       
                | LET ID '=' <Expression> 
                | LIST <Line Range>
                | LOAD <Value List>        
                | ID '=' <Expression> 
                | NEW
                | NEXT <ID List>               
                | ON ID GOTO <Expression List>
                | OPEN <Expression List>         
                | POKE <Expression> ',' <Expression>
                | PRINT <Print list>
                | PRINT '#' Integer ',' <Print List>
                | READ <ID List>           
                | RETURN
                | RESTORE
                | RUN
                | RUN <Expression>
                | STOP
                | SYS <Expression>
                | WAIT <Expression List>     
                | VERIFY <Expression List>     
                | Remark

<Step Opt> ::= STEP <Expression>
             | 
                   
<ID List>  ::= ID ',' <ID List> 
             | ID 

<Value List>      ::= <Value> ',' <Value List> 
                    | <Value> 

<Constant List>   ::= <Constant> ',' <Constant List> 
                    | <Constant> 
                 
<Expression List> ::= <Expression> ',' <Expression List> 
                    | <Expression> 

<Print List>      ::= <Expression> ';' <Print List>
                    | <Expression> 
                    |  

<Line Range>  ::= Integer 
                | Integer '-'
                | Integer '-' Integer 

<Then Clause> ::= Integer
                | <Statement>

! ----------------------------------------------- Expressions

<Expression>  ::= <And Exp> OR <Expression> 
                | <And Exp> 

<And Exp>     ::= <Not Exp> AND <And Exp> 
                | <Not Exp> 
 
<Not Exp>     ::= NOT <Compare Exp> 
                | <Compare Exp> 

<Compare Exp> ::= <Add Exp> '='  <Compare Exp> 
                | <Add Exp> '<>' <Compare Exp> 
                | <Add Exp> '>'  <Compare Exp> 
                | <Add Exp> '>=' <Compare Exp> 
                | <Add Exp> '<'  <Compare Exp> 
                | <Add Exp> '<=' <Compare Exp> 
                | <Add Exp> 

<Add Exp>     ::= <Mult Exp> '+' <Add Exp> 
                | <Mult Exp> '-' <Add Exp> 
                | <Mult Exp> 

<Mult Exp>    ::= <Negate Exp> '*' <Mult Exp> 
                | <Negate Exp> '/' <Mult Exp> 
                | <Negate Exp> 

<Negate Exp>  ::= '-' <Power Exp> 
                | <Power Exp> 

<Power Exp>   ::= <Power Exp> '^' <Sub Exp>        !On the Commodore, the symbol was an up-arrow
                | <Sub Exp> 

<Sub Exp>     ::= '(' <Expression> ')'
                | <Value>

<Value>       ::= ID 
                | ABS        '(' <Expression> ')'
                | ASC        '(' <Expression> ')'
                | ATN        '(' <Expression> ')'
                | 'CHR$'     '(' <Expression> ')'
                | COS        '(' <Expression> ')'
                | EXP        '(' <Expression> ')'
                | FunctionID '(' <Expression List> ')'
                | FRE        '(' <Value> ')'                  !The <Value> is  irrelevant
                | INT        '(' <Expression> ')'
                | 'LEFT$'    '(' <Expression> ',' <Expression> ')'
                | LEN        '(' <Expression> ')'
                | PEEK       '(' <Expression> ')'
                | POS        '(' <Value> ')'                  !The <Value> is  irrelevant
                | 'RIGHT$'   '(' <Expression> ',' <Expression> ')'
                | RND        '(' <Expression> ')'
                | SGN        '(' <Expression> ')' 
                | SPC        '(' <Expression> ')' 
                | SQR        '(' <Expression> ')' 
                | TAB        '(' <Expression> ')' 
                | TAN        '(' <Expression> ')' 
                | VAL        '(' <Expression> ')' 
                
                | <Constant> 

<Constant>    ::= Integer 
                | String 
                | Real 

Brainf***

! ---------------------------------------------------------------------------
!
! Brainf***
!
!
! As legend states, the Brainf*** Programming Language (also called BF by 
! those not wanting to curse) was created by Urban Mueller in 1993.
! The language was designed, in part, so Mueller could create the smallest 
! compiler ever. The first BF compiler was written for the Commodore Amiga 
! OS 2.0 and was only 240 bytes in size. 
! 
! BF is a Turing-complete language. This means that any BF program can be 
! proved to be equivalent to a Turing Machine. 
! 
! The system consists of an continuous array of 30,000 bytes (more can be 
! added of course, but this is the standard size). Each cell is accessed 
! through a single, global, pointer that can either move forward or backward 
! on the array. The content of each cell can be modified by either reading a 
! new byte from standard input or by incrementing or decrementing the 
! current value. The array is initialized with zeroes. 
! 
! 
! The BF Programming Language only consists of 8 different instructions: 
! 
!    >    Increment the pointer 
!    <    Decrement the pointer 
!    
!    +    Add 1 to the current cell 
!    -    Substract 1 from current cell 
!    
!    .    Print the current cell to the screen using its ASCII value. 
!    ,    Read a character and store its ASCII value in the current cell 
!    
!    [    Jump forward past the corresponding ] if the current byte is zero 
!    ]    Jump back to the statement after the corresponding [ if the
!         current cell is not zero. 
! 
! In reality, the BF Programming Language is not that different from ANSI C. 
! Each of the 8 instructions can be substituted for C statements and 
! language constructs. 
!   
!    >    becomes    p++; 
!    <    becomes    p--; 
!    +    becomes    *p++; 
!    -    becomes    *p--; 
!    .    becomes    putchar(*p); 
!    ,    becomes    *p = getchar(); 
!    
!    [    becomes    while (*p) {    ... 
!    ]    becomes    }  
! 
! 
! BF also treats all characters that are not the 8 basic commands as 
! comments. In the grammar below, Whitespace is defined to include all the 
! printable characters - with the exception of the statements. 
! 
! Please see http://en.wikipedia.org/wiki/Brainfuck for more information
! 
! PLEASE NOTE: This grammar was created for fun. If you want to create a BF 
!              parser, it is far easier (and much more efficient) to write 
!              one manually.
!
! ---------------------------------------------------------------------------


"Name"     = 'Brainf***'
"Author"   = 'Urban Mueller'
"Version"  = '1993'

"About"    = 'Brainf*** was created by Urban Mueller with the goal to build'
           | 'the smallest compiler ever.'

"Start Symbol" = <Instructions>

! ============================================== Comments 

{WS} = {Printable} - [<>+-.,'['']'] 

Whitespace = {WS}+


! ============================================== Statements

<Instructions> ::= <Instructions> <Instruction>
                 | 


<Instruction>  ::= '>'                     ! Increment p
                 | '<'                     ! Decrement p
                 | '+'                     ! Increment a[p]
                 | '-'                     ! Decrement a[p]
                 | '.'                     ! Output a[p]
                 | ','                     ! Input a[p]
                 | '[' <Instructions> ']'

C#

See the following, C-sharp syntax

Cobol

! -----------------------------------------------------------------------------
! COBOL 85
!
! COmmon Business Oriented Language 
!
!
! The COBOL programmming language is one of the oldest still in use today. It
! was originally designed by the United States Department of defense under the 
! supervision of the COnference on DAta SYstems Languages (CODASYL) Committee.
! Most of the groundwork and design of COBOL was done by General Grace Hopper 
! of the United States Navy.
!
! The COBOL language was designed to be a self-documenting language where 
! programs would read as close to English as possible. All interaction
! between the user, the terminal and files are performed through language
! statements rather than third-party libraries. The metaphor used for data 
! types is abstract and completely platform independant. As a result of these
! factors, COBOL is a very portable. 
!
! The COBOL 85 grammar is complex - containing, over 350 reserved words, 
! 950 rules which results in iver 1,600 LALR states.
!
!
! Side Note: General Grace Hopper was the engineer who coined the term "bug" 
! when she found an "ill-positioned" insect in an early mainframe.
!
! Revisions:
!    09-13-06: Devin Cook  
!       * Fixed a flaw in the Communications Section where a period was added 
!         to the end of a terminal rather than as a separate terminal. Thanks
!         to Jose Ventura for finding this flaw.
!
!       * Fixed a flaw in the PicString terminal. The definition required two or
!         more spaces between PIC and the picture characters. Thanks to Jose 
!         Ventura for finding this flaw.
!
!    07-21-06: Devin Cook  
!       * The grammar was modified to better handle embeded statements and 
!         message handling clauses.
!
!    06-12-06: Devin Cook  
!       * Grammar was completed
! -----------------------------------------------------------------------------

"Name"    = 'COBOL 85'
"Version" = '1.1'

"Author"  = 'General Grace Hopper (United States Navy) and the CODASYL Committee'

"About"   = 'Originally created in 1960, COBOL (COmmon Business Oriented Language)'
          | 'is one of the top 5 most popular languages in use today. COBOL was designed'
          | 'to be self-documenting by using a structure simular to basic English.'
          | 'This is the full 85 grammar. However, However, differ vendors have'
          | 'created specialized dialects. As result, this grammar may not parse'
          | 'them. This grammar was written by Devin Cook.'

"Case Sensitive" = False
"Start Symbol" = <Program>


{String Chars 1} = {Printable} - ['']
{String Chars 2} = {Printable} - ["]
{Id Tail Chars}  = {Alphanumeric} + [-]

StringLiteral = ''{String Chars 1}*'' | '"'{String Chars 2}*'"'
IntLiteral    = {Digit}+
FloatLiteral  = {Digit}+'.'{Digit}+
Identifier    = {Letter}{Id Tail Chars}*

! -----------------------------------------------------------------------------   
! Picture Clause
! -----------------------------------------------------------------------------

! TYPE SYMBOLS
!   X
!   9
!
! EDITED SYMBOLS
!   , B 0 /          Simple Insertion
!   .                Special Insertion
!   - CR DB $        Fixed Insertion
!   + - $            Floating Insertion
!   Z *              Suppression and Replacement


{Pic Ch} = [xa9] + [bpz0*+-,]
{WS}     = {Space} + {HT} + {NBSP}

PicString = PIC(TURE)? {WS}+ (IS {WS}+)?  (CR|DB|[$s])? {Pic Ch}+ ( '('{Number}+')' )? ( [v.] {Pic Ch}+ ( '('{Number}+')' )? )? (CR|DB|[$s])?
          | PIC(TURE)? {WS}+ (IS {WS}+)?  ''  {String Chars 1}* ''
          | PIC(TURE)? {WS}+ (IS {WS}+)?  '"' {String Chars 2}* '"'

! -----------------------------------------------------------------------------  
! Main program structure
! ----------------------------------------------------------------------------- 

<Program>
        ::= <Identification Division> <Environment Division> <Data Division> <Procedure Division>

! -----------------------------------------------------------------------------  
! Optional Keywords - Often used only for readbility
! -----------------------------------------------------------------------------        

<ADVANCING Opt>  ::= ADVANCING    |  !Optional
<ALL Opt>        ::= ALL          |  !Optional
<ARE Opt>        ::= ARE          |  !Optional                  
<AREA Opt>       ::= AREA | AREAS |  !Optional
<AT Opt>         ::= AT           |  !Optional        
<BY Opt>         ::= BY           |  !Optional
<CHARACTERS Opt> ::= CHARACTERS   |  !Optional
<COLLATING Opt>  ::= COLLATING    |  !Optional
<CONTAINS Opt>   ::= CONTAINS     |  !Optional
<DATA Opt>       ::= DATA         |  !Optional
<EVERY Opt>      ::= EVERY        |  !Optional      
<FILE Opt>       ::= FILE         |  !Optional      
<FINAL Opt>      ::= FINAL        |  !Optional
<FOR Opt>        ::= FOR          |  !Optional
<GLOBAL Opt>     ::= GLOBAL       |  !Optional
<IN Opt>         ::= IN           |  !Optional
<INDICATE Opt>   ::= INDICATE     |  !Optional 
<INITIAL Opt>    ::= INITIAL      |  !Optional 
<IS Opt>         ::= IS           |  !Optional
<KEY Opt>        ::= KEY          |  !Optional
<LINE Opt>       ::= LINE         |  !Optional
<LINES Opt>      ::= LINE | LINES |  !Optional
<MESSAGE opt>    ::= MESSAGE      |  !Optional
<MODE Opt>       ::= MODE         |  !Optional
<NEXT Opt>       ::= NEXT         |  !Optional
<NUMBER Opt>     ::= NUMBER       |  !Optional 
<OF Opt>         ::= OF           |  !Optional
<ON Opt>         ::= ON           |  !Optional
<ORDER opt>      ::= ORDER        |  !Optional
<PRINTING Opt>   ::= PRINTING     |  !Optional
<RECORD Opt>     ::= RECORD       |  !Optional
<REFERENCES Opt> ::= REFERENCES   |  !Optional
<RIGHT Opt>      ::= RIGHT        |  !Optional 
<ROUNDED Opt>    ::= ROUNDED      |  !Optional
<STANDARD Opt>   ::= STANDARD     |  !Optional
<SIGN Opt>       ::= SIGN         |  !Optional
<SIZE Opt>       ::= SIZE         |  !Optional
<STATUS Opt>     ::= STATUS       |  !Optional
<SYMBOLIC Opt>   ::= SYMBOLIC     |  !Optional
<TAPE Opt>       ::= TAPE         |  !Optional
<THEN Opt>       ::= THEN         |  !Optional
<THAN Opt>       ::= THAN         |  !Optional
<TO Opt>         ::= TO           |  !Optional
<WHEN Opt>       ::= WHEN         |  !Optional
<WITH Opt>       ::= WITH         |  !Optional

! -----------------------------------------------------------------------------  
! Equivelent Keywords
! -----------------------------------------------------------------------------                        

<THRU>
        ::= THRU
         |  THROUGH

<IS ARE Opt>
        ::= IS
         |  ARE
         |  !Optional  

<CORRESPONDING>
        ::= CORRESPONDING
         |  CORR

! -----------------------------------------------------------------------------  
! Clauses Shared By Multiple Rules
! -----------------------------------------------------------------------------                        

<Giving Clause Opt> 
        ::= GIVING Identifier
         |  !Optional
               
<Pointer Clause>   
        ::= <WITH Opt> POINTER <Variable>
         |  !Optional
               
<File Name>
        ::= Identifier
         |  StringLiteral

<File Name List>
        ::= <File Name List> <File Name>
         |  <File Name>

<Int Constant>
        ::= Identifier
         |  <Integer>

<Index Clause>
        ::= INDEXED <BY Opt> Identifier
         |  !Optional

<BEFORE AFTER>
        ::= BEFORE
         |  AFTER

! -----------------------------------------------------------------------------  
! Values, Literals, etc...
! -----------------------------------------------------------------------------

<Symbolic Value>
        ::= <Literal>
         |  <Variable>
         |  <Figurative>

<Values>       
       ::= <Values> <Value>
        |  <Value>   
                
<Value>      
        ::= <Literal>
         |  <Variable>
                     
<Numeric>    
        ::= <Integer>
         |  Identifier
                                  
<Literal>
        ::= <Integer>
         |  FloatLiteral
         |  StringLiteral
         |  QUOTE
         |  QUOTES

<Integer>
        ::= IntLiteral
         |  '66'
         |  '77'         
         |  '88'
         
<Figurative> 
        ::= ZERO
         |  ZEROS
         |  ZEROES
         |  SPACE
         |  SPACES
         |  HIGH-VALUE
         |  HIGH-VALUES
         |  LOW-VALUE
         |  LOW-VALUES
         |  ALL StringLiteral
         |  NULL
         |  NULLS

<Identifiers> 
        ::= <Identifiers> Identifier
         |  Identifier

<Variables> 
        ::= <Variables> Identifier 
         |  Identifier

<Variable>
        ::= Identifier
         |  Identifier '(' <Subsets> ')'

<Subsets>
        ::= <Subsets> ':' <Numeric> 
         |  <Numeric>

! -----------------------------------------------------------------------------
! ------------------------- IDENTIFICATION DIVISION ---------------------------
! -----------------------------------------------------------------------------
       
<Identification Division> 
        ::= IDENTIFICATION DIVISION '.' <Prog ID> <Program Info Items>
        
<Prog ID>
        ::= PROGRAM-ID '.' <Word List> <Prog Name Opt> '.'

<Program Info Items> 
        ::= <Program Info Items> <Program Info Item>
         |  !Zero or more
        
<Program Info Item>
        ::= AUTHOR        '.' <Word List> '.'
         |  INSTALLATION  '.' <Word List> '.'
         |  DATE-WRITTEN  '.' <Word List> '.'
         |  DATE-COMPILED '.' <Word List> '.'
         |  SECURITY      '.' <Word List> '.'
         
<Word List> 
        ::= <Word List> <Word Item>                         
         |  <Word Item>

<Word Item>
        ::= Identifier 
         |  <Integer> 
         |  FloatLiteral 
         |  StringLiteral 
         |  '/' 
         |  ','
                                         
<Prog Name Opt>
        ::= <IS Opt> <Common Initial> <Program Opt>
         |  !Optional
    
<Common Initial> 
        ::= COMMON
         |  INITIAL
        
<Program Opt>
         ::= PROGRAM
          |  !Optional
 
! -----------------------------------------------------------------------------
! -------------------------- ENVIRONMENT DIVISION -----------------------------
! -----------------------------------------------------------------------------  

<Environment Division>
       ::= ENVIRONMENT DIVISION '.' <Config Section> <Input-Output Section>
        |  !Optional
        
! -----------------------------------------------------------------------------   
! CONFIGURATION SECTION
! -----------------------------------------------------------------------------

<Config Section>   
        ::= CONFIGURATION SECTION '.' <Config Section Items>
         |  !Optional

<Config Section Items>
        ::= <Config Section Items> <Config Section Item>
         |  !Zero or more

<Config Section Item>
        ::= <Source Computer>
         |  <Object Computer>
         |  <Special Names>
                           
! -----------------------------------------------------------------------------  
! SOURCE-COMPUTER
! ----------------------------------------------------------------------------- 

<Source Computer>  
        ::= SOURCE-COMPUTER '.' <Source Computer Clause Opt>

<Source Computer Clause Opt>
        ::= Identifier <Source Debug Opt> '.'
         |  !Optional 
                  
<Source Debug Opt> 
        ::= <WITH Opt> DEBUGGING MODE
        
! -----------------------------------------------------------------------------  
! OBJECT-COMPUTER
! ----------------------------------------------------------------------------- 
                     
<Object Computer>  
        ::= OBJECT-COMPUTER '.' <Object Computer Clause Opt>

<Object Computer Clause Opt>
        ::= Identifier <Object Clauses> '.'
         |  !Optional
        
<Object Clauses>
        ::= <Object Clause> <Object Clauses>
         |  !Optional

<Object Clause>
        ::= <Program Opt> <COLLATING Opt> SEQUENCE <IS Opt> Identifier
         |  SEGMENT-LIMIT <IS Opt> <Integer>
        
! -----------------------------------------------------------------------------  
! SPECIAL-NAMES
! ----------------------------------------------------------------------------- 
      
<Special Names> 
        ::= SPECIAL-NAMES '.' <Special Name List>
        
<Special Name List>
        ::= <Special Name List> <Special Names Item>
         |  !Zero or more
  
<Special Names Item> 
        ::= Identifier <IS Opt> Identifier <Name Status Items> '.' 
         |  Identifier                     <Name Status Items> '.'
         |  SYMBOLIC <CHARACTERS Opt> <Symbolic Char List>  '.'
         |  ALPHABET Identifier <IS Opt> <Alphabet Item>    '.'
         |  CLASS Identifier    <IS Opt> <Special Ranges>   '.'
         |  CURRENCY <SIGN Opt> <IS Opt> <Literal>          '.'
         |  DECIMAL-POINT       <IS Opt> COMMA              '.'
         
<Name Status Items> 
        ::= <Name Status Items> <Name Status Item>
         |  !Zero or more

<Name Status Item>
        ::= ON  <STATUS Opt> <IS Opt> Identifier
         |  OFF <STATUS Opt> <IS Opt> Identifier

! -----------------------------------------------

<Alphabet Item>
        ::= STANDARD-1
         |  STANDARD-2 
         |  NATIVE
         |  Identifier
         |  <Special Ranges>

<Special Ranges>
         ::= <Special Ranges> ALSO <Special Range>
          |  <Special Range>

<Special Range>
         ::= <Literal> <THRU> <Literal>

! -----------------------------------------------

<Symbolic Char List>
         ::= <Symbolic Characters>
          |  <Symbolic Characters> IN Identifier

<Symbolic Characters>
         ::= <Symbolic Character> <Symbolic Value>
          |  <Symbolic Character>

<Symbolic Character>
         ::= Identifier <IS ARE Opt> <Literal>

! -----------------------------------------------------------------------------   
! INPUT-OUTPUT SECTION
! -----------------------------------------------------------------------------        
        
<Input-Output Section> 
        ::= INPUT-OUTPUT SECTION '.' <File-Control> <I-O-Control>
         |  !Optional
                
! -----------------------------------------------------------------------------  
! FILE-CONTROL
! ----------------------------------------------------------------------------- 
   
<File-Control> 
        ::= FILE-CONTROL '.' <Select Block>
         |  !Optional
        
<Select Block>
        ::= <Select Block> <Select Paragraph>
         |  !Optional
        
<Select Paragraph> 
        ::= SELECT <Optional Opt> Identifier ASSIGN <TO Opt> Identifier <Select Opt List> '.'

<Optional Opt> 
        ::= OPTIONAL
         |  !Null
                    
<Select Opt List>
        ::= <Select Option> <Select Opt List>
         |  !Zero or more
                
<Select Option> 
        ::= RESERVE <Integer> <AREA Opt>
         |  ORGANIZATION <IS Opt> <Organization Kind>
         |                        <Organization Kind>
         |  PADDING <Character Opt> <IS Opt> <Padding Kind>  
         |  RECORD DELIMITER  <IS Opt> <Record Delimiter Kind>
         |  RECORD <KEY Opt>  <IS Opt> Identifier
         |  ALTERNATIVE RECORD <KEY Opt> <IS Opt> Identifier <Duplicates Clause Opt>

         |  ACCESS <MODE Opt> <IS Opt> <Access Mode>
         |  <FILE Opt> STATUS <IS Opt> Identifier
                                         
<Access Mode> 
        ::= SEQUENTIAL
         |  RANDOM
         |  DYNAMIC
                    
<Organization Kind> 
        ::= SEQUENTIAL
         |  LINE SEQUENTIAL
         |  RELATIVE <Relative Key Opt>
         |  INDEXED 
                
<Relative Key Opt>  
        ::= <KEY Opt> <IS Opt> Identifier
         |  !Optional
                  
<Record Delimiter Kind>
        ::= STANDARD-1
         |  Identifier

<Padding Kind>
        ::= Identifier
         |  <Literal>

<Duplicates Clause Opt>
        ::= <WITH Opt> DUPLICATES
         |  !Optional   

! -----------------------------------------------------------------------------  
! I-O CONTROL
! ----------------------------------------------------------------------------- 

<I-O-Control>
        ::= I-O-CONTROL '.' <Rerun List> <Same List> <Multiple List> '.'
        
<Rerun List>
        ::= <Rerun List> <Rerun Item>
         |  !Zero or more

<Rerun Item>
        ::= RERUN <Rerun Clause Opt> <EVERY Opt> <Every Clause>
        
<Rerun Clause Opt>
        ::= ON <File Name>
         |  !Optional 

<Every Clause>
        ::= <End Of Opt> <Every End Target> <OF Opt> <File Name>
         |  <Integer> RECORDS
         |  <Integer> CLOCK-UNITS
         |  Identifier 

<End Of Opt>
        ::= END <OF Opt>
         |  !Optional

<Every End Target>
        ::= REEL
         |  UNIT

! -----------------------------------------------

<Same List>
        ::= <Same List> <Same Item>
         |  !Zero or more

<Same Item>
        ::= SAME <Same Source> <AREA Opt> <File Name> <File Name List>

<Same Source>
        ::= RECORD
         |  SORT
         |  SORT-MERGE 

<Multiple List> 
        ::= <Multiple List> <Multiple Item>
         |  !Zero or more

<Multiple Item>
        ::= MULTIPLE FILE <TAPE Opt> <CONTAINS Opt> <Contain List>

<Contain List>
        ::= <Contain List> <Contain Item>
         |  <Contain Item>

<Contain Item>
        ::= <File Name> POSITION <IS Opt> <Integer>
         |  <File Name>

! -----------------------------------------------------------------------------
! ------------------------------ DATA DIVISION --------------------------------
! -----------------------------------------------------------------------------        
        
<Data Division>  
        ::= DATA DIVISION '.' <Data Section List>
        
        
<Data Section List> 
        ::= <Data Section Entry> <Data Section List>
         |  !Zero or more
        
<Data Section Entry> 
        ::= <File Section>
         |  <Working-Storage Section>
         |  <Linkage Section>
         |  <Screen Section>
         |  <Communication Section> 
         |  <Report Section>
                       
! -----------------------------------------------------------------------------
! Record Definition
! -----------------------------------------------------------------------------
        
<Record Entry Block>
        ::= <Record Entry Block> <Record Entry>
         |  !Zero or more   

<Record Entry>
        ::= IntLiteral <Level Name> <Record Option List>         '.'   !Normal Record
         |  '66'       <Level Name> RENAMES <Identifier Range>   '.'
         |  '77'       <Level Name> <Record Option List>         '.'   !Constant
         |  '88'       <Level Name> VALUES <IS ARE Opt> <Values> '.'
               
<Level Name>    
        ::= Identifier
         |  FILLER
          
<Times Opt>     
        ::= TIMES
         |  !Optional       

<Record Option List>
        ::= <Record Option List> <Record Option>
         |  !Zero or more  


<Record Option>
        ::= REDEFINES Identifier
         |  <IS Opt> EXTERNAL
         |  <IS Opt> INTERNAL
         |  <Picture>             
       
         |  USAGE <IS Opt> <Usage Args>
         |                 <Usage Args>  

         |  SIGN <IS Opt> <Sign Args> <Sep Char Option>
         |  OCCURS <Numeric>              <Times Opt>                               <Key Clause> <Index Clause>
         |  OCCURS <Numeric> TO <Numeric> <Times Opt> DEPENDING <ON Opt> Identifier <Key Clause> <Index Clause>
         |  SYNCHRONIZED <Left Right Opt>  
         |  SYNC         <Left Right Opt>  
         |  JUSTIFIED <RIGHT Opt>  
         |  JUST      <RIGHT Opt>  
         |  BLANK <WHEN Opt> ZERO
         |  VALUE <IS Opt> <Symbolic Value> 

<Picture>
        ::= PicString

<Key Clause>
        ::= ASCENDING <KEY Opt> <IS Opt> <Identifiers>
         |  DESCENDING <KEY Opt> <IS Opt> <Identifiers>
         |  !Optional

<Usage Args> 
        ::= BINARY
         |  COMPUTATIONAL
         |  COMP
         |  DISPLAY
         |  INDEX
         |  PACKED-DECIMAL
           
<Sign Args>
        ::= LEADING
         |  TRAILING
            
<Sep Char Option>  
        ::= SEPARATE <Character Opt>
         |  !Optional
        
<Character Opt>    
        ::= CHARACTER
         |  !Optional

<Left Right Opt>   
        ::= LEFT
         |  RIGHT
         |  !Optional 
           
        
! -----------------------------------------------------------------------------  
! FILE SECTION
! -----------------------------------------------------------------------------

<File Section> 
        ::= FILE SECTION '.' <File Desc Block>
                
<File Desc Block> 
        ::= <File Desc Entry> <File Desc Block>
         |  !Zero ore more
        
<File Desc Entry> 
        ::= FD Identifier <File Option List> '.' <Record Entry Block>
         |  SD Identifier <File Option List> '.' <Record Entry Block>
                                              
<File Option List>
        ::= <File Option List> <File Option>
         |  !Zero or more

<File Option>
        ::= <File Is Option>
         |  <File Block Option>
         |  <File Record Option>
         |  <File Label Option> 
         |  <File Value Option>
         |  <File Data Option>
         |  <File Linage Option>
         |  <File Code-Set Option>

! -----------------------------------------------------------------------------  
! Description Clauses
! -----------------------------------------------------------------------------

<File Is Option>
        ::= <IS Opt> EXTERNAL
         |  <IS Opt> INTERNAL

! -----------------------------------------------

<File Block Option>
        ::= BLOCK <CONTAINS Opt> <Numeric>              <File Block Units>
         |  BLOCK <CONTAINS Opt> <Numeric> TO <Numeric> <File Block Units>

<File Block Units>
        ::= RECORDS
         |  CHARACTERS
         |  !Optional - defaults to characters.          

! -----------------------------------------------
 
<File Record Option>
        ::= RECORD <CONTAINS Opt> <Numeric> <CHARACTERS Opt>
         |  RECORD <CONTAINS Opt> <Numeric> TO <Numeric> <CHARACTERS Opt>
         |  RECORD <IS Opt> VARYING <IN Opt> <SIZE Opt> <File Record Size Clause> <File Record Depending Clause>

<File Record Size Clause>
        ::= FROM <Numeric> <CHARACTERS Opt>
         |  TO   <Numeric> <CHARACTERS Opt>
         |  FROM <Numeric> TO <Numeric> <CHARACTERS Opt>
         |  !Optional 

<File Record Depending Clause>
        ::= DEPENDING <ON Opt> Identifier
         |  !Optional 

! -----------------------------------------------

<File Label Option> 
        ::= LABEL RECORD  <IS Opt> <File Label Type>
         |  LABEL RECORDS <IS Opt> <File Label Type>

<File Label Type> 
        ::= STANDARD
         |  OMITTED

! -----------------------------------------------

<File Value Option>
        ::= VALUE OF <File Value List>

<File Value List>
        ::= <File Value List> <File Value Item>
         |  <File Value Item>

<File Value Item>
        ::= Identifier <IS Opt> Identifier
         |  Identifier <IS Opt> <Literal>

! -----------------------------------------------

<File Data Option>
        ::= DATA RECORD  <IS Opt>  <Identifiers>
         |  DATA RECORDS <ARE Opt> <Identifiers>

! -----------------------------------------------

<File Linage Option>
        ::= LINAGE <IS Opt> <Int Constant> <LINES Opt> <File Linage Footing> <File Linage Top> <File Linage Bottom>
 
<File Linage Footing> 
        ::= <WITH Opt> FOOTING <AT Opt> <Int Constant>
         !  Optional

<File Linage Top>
        ::= <LINES Opt> <AT Opt> TOP <Int Constant>
         !  Optional

<File Linage Bottom>
        ::= <LINES Opt> <AT Opt> BOTTOM <Int Constant>
         !  Optional

! -----------------------------------------------

<File Code-Set Option>
        ::= CODE-SET <IS Opt> Identifier

! -----------------------------------------------------------------------------  
! WORKING-STORAGE SECTION
! -----------------------------------------------------------------------------

<Working-Storage Section> 
        ::= WORKING-STORAGE SECTION '.' <Record Entry Block>
        
        
! -----------------------------------------------------------------------------  
! LINKAGE SECTION
! -----------------------------------------------------------------------------

<Linkage Section>  
        ::= LINKAGE SECTION '.' <Record Entry Block>
            

! -----------------------------------------------------------------------------  
! SCREEN SECTION
! -----------------------------------------------------------------------------

<Screen Section> 
        ::= SCREEN SECTION '.'  <Screen Field List>      
        
<Screen Field List> 
        ::= <Screen Field> <Screen Field List>
         |  <Screen Field>
                
<Screen Field>
        ::= <Integer> <Field Name opt> <Field Def List> '.'
                
<Field Name opt> 
        ::= Identifier
         |  !Optional
                
<Field Def List> 
        ::= <Field Def List>  <Field Def Item>
         |  !Optional
        
<Field Def Item> 
        ::= LINE   <Numeric>
         |  COLUMN <Numeric>
         |  FOREGROUND-COLOR <Numeric>
         |  BACKGROUND-COLOR <Numeric>
         |  VALUE <IS Opt> <Symbolic Value>
         |  <Picture>
         |  FROM Identifier
         |  USING Identifier
         |  HIGHLIGHT
         |  REVERSE-VIDEO
         |  BLINK
         |  UNDERLINE
         |  BLANK SCREEN
                       
! -----------------------------------------------------------------------------  
! COMMUNICATION SECTION
! -----------------------------------------------------------------------------

<Communication Section>
        ::= COMMUNICATION SECTION '.' <Comm Desc List> 

<Comm Desc List>
        ::= <Comm Desc List> <Comm Desc>
         |   !Zero or more

<Comm Desc>
        ::= CD Identifier <FOR Opt> <INITIAL Opt> INPUT  <Comm Input Body>     '.' <Record Entry Block>
         |  CD Identifier <FOR Opt>               OUTPUT <Comm Output Options> '.' <Record Entry Block>
         |  CD Identifier <FOR Opt> <INITIAL Opt> I-O    <Comm I-O Body>       '.' <Record Entry Block>

<Comm Input Body>
        ::= <Identifiers>
         |  <Comm Input Options>

<Comm Input Options>
        ::= <Comm Input Options> <Comm Input Option>
         |  !Zero ore more

<Comm Input Option>
        ::= <SYMBOLIC Opt> QUEUE       <IS Opt> Identifier
         |  <SYMBOLIC Opt> SUB-QUEUE-1 <IS Opt> Identifier
         |  <SYMBOLIC Opt> SUB-QUEUE-2 <IS Opt> Identifier
         |  <SYMBOLIC Opt> SUB-QUEUE-3 <IS Opt> Identifier
         |  MESSAGE DATE <IS Opt> Identifier   
         |  MESSAGE TIME <IS Opt> Identifier
         |  <SYMBOLIC Opt> SOURCE <IS Opt> Identifier
         |  TEXT LENGTH <IS Opt> <Numeric>
         |  END KEY <IS Opt> Identifier
         |  STATUS KEY  <IS Opt> Identifier
         |  MESSAGE COUNT <IS Opt> Identifier           
           
<Comm Output Options>
        ::= <Comm Output Options>  <Comm Output Option>
         |  !Zero or more

<Comm Output Option>
        ::= DESTINATION TABLES OCCURS <Numeric> <TIMES Opt> <Index Clause>
         |  DESTINATION COUNT    <IS Opt> Identifier           
         |  TEXT LENGTH          <IS Opt> Identifier           
         |  STATUS KEY           <IS Opt> Identifier
         |  ERROR KEY            <IS Opt> Identifier
         |  SYMBOLIC DESTINATION <IS Opt> Identifier
         |  DESTINATION          <IS Opt> Identifier

<Comm I-O Body>
        ::= <Identifiers>
         |  <Comm I-O Options>

<Comm I-O Options>
        ::= <Comm I-O Options> <Comm I-O Option>
         |  !Zero or more 

<Comm I-O Option>
        ::= MESSAGE DATE <IS Opt> Identifier   
         |  MESSAGE TIME <IS Opt> Identifier
         |  <SYMBOLIC Opt> TERMINAL <IS Opt> Identifier
         |  TEXT LENGTH  <IS Opt> <Numeric>
         |  END KEY      <IS Opt> Identifier
         |  STATUS KEY   <IS Opt> Identifier

! -----------------------------------------------------------------------------  
! REPORT SECTION
! -----------------------------------------------------------------------------

<Report Section>
        ::= REPORT SECTION '.' <Report Desc List> 

<Report Desc List>
        ::= <Report Desc List> <Report Desc> 
         |  !Zero or more

<Report Desc>
        ::= RD Identifier <Report Options> <Report Entry Block> 
  
<Report Options>
        ::= <Report Options> <Report Option>
         |  !Zero or more

<Report Option>
        ::= <IS Opt> GLOBAL
         |  CODE <Literal>
         |  <CONTROL IS> <FINAL Opt> <Identifiers>
         |  PAGE <LIMITS IS Opt> <Numeric> <LINES Opt> <Report Heading Opt>

<CONTROL IS>
        ::= CONTROL  IS 
         |  CONTROLS ARE

<LIMITS IS Opt>
        ::= LIMIT IS
         |  LIMITS ARE
         |  !Optional

<Report Heading Opt>
        ::= HEADING <Integer>
         |  !Optional

<Report Entry Block>
        ::= <Report Entry Block> <Report Entry>
         |  !Zero or more   

<Report Entry>
        ::= <Integer> Identifier <Report Entry Options>  '.'

<Report Entry Options>
        ::= <Report Entry Option> <Report Entry Options>
         |  !Zero or more

<Report Entry Option>
        ::= LINE <NUMBER Opt> <IS Opt> <Numeric>           
         |  LINE <NUMBER Opt> <IS Opt> <Numeric> ON NEXT PAGE      !Same as above
         |  LINE <NUMBER Opt> <IS Opt> PLUS <Numeric>
         |  NEXT GROUP        <IS Opt> <Report Entry Next Group>
         |  TYPE              <IS Opt> <Report Entry Type>
         |  USAGE             <IS Opt> DISPLAY
         |  DISPLAY

         |  <Picture>                    
         |  SIGN <IS Opt> <Sign Args> <Sep Char Option>
         |  JUSTIFIED <RIGHT Opt>  
         |  JUST      <RIGHT Opt>  
         |  BLANK <WHEN Opt> ZERO
         |  COLUMN <Number Opt> <IS Opt> <Numeric>
         |  SOURCE  <IS Opt> <Numeric>
         |  VALUE   <IS Opt> <Symbolic Value> 
         |  SUM <Identifiers> 
         |  SUM <Identifiers> UPON <Identifiers> <Report Entry Result Clause>
         |  GROUP <INDICATE Opt>

<Report Entry Next Group>
        ::= <Numeric>
         |  PLUS <Numeric>
         |  NEXT PAGE     

<Report Entry Type>
        ::= REPORT HEADING
         |  RH                !Report Heading
         |  PAGE HEADING
         |  PH                !Page Heading
         |  CONTROL HEADING
         |  CH                !Control Heading
         |  DETAIL          
         |  DE                !Detail
         |  CONTROL FOOTING
         |  CF                !Control Footing      
         |  PAGE FOOTING   
         |  PF                !Page Footing
         |  REPORT FOOTING
         |  RF                !Report Footing


<Report Entry Result Clause>
        ::= RESET <ON Opt> Identifier 
         |  RESET <ON Opt> FINAL
         |  !Optional

! ------------------------------------------------------------------------------
! --------------------------- PROCEDURE DIVISION ------------------------------- 
! ------------------------------------------------------------------------------
  
<Procedure Division>
        ::= PROCEDURE DIVISION <Using Clause Opt> <Declarative Block> '.' <Paragraphs>  

<Using Clause Opt> 
        ::= USING <Identifiers>
         |  !Optional
        
<Paragraphs>  
        ::= <Paragraphs> <Paragraph>
         |  !Zero or more

<Paragraph>
        ::= Identifier SECTION '.' Identifier '.' <Sentences>
         |                         Identifier '.' <Sentences>

! -----------------------------------------------------------------------------  
! Declaratives
! -----------------------------------------------------------------------------
    
<Declarative Block>
        ::= DECLARATIVES '.' <Declarative Sections> END DECLARATIVES '.'    !No dash - inconsistent
         |  !Optional

<Declarative Sections>
        ::= <Declarative Sections> <Declarative Section> 
         |  !Zero or more

<Declarative Section>
        ::= Identifier SECTION '.' USE <BEFORE AFTER> <STANDARD Opt> ERROR PROCEDURE ON <Error Cause>  '.' <Sentences>
         |  Identifier '.' <Sentences>

<Error Cause>
        ::= Identifier 
         |  INPUT 
         |  OUTPUT
         |  I-O
         |  EXTEND 

! -----------------------------------------------------------------------------  
! Shared by sentences
! -----------------------------------------------------------------------------

<Sort Keys>
        ::= <Sort Keys> <Sort Key>
         |  <Sort Key>
         
<Sort Key>         
        ::= <ON Opt> ASCENDING  <KEY Opt> Identifier
         |  <ON Opt> DESCENDING <KEY Opt> Identifier

<Collating Clause>
        ::= <COLLATING Opt> SEQUENCE <IS Opt> Identifier
         |  !Optional        

<Sort Source>
        ::= INPUT PROCEDURE <IS Opt> <Identifier Range>
         |  USING <Values>                
     
<Sort Target>
        ::= OUTPUT PROCEDURE <IS Opt> <Identifier Range>
         |  GIVING <Values>                
    
<Identifier Range>
        ::= Identifier
         |  Identifier THRU Identifier
         |  Identifier THROUGH Identifier          
                               
<Enabled Disable Mode>        
        ::= INPUT 
         |  INPUT TERMINAL
         |  I-O TERMINAL
         |  OUTPUT

<Enable Disable Key>
        ::= <WITH Opt> KEY <Value>
         |  !Optional

! -----------------------------------------------------------------------------  
! Boolean Expressions
! -----------------------------------------------------------------------------

! Note: <Not Opt> is very significant in the operators below

<Boolean Exp>   
        ::= <Boolean Exp> OR <And Exp>
         |  <And Exp>

<And Exp>
        ::= <Negation Exp> And <And Exp>
         |  <Negation Exp>
              
<Negation Exp>  
        ::= <Compare Exp>
         |  NOT <Compare Exp>
 
!<And Exp>
!        ::= <And Exp> AND <Compare Exp>
!         |  <Compare Exp>
              
<Compare Exp> 
        ::= <Symbolic Value> <Compare Op> <Symbolic Value>
         |  <Symbolic Value> IS ALPHABETIC
         |  <Symbolic Value> IS ALPHABETIC-UPPER
         |  <Symbolic Value> IS ALPHABETIC-LOWER
         |  '(' <Boolean Exp> ')'
         |  <Symbolic Value>
    
<Compare Op>
        ::= <IS ARE Opt>     <Greater Op>
         |  <IS ARE Opt> NOT <Greater Op>

         |  <IS ARE Opt>     <Greater Eq Op>
         |  <IS ARE Opt> NOT <Greater Eq Op>

         |  <IS ARE Opt>     <Less Op>
         |  <IS ARE Opt> NOT <Less Op>

         |  <IS ARE Opt>     <Less Eq Op>
         |  <IS ARE Opt> NOT <Less Eq Op>

         |  <IS ARE Opt>     <Equal Op>
         |  <IS ARE Opt> NOT <Equal Op>
  
<Greater Op>    
        ::= GREATER <THAN Opt>
         |  '>'
                    
<Greater Eq Op> 
        ::= GREATER <THAN Opt> OR EQUAL <TO Opt>
         |  '>='
                    
<Less Op>       
        ::= LESS <THAN Opt>
         |  '<'
                    
<Less Eq Op>    
        ::= LESS <THAN Opt> OR EQUAL <TO Opt>
         |  '<='

<Equal Op>
        ::= EQUAL <TO Opt>
         |  '='


! -----------------------------------------------------------------------------  
! Sentences
! -----------------------------------------------------------------------------

! If you add statements to the grammar, make sure to update the corresponding 
! <Statement> rules below
             
<Sentences> 
        ::= <Sentence> <Sentences>
         |  !Zero or more

<Sentence> 
        ::= <Sent Stm>  '.'   

<Sent Stm>
        ::= <Accept Sent>
         |  <Add Sent>     
         |  <Alter Sent>         
         |  <Call Sent>
         |  <Cancel Sent>
         |  <Close Sent>
         |  <Compute Sent>
         |  <Continue Sent>
         |  <Delete Sent>
         |  <Disable Sent> 
         |  <Display Sent>
         |  <Divide Sent>
         |  <Enable Sent>
         |  <Evaluate Sent>
         |  <Exit Sent>
         |  <Generate Sent>     
         |  <Go To Sent>
         |  <If Sent>
         |  <Initialize Sent>                      
         |  <Initiate Sent>      
         |  <Inspect Sent>     
         |  <Merge Sent>
         |  <Move Sent>         
         |  <Multiply Sent>
         |  <Open Sent>
         |  <Perform Sent>
         |  <Read Sent>
         |  <Release Sent>
         |  <Return Sent>                         
         |  <Rewrite Sent>  
         |  <Search Sent>
         |  <Send Sent>                      
         |  <Set Sent>
         |  <Sort Sent>
         |  <Start Sent>
         |  <Stop Sent>         
         |  <String Sent>      
         |  <Subtract Sent>             
         |  <Suppress Sent>
         |  <Terminate Sent>
         |  <Unstring Sent>
         |  <Use Sent> 
         |  <Write Sent>

<Embed Stms> 
        ::= <Embed Stms> <Embed Stm>
         |  <Embed Stm>
                
<Embed Stm>
        ::= <Accept Embed>
         |  <Add Embed>     
         |  <Alter Embed>         
         |  <Call Embed>
         |  <Cancel Embed>
         |  <Close Embed>
         |  <Compute Embed>
         |  <Continue Embed>
         |  <Delete Embed>
         |  <Disable Embed> 
         |  <Display Embed>
         |  <Divide Embed>
         |  <Enable Embed>
         |  <Evaluate Embed>
         |  <Exit Embed>
         |  <Generate Embed>     
         |  <Go To Embed>
         |  <If Embed>
         |  <Initialize Embed>                      
         |  <Initiate Embed>      
         |  <Inspect Embed>     
         |  <Merge Embed>
         |  <Move Embed>         
         |  <Multiply Embed>
         |  <Open Embed>
         |  <Perform Embed>
         |  <Read Embed>
         |  <Release Embed>
         |  <Return Embed>                         
         |  <Rewrite Embed>  
         |  <Search Embed>
         |  <Send Embed>                      
         |  <Set Embed>
         |  <Sort Embed>
         |  <Start Embed>
         |  <Stop Embed>         
         |  <String Embed>      
         |  <Subtract Embed>             
         |  <Suppress Embed>
         |  <Terminate Embed>
         |  <Unstring Embed>
         |  <Use Embed> 
         |  <Write Embed>

<Imperative Stms> 
        ::= <Imperative Stms> <Imperative Stm>
         |  <Imperative Stm>
                              
<Imperative Stm>
        ::= <Accept Imp>
         |  <Add Imp>     
         |  <Alter Imp>         
         |  <Call Imp>
         |  <Cancel Imp>
         |  <Close Imp>
         |  <Compute Imp>
         |  <Continue Imp>
         |  <Delete Imp>
         |  <Disable Imp> 
         |  <Display Imp>
         |  <Divide Imp>
         |  <Enable Imp>
         |  <Evaluate Imp>
         |  <Exit Imp>
         |  <Generate Imp>     
         |  <Go To Imp>
         |  <If Imp>
         |  <Initialize Imp>                      
         |  <Initiate Imp>      
         |  <Inspect Imp>     
         |  <Merge Imp>
         |  <Move Imp>         
         |  <Multiply Imp>
         |  <Open Imp>
         |  <Perform Imp>
         |  <Read Imp>
         |  <Release Imp>
         |  <Return Imp>                         
         |  <Rewrite Imp> 
         |  <Search Imp> 
         |  <Send Imp>                      
         |  <Set Imp>
         |  <Sort Imp>
         |  <Start Imp>
         |  <Stop Imp>         
         |  <String Imp>      
         |  <Subtract Imp>             
         |  <Suppress Imp>
         |  <Terminate Imp>
         |  <Unstring Imp>
         |  <Use Imp> 
         |  <Write Imp>
    
! -----------------------------------------------------------------------------  
! Exception Handling
! -----------------------------------------------------------------------------

<Size Clauses>
        ::= <Size Clauses> <Size Clause>
         |  <Size Clause>

<Size Clause>
        ::=     <ON Opt> SIZE ERROR <Imperative Stms>
         |  NOT <ON Opt> SIZE ERROR <Imperative Stms>
 
!-----------------------------------------

<Invalid Key Clauses>
        ::= <Invalid Key Clauses> <Invalid Key Clause>
         |  <Invalid Key Clause>

<Invalid Key Clause>
        ::=     INVALID <KEY Opt> <Imperative Stms>
         |  NOT INVALID <KEY Opt> <Imperative Stms>
   
!-----------------------------------------

<Exception Clauses>
        ::= <Exception Clauses> <Exception Clause>
         |  <Exception Clause>

<Exception Clause>
        ::=     <ON Opt> EXCEPTION <Imperative Stms>
         |  NOT <ON Opt> EXCEPTION <Imperative Stms>
    
!-----------------------------------------     

<Overflow Clauses>
        ::= <Overflow Clauses> <Overflow Clause>
         |  <Overflow Clause>

<Overflow Clause>  
        ::=     <ON Opt> OVERFLOW <Imperative Stms>
         |  NOT <ON Opt> OVERFLOW <Imperative Stms>
   
!-----------------------------------------

<At End Clauses>
        ::= <At End Clauses> <At End Clause>
         |  <At End Clause>

<At End Clause>
        ::=     AT END <Imperative Stms>
         |  NOT AT END <Imperative Stms>    

!-----------------------------------------

<AT EOP Clauses>           
        ::= <AT EOP Clauses> <AT EOP Clause>
         |  <AT EOP Clause>

<AT EOP Clause>           
        ::= AT <End of Page> <Imperative Stms>    
         |  NOT AT <End of Page> <Imperative Stms>
          
<End of Page>
        ::= END-OF-PAGE
         |  EOP

! -----------------------------------------------------------------------------  
! ACCEPT Statement
! -----------------------------------------------------------------------------

<Accept Sent>
       ::= <Accept Stm> 

<Accept Embed>
       ::= <Accept Stm>

<Accept Imp>
       ::= <Accept Stm>

<Accept Stm> 
       ::= ACCEPT Identifier 
        |  ACCEPT Identifier FROM <Accept From Arg> 
        |  ACCEPT Identifier <MESSAGE opt> COUNT        !CD
    
<Accept From Arg> 
       ::= FROM DATE
        |  FROM DAY 
        |  FROM DAY-OF-WEEK 
        |  FROM TIME 
        |  FROM CONSOLE 
        |  FROM Identifier
        |  !Optional 

! -----------------------------------------------------------------------------  
! ADD Statement
! -----------------------------------------------------------------------------       

<Add Sent>
        ::= <Add Stm> <Size Clauses> <END-ADD Opt>
         |  <Add Stm>

<Add Embed>
        ::= <Add Stm> <Size Clauses> 'END-ADD'
         |  <Add Stm>

<Add Imp>
        ::= <Add Stm> 
   
<Add Stm>
        ::= ADD <Values> TO <Add Items> <Giving Clause>
         |  ADD <CORRESPONDING> Identifier TO Identifier <ROUNDED Opt>
        
<Giving Clause>
        ::= GIVING <Add Item>
         |  !Optional

<Add Items>
        ::= <Add Items> <Add Item>
         |  <Add Item>
         
<Add Item>
        ::= <Variable> <ROUNDED Opt>


<END-ADD Opt>
        ::= END-ADD
         |  !Optional 

! -----------------------------------------------------------------------------  
! ALTER Statement
! -----------------------------------------------------------------------------       

<Alter Sent>
       ::= <Alter Stm>

<Alter Embed>
       ::= <Alter Stm>

<Alter Imp>
       ::= <Alter Stm>

<Alter Stm>
       ::= ALTER Identifier TO Identifier
        |  ALTER Identifier TO PROCEED TO Identifier
 
! -----------------------------------------------------------------------------  
! CALL Statement
! -----------------------------------------------------------------------------

!Call can call just about anything, it depends on the system.

<Call Sent> 
        ::= <Call Stm> <Exception Clauses> <END-CALL Opt>
         |  <Call Stm> <Overflow Clauses>  <END-CALL Opt>
         |  <Call Stm>

<Call Embed> 
        ::= <Call Stm> <Exception Clauses> END-CALL
         |  <Call Stm> <Overflow Clauses>  END-CALL
         |  <Call Stm>

<Call Imp>
        ::= <Call Stm>  

<Call Stm> 
        ::= CALL <Value>                        
         |  CALL <Value> USING <Call Items>

<Call Items>
        ::= <Call Items> <Call Item>
         |  <Call Item>

<Call Item>
        ::= <Variable>        
         |  <BY Opt> REFERENCE <Variable>   !default
         |  <BY Opt> CONTENT   <Variable>

<END-CALL Opt>
        ::= END-CALL
         |  !Optional

! -----------------------------------------------------------------------------  
! CANCEL Statement
! -----------------------------------------------------------------------------                     

<Cancel Sent>  
        ::= <Cancel Stm>

<Cancel Embed>  
        ::= <Cancel Stm>

<Cancel Imp>  
        ::= <Cancel Stm>

<Cancel Stm>  
        ::= CANCEL <Values>

! -----------------------------------------------------------------------------  
! CLOSE Statement
! -----------------------------------------------------------------------------                     

<Close Sent>
        ::= <Close Stm>    

<Close Embed>
        ::= <Close Stm>    

<Close Imp>
        ::= <Close Stm>    

<Close Stm>    
        ::= CLOSE <Close Items>

<Close Items>
        ::= <Close Items> <Close Item>
         |  <Close Item>

<Close Item>
        ::= Identifier <Close Options> 

<Close Options> 
        ::= UNIT <Close Method>
         |  REEL <Close Method>
         |  <WITH Opt> LOCK
         |  <WITH Opt> NO REWIND
         |  !Empty
       
<Close Method>  
        ::= <FOR Opt> REMOVAL
         |  !Optional
        
! -----------------------------------------------------------------------------  
! COMPUTE Statement
! -----------------------------------------------------------------------------              

<Compute Sent> 
        ::= <Compute Stm> <Size Clauses> <END-COMPUTE Opt>
         |  <Compute Stm>

<Compute Embed> 
        ::= <Compute Stm> <Size Clauses> END-COMPUTE
         |  <Compute Stm>

<Compute Imp> 
        ::= <Compute Stm>

<Compute Stm> 
        ::= COMPUTE Identifier <ROUNDED Opt> <Equal Op> <Math Exp>
       
<Math Exp>
        ::= <Math Exp> '+' <Mult Exp>
         |  <Math Exp> '-' <Mult Exp>
         |  <Mult Exp> 

<Mult Exp>
        ::= <Mult Exp> '*' <Negate Exp>
         |  <Mult Exp> '/' <Negate Exp>
         |  <Negate Exp>

<Negate Exp>   
        ::= '-' <Value>
         |  <Value>
         |  '(' <Math Exp> ')'

<END-COMPUTE Opt>
        ::= END-COMPUTE
         |  !Optional

! -----------------------------------------------------------------------------  
! CONTINUE
! -----------------------------------------------------------------------------              

<Continue Sent> 
        ::= <Continue Stm> 

<Continue Embed> 
        ::= <Continue Stm> 

<Continue Imp> 
        ::= <Continue Stm> 

<Continue Stm> 
        ::= CONTINUE

! -----------------------------------------------------------------------------  
! DELETE Statement
! -----------------------------------------------------------------------------
           
<Delete Sent>
        ::= <Delete Stm> <Invalid Key Clauses> <END-DELETE Opt>
         |  <Delete Stm> 

<Delete Embed>
        ::= <Delete Stm> <Invalid Key Clauses> END-DELETE
         |  <Delete Stm>

<Delete Imp>
        ::= <Delete Stm>

<Delete Stm>
        ::= DELETE Identifier <RECORD Opt>

<END-DELETE Opt>
        ::= END-DELETE
         |  !Optional

! -----------------------------------------------------------------------------  
! DISABLE Statement
! -----------------------------------------------------------------------------

<Disable Sent>    
        ::= <Disable Stm> 

<Disable Embed>    
        ::= <Disable Stm> 

<Disable Imp>    
        ::= <Disable Stm> 

<Disable Stm> 
        ::= DISABLE <Enabled Disable Mode> Identifier <Enable Disable Key>
         
! -----------------------------------------------------------------------------  
! DISPLAY Statement
! -----------------------------------------------------------------------------

<Display Sent>    
        ::= <Display Stm> 

<Display Embed>    
        ::= <Display Stm> 

<Display Imp>    
        ::= <Display Stm> 
    
<Display Stm> 
        ::= DISPLAY <Values> <Display Target> <Advancing Clause>

<Display Target>
        ::= UPON Identifier
         |  !Optional

<Advancing Clause>
        ::= <WITH Opt> NO ADVANCING
         |  !Optional

! -----------------------------------------------------------------------------  
! DIVIDE Statement
! -----------------------------------------------------------------------------       

<Divide Sent> 
        ::= <Divide Stm> <Size Clauses> <END-DIVIDE Opt> 
         |  <Divide Stm>

<Divide Embed> 
        ::= <Divide Stm> <Size Clauses> 'END-DIVIDE' 
         |  <Divide Stm>

<Divide Imp>
        ::= <Divide Stm> 

<Divide Stm> 
        ::= DIVIDE <Values> BY   <Values>
         |  DIVIDE <Values> BY   <Values> GIVING <Variable> <ROUNDED Opt> 
         |  DIVIDE <Values> INTO <Values>
         |  DIVIDE <Values> INTO <Values> GIVING <Variable> <ROUNDED Opt> <Remainder Opt>

<Remainder Opt>
        ::= REMAINDER <Variable>
         |  !Optional
 
<END-DIVIDE Opt>
        ::= END-DIVIDE
         |  !Optional

! -----------------------------------------------------------------------------  
! ENABLE Statement
! -----------------------------------------------------------------------------       

<Enable Sent>
        ::= <Enable Stm>  

<Enable Embed>
        ::= <Enable Stm>  

<Enable Imp>
        ::= <Enable Stm>  

<Enable Stm> 
        ::= ENABLE <Enabled Disable Mode> Identifier <Enable Disable Key>
         
! -----------------------------------------------------------------------------  
! EVALUATE Statement
! -----------------------------------------------------------------------------

<Evaluate Sent> 
        ::= <Evaluate Stm> <END-EVALUATE Opt> 

<Evaluate Embed> 
        ::= <Evaluate Stm> END-EVALUATE

<Evaluate Imp> 
        ::= <Evaluate Stm> END-EVALUATE
 
<Evaluate Stm> 
        ::= EVALUATE <Subjects> <When Clauses> 
              
<Subjects>
        ::= <Subjects> ALSO <Subject>
         |  <Subject>

<Subject>
        ::= TRUE
         |  <Boolean Exp>

<When Clauses>
        ::= <When Clauses> <When Clause>
         |  <When Clause>

<When Clause>  
        ::= WHEN <Phrases> <THEN Opt> <Embed Stms>
         |  WHEN OTHER <THEN Opt> <Embed Stms>

<Phrases> 
        ::= <Phrases> ALSO <Phrase>
         |  <Phrase>

<Phrase>  
        ::= ANY
         |  <Symbolic Value> THROUGH <Symbolic Value>
         |  <Symbolic Value> THRU <Symbolic Value>
         |  <Symbolic Value>

<END-EVALUATE Opt>
        ::= END-EVALUATE
         |  !Optional

! -----------------------------------------------------------------------------  
! EXIT Statement
! -----------------------------------------------------------------------------       

<Exit Sent>
       ::= <Exit Stm>

<Exit Embed>
       ::= <Exit Stm>

<Exit Imp>
       ::= <Exit Stm>

<Exit Stm> 
        ::= EXIT
         |  EXIT PROGRAM
         
! -----------------------------------------------------------------------------  
! GENERATE Statement
! -----------------------------------------------------------------------------       

<Generate Sent>
        ::= <Generate Stm>

<Generate Embed>
        ::= <Generate Stm>

<Generate Imp>
        ::= <Generate Stm>

<Generate Stm>     
        ::= GENERATE Identifier
        
! -----------------------------------------------------------------------------  
! GO TO Statement
! -----------------------------------------------------------------------------       

<Go To Sent> 
        ::= <Go To Stm>

<Go To Embed> 
        ::= <Go To Stm>

<Go To Imp> 
        ::= <Go To Stm>

<Go To Stm>          
        ::= GO TO Identifier
         |  GO TO <Identifiers> DEPENDING ON <Variable>
                
! -----------------------------------------------------------------------------  
! IF Statement
! -----------------------------------------------------------------------------

<If Sent> 
        ::= <If Stm> <END-IF Opt>          

<If Embed> 
        ::= <If Stm> END-IF

<If Imp> 
        ::= <If Stm> END-IF

<If Stm> 
        ::= IF <Boolean Exp> <THEN Opt> <Embed Stms>
         |  IF <Boolean Exp> <THEN Opt> <Embed Stms> ELSE <THEN Opt> <Embed Stms>
         |  IF <Boolean Exp> <THEN Opt> <Embed Stms> ELSE NEXT SENTENCE

<END-IF Opt>
        ::= END-IF
         |  !Optional

! -----------------------------------------------------------------------------  
! INITIALIZE Statement
! -----------------------------------------------------------------------------

<Initialize Sent> 
        ::= <Initialize Stm>  

<Initialize Embed> 
        ::= <Initialize Stm> 

<Initialize Imp> 
        ::= <Initialize Stm> 

<Initialize Stm> 
        ::= INITIALIZE <Variables> <Replacing Opt>
        
<Replacing Opt>
        ::= REPLACING <Replacing Items>
        
<Replacing Items>
        ::= <Replacing Items> <Replacing Item>
         |  <Replacing Item>
        
<Replacing Item>        
        ::= <Replacing Type> <DATA Opt> <Value>

<Replacing Type> 
        ::= ALPHABETIC       
         |  ALPHANUMERIC     
         |  NUMERIC          
         |  ALPHANUMERIC-EDITED 
         |  NUMERIC-EDITED 

! -----------------------------------------------------------------------------  
! INITIATE Statement
! -----------------------------------------------------------------------------

<Initiate Sent> 
        ::= <Initiate Stm>

<Initiate Embed> 
        ::= <Initiate Stm>

<Initiate Imp> 
        ::= <Initiate Stm>

<Initiate Stm> 
        ::= INITIATE <Identifiers> 
         
! -----------------------------------------------------------------------------  
! INSPECT Statement
! -----------------------------------------------------------------------------

<Inspect Sent> 
        ::= <Inspect Stm> 

<Inspect Embed> 
        ::= <Inspect Stm> 

<Inspect Imp> 
        ::= <Inspect Stm> 

<Inspect Stm>        
        ::= INSPECT <Variable> TALLYING <Tally Variables>
         |  INSPECT <Variable> TALLYING <Tally Variables> REPLACING <Replace Chars>
         |  INSPECT <Variable> REPLACING <Replace Chars>
         |  INSPECT <Variable> CONVERTING <Value> TO <Value> <Inspect Specs>       

! ----------------------------------- Tally group

<Tally Variables>
        ::= <Tally Variables> <Tally Variable>
         |  <Tally Variable>
         
<Tally Variable>           
        ::= <Variable> FOR <Tally Items>

<Tally Items>
        ::= <Tally Items> <Tally Item>
         |  <Tally Item>
        
<Tally Item>
        ::= CHARACTERS <Inspect Specs>
         |  ALL      <Value> <Inspect Specs>
         |  LEADING  <Value> <Inspect Specs>

! ----------------------------------- Replacing group
 
<Replace Chars>
        ::= <Replace Chars> <Replace Char>
         |  <Replace Char>
         
<Replace Char>
        ::= CHARACTERS BY <Value> <Inspect Specs>
         |  ALL     <Replace Items>
         |  LEADING <Replace Items>
         |  FIRST   <Replace Items>
        
<Replace Items>
        ::= <Replace Items> <Replace Item>
         |  <Replace Item>
                
<Replace Item>
        ::= <Value> BY <Value> <Inspect Specs>

! ----------------------------------- Substring Specifiers
        
<Inspect Specs>
        ::= <Inspect Specs> <Inspect Spec>
         |  !Zero or more

<Inspect Spec>
        ::= <BEFORE AFTER> INITIAL <Value>
        
! -----------------------------------------------------------------------------  
! MERGE Statement
! -----------------------------------------------------------------------------     

<Merge Sent>
        ::= <Merge Stm>

<Merge Embed>
        ::= <Merge Stm>

<Merge Imp>
        ::= <Merge Stm>

<Merge Stm>
        ::= MERGE Identifier <Sort Keys> <Collating Clause> USING <Identifiers> <Sort Target>
        
! -----------------------------------------------------------------------------  
! MOVE Statement
! -----------------------------------------------------------------------------       

<Move Sent> 
        ::= <Move Stm> <Size Clauses> <END-MOVE Opt>
         |  <Move Stm> 

<Move Embed> 
        ::= <Move Stm> <Size Clauses> END-MOVE
         |  <Move Stm> 

<Move Imp> 
        ::= <Move Stm>

<Move Stm> 
        ::= MOVE <Symbolic Value> TO <Variables>               
         |  MOVE <CORRESPONDING> Identifier TO Identifier 
 
<END-MOVE Opt>
        ::= END-MOVE
         |  !Optional

! -----------------------------------------------------------------------------  
! MULTIPLY Statement
! -----------------------------------------------------------------------------       

<Multiply Sent> 
        ::= <Multiply Stm> <Size Clauses> <END-MULTIPLY Opt>
         |  <Multiply Stm>

<Multiply Embed> 
        ::= <Multiply Stm> <Size Clauses> END-MULTIPLY
         |  <Multiply Stm>

<Multiply Imp> 
        ::= <Multiply Stm>

<Multiply Stm> 
        ::= MULTIPLY <Variables> BY <Multiply Items> <Giving Clause Opt>

<Multiply Items>
        ::= <Multiply Items> <Multiply Item>
         |  <Multiply Item>

<Multiply Item>
        ::= <Value> <ROUNDED Opt>

<END-MULTIPLY Opt>
        ::= END-MULTIPLY
         |  !Optional

! -----------------------------------------------------------------------------  
! OPEN Statement
! ----------------------------------------------------------------------------- 

<Open Sent>
        ::= <Open Stm>

<Open Embed>
        ::= <Open Stm>

<Open Imp>
        ::= <Open Stm>

<Open Stm> 
        ::= OPEN <Open List>
        
<Open List> 
        ::= <Open List> <Open Entry> 
         |  <Open Entry>
              
<Open Entry>
        ::= INPUT  <Variables> <Open No Rewind>
         |  OUTPUT <Variables> <Open No Rewind>
         |  EXTEND <Variables> <Open No Rewind>
         |  I-O    <Variables> <Open No Rewind>
        
<Open No Rewind>
        ::= <WITH Opt> NO REWIND
         |  !Optional
         
! -----------------------------------------------------------------------------  
! PERFORM Statement
! -----------------------------------------------------------------------------              

<Perform Sent>
        ::= <Perform Block> <END-PERFORM Opt>
         |  <Perform Stm>
         |  <Perform Loop>

<Perform Embed>
        ::= <Perform Block> END-PERFORM
         |  <Perform Stm>
         |  <Perform Loop>
           
<Perform Imp>
        ::= <Perform Block> END-PERFORM
         |  <Perform Stm>


<Perform Stm>
        ::= PERFORM <Identifier Range>
         |  PERFORM <Identifier Range> <Numeric> TIMES 

<Perform Loop>
        ::= PERFORM <Identifier Range> <With Test> UNTIL <Boolean Exp> 
         |  PERFORM <Identifier Range> <With Test> VARYING <Perform For List>  

<Perform Block>
        ::= PERFORM <With Test> UNTIL <Boolean Exp>         <Embed Stms>
         |  PERFORM <With Test> VARYING <Perform For List>  <Embed Stms>
         |  PERFORM <Numeric> TIMES                         <Embed Stms>

<With Test> 
        ::= <WITH Opt> TEST <BEFORE AFTER>
         |  !Optional
                      
<Perform For List>
        ::= <Perform For List> AFTER <Perform For Range>
         |  <Perform For Range>

<Perform For Range>
        ::=  <Variable> FROM <Numeric> BY <Numeric> UNTIL <Boolean Exp>

<END-PERFORM Opt>
        ::= END-PERFORM
         |  !Optional

! -----------------------------------------------------------------------------  
! READ Statement
! -----------------------------------------------------------------------------

<Read Sent> 
        ::= <Read Stm> <Read Msg Clauses> <END-READ Opt> 
         |  <Read Stm>

<Read Embed> 
        ::= <Read Stm> <Read Msg Clauses> END-READ 
         |  <Read Stm>

<Read Imp> 
        ::= <Read Stm>

<Read Stm> 
        ::= READ Identifier <Next Opt> <RECORD Opt>                                 
         |  READ Identifier <Next Opt> <RECORD Opt> INTO <Variable> <Read Key Opt>  
             
<Read Msg Clauses>
        ::= <At End Clauses>
         |  <Invalid Key Clauses>

<Read Key Opt>
        ::= KEY <IS Opt> Identifier
         |  !Optional

<END-READ Opt>
        ::= END-READ
         |  !Optional

! -----------------------------------------------------------------------------  
! RELEASE Statement
! -----------------------------------------------------------------------------

<Release Sent>
        ::= <Release Stm>

<Release Embed>
        ::= <Release Stm>

<Release Imp>
        ::= <Release Stm>

<Release Stm>
        ::= RELEASE Identifier 
         |  RELEASE Identifier FROM Identifier
       
! -----------------------------------------------------------------------------  
! RETURN Statement
! -----------------------------------------------------------------------------

<Return Sent> 
        ::= <Return Stm> 

<Return Embed> 
        ::= <Return Stm> 

<Return Imp> 
        ::= <Return Stm> 

<Return Stm> 
        ::= RETURN Identifier <RECORD Opt>
         |  RETURN Identifier <RECORD Opt> INTO Identifier
        
! -----------------------------------------------------------------------------  
! REWRITE Statement
! -----------------------------------------------------------------------------

<Rewrite Sent>
        ::= <Rewrite Stm> <Invalid Key Clauses> <END-REWRITE Opt>
         |  <Rewrite Stm>

<Rewrite Embed>
        ::= <Rewrite Stm> <Invalid Key Clauses> END-REWRITE
         |  <Rewrite Stm>

<Rewrite Imp>
        ::= <Rewrite Stm>

<Rewrite Stm>
        ::= REWRITE Identifier                     
         |  REWRITE Identifier FROM Identifier 

<END-REWRITE Opt>   
        ::= END-REWRITE
         |  !Optional

! -----------------------------------------------------------------------------  
! SEARCH Statement
! -----------------------------------------------------------------------------

<Search Sent> 
        ::= <Search Stm> <END-SEARCH Opt>

<Search Embed> 
        ::= <Search Stm> END-SEARCH

<Search Imp> 
        ::= <Search Stm> END-SEARCH
         
<Search Stm> 
        ::= SEARCH Identifier <Varying Opt> <At End Clauses> <When Clauses>
         |  SEARCH ALL Identifier           <At End Clauses> <When Clauses>

<Varying Opt>
        ::= VARYING <Value>
         |  !Optional 

<END-SEARCH Opt> 
        ::= END-SEARCH
         |  !Optional

! -----------------------------------------------------------------------------  
! SEND Statement
! -----------------------------------------------------------------------------

<Send Sent>
        ::= <Send Stm> 

<Send Embed>
        ::= <Send Stm> 

<Send Imp>
        ::= <Send Stm> 

<Send Stm> 
        ::= SEND Identifier FROM <Variable>
         |  SEND Identifier FROM <Variable> <Send With> <Send Spec> <Send Replacing Opt>
         |  SEND Identifier                 <Send With> <Send Spec> <Send Replacing Opt>

<Send With> 
        ::= <WITH Opt> Identifier
         |  <WITH Opt> ESI
         |  <WITH Opt> EMI
         |  <WITH Opt> EGI
        
<Send Spec>
        ::= <BEFORE AFTER> <ADVANCING Opt> <Send Advance>

<Send Advance>
        ::= <Value> <LINES Opt>
         |  PAGE
               
<Send Replacing Opt>
        ::= REPLACING <LINE Opt>

! -----------------------------------------------------------------------------  
! SET Statement
! -----------------------------------------------------------------------------

<Set Sent>
        ::= <Set Stm> 

<Set Embed>
        ::= <Set Stm> 

<Set Imp>
        ::= <Set Stm> 

<Set Stm> 
        ::= SET <Variables> UP BY <Value>         
         |  SET <Variables> DOWN BY <Value>
         |  SET <Variables> TO <Set Value> 
         
<Set Value> 
        ::= ON
         |  OFF
         |  TRUE

! -----------------------------------------------------------------------------  
! SORT Statement
! -----------------------------------------------------------------------------

<Sort Sent>
        ::= <Sort Stm>

<Sort Embed>
        ::= <Sort Stm>

<Sort Imp>
        ::= <Sort Stm>

<Sort Stm>
        ::= SORT <Value> <Sort Keys> <Sort Duplicates Opt> <Collating Opt> <Sort Source> <Sort Target>
        
<Sort Duplicates Opt>
        ::= <WITH Opt> DUPLICATES <IN Opt> <ORDER opt>
         |  !Optional
              
! -----------------------------------------------------------------------------  
! START Statement
! -----------------------------------------------------------------------------

<Start Sent> 
        ::= <Start Stm> <Invalid Key Clauses> <END-START Opt>
         |  <Start Stm>

<Start Embed> 
        ::= <Start Stm> <Invalid Key Clauses> END-START
         |  <Start Stm>

<Start Imp> 
        ::= <Start Stm>

<Start Stm>   
        ::= START Identifier <Start Key Opt>

<Start Key Opt>
        ::= KEY <Compare Op> Identifier
         |  !Optional

<END-START Opt>
        ::= END-START
         |  !Optional

! -----------------------------------------------------------------------------  
! STOP Statement
! -----------------------------------------------------------------------------

<Stop Sent>
        ::= <Stop Stm> 

<Stop Embed>
        ::= <Stop Stm> 

<Stop Imp>
        ::= <Stop Stm> 

<Stop Stm>
        ::= STOP RUN
         |  STOP <Literal>
                 
! -----------------------------------------------------------------------------  
! STRING Statement
! -----------------------------------------------------------------------------

<String Sent>
        ::= <String Stm> <Overflow Clauses> <END-STRING Opt>
         |  <String Stm> 

<String Embed>
        ::= <String Stm> <Overflow Clauses> END-STRING
         |  <String Stm> 

<String Imp>
        ::= <String Stm>

<String Stm>    
        ::= STRING <String Items> INTO <Variable> <Pointer Clause>

<String Items>
        ::= <String Item> <String Items>
         |  <String Item>

<String Item>
        ::= <Values> DELIMITED <BY Opt> <Value>
           
<END-STRING Opt>    
        ::= END-STRING
         |  !Optional

! -----------------------------------------------------------------------------  
! SUBTRACT Statement
! -----------------------------------------------------------------------------       

<Subtract Sent>
        ::= <Subtract Stm> <Size Clauses> <END-SUBTRACT Opt>
         |  <Subtract Stm> 

<Subtract Embed>
        ::= <Subtract Stm> <Size Clauses> END-SUBTRACT
         |  <Subtract Stm> 

<Subtract Imp>
        ::= <Subtract Stm> 

<Subtract Stm> 
        ::= SUBTRACT <Values> FROM <Variables> <Giving Clause Opt>
          | SUBTRACT <CORRESPONDING> <Value> FROM Identifier
        
<END-SUBTRACT Opt> 
        ::= END-SUBTRACT
         |  !Optional

! -----------------------------------------------------------------------------  
! SUPPRESS Statement
! -----------------------------------------------------------------------------

<Suppress Sent> 
        ::= <Suppress Stm>  

<Suppress Embed> 
        ::= <Suppress Stm>  

<Suppress Imp> 
        ::= <Suppress Stm>  

<Suppress Stm> 
        ::= SUPPRESS <PRINTING Opt>
                          
! -----------------------------------------------------------------------------  
! TERMMINATE Statement
! -----------------------------------------------------------------------------

<Terminate Sent> 
        ::= <Terminate Stm> 

<Terminate Embed> 
        ::= <Terminate Stm> 

<Terminate Imp> 
        ::= <Terminate Stm> 

<Terminate Stm> 
        ::= TERMINATE <Identifiers>                                                 
                         
! -----------------------------------------------------------------------------  
! UNSTRING Statement
! -----------------------------------------------------------------------------

<Unstring Sent>
        ::= <Unstring Stm> <Overflow Clauses> <END-UNSTRING Opt>
         |  <Unstring Stm> 

<Unstring Embed>
        ::= <Unstring Stm> <Overflow Clauses> END-UNSTRING
         |  <Unstring Stm> 

<Unstring Imp>
        ::= <Unstring Stm> 

<Unstring Stm>
        ::= UNSTRING identifier <Delimiter Clause> INTO Identifier <Unstring Options>

<Delimiter Clause>
        ::= DELIMITED <BY Opt> <Unstring Delimiter List>
         |  !Optional

<Unstring Delimiter List>
        ::= <Unstring Delimiter List> OR <Unstring Delimiter>
         |  <Unstring Delimiter> 

<Unstring Delimiter>
        ::= <ALL Opt> <Value>

<Unstring Options>
        ::= <Unstring Options> <Unstring Option> 
         |  !Empty

<Unstring Option> 
        ::= <WITH Opt> POINTER <Variable>
         |  TALLYING <IN Opt> Identifier 
 
<END-UNSTRING Opt>  
        ::= END-UNSTRING
         |  !Optional

! -----------------------------------------------------------------------------  
! USE Statement
! -----------------------------------------------------------------------------

<Use Sent> 
        ::= <Use Stm> 

<Use Embed> 
        ::= <Use Stm> 

<Use Imp> 
        ::= <Use Stm> 

<Use Stm> 
        ::= USE <GLOBAL Opt> AFTER STANDARD <Use Proc Type> PROCEDURE ON <Use Access>
         |  USE <GLOBAL Opt> BEFORE REPORTING Identifier
         |  USE <FOR Opt> DEBUGGING <ON Opt> <Use Debug>

<Use Proc Type>
        ::= EXCEPTION
         |  ERROR

<Use Access>
        ::= INPUT
         |  OUTPUT
         |  I-O
         |  EXTEND
         |  <Value>
         
<Use Debug>
        ::= ALL <REFERENCES Opt> <OF Opt> Identifier
         |  ALL PROCEDURES
         |  <Value>

! -----------------------------------------------------------------------------  
! WRITE Statement
! -----------------------------------------------------------------------------

<Write Sent> 
        ::= <Write Stm> <Invalid Key Clauses> <END-WRITE Opt>
         |  <Write Stm> <AT EOP Clauses>      <END-WRITE Opt>  
         |  <Write Stm> 

<Write Embed> 
        ::= <Write Stm> <Invalid Key Clauses> END-WRITE
         |  <Write Stm> <AT EOP Clauses>      END-WRITE  
         |  <Write Stm> 

<Write Imp> 
        ::= <Write Stm> 

<Write Stm> 
        ::= WRITE Identifier                 <Write Options>
         |  WRITE Identifier FROM Identifier <Write Options>
           
<Write Options> 
        ::= <BEFORE AFTER> <ADVANCING Opt> <Write Advance>

<Write Advance>
        ::= <Value> <LINES Opt>
         |  PAGE 
               
<END-WRITE Opt>
        ::= END-WRITE
         |  !Optional

Delphi

! -----------------------------------------------------------------------
! Delphi 7.0 Object Pascal Grammar
! -----------------------------------------------------------------------
! (c) Rob F.M. van den Brink - the Netherlands, 2006 - R.F.M.vandenBrink@hccnet.nl
! Version V1.1, Aug 2006
!
! This grammar parses almost everything of the language, except for a few issues
! that are probably beyond the capabilities of Gold parser.
! Known limitations:
! (1) Cannot handle comment directives like {$ifdef Windows} ... {$endif} 
!     When parts of the source code is uncommented in this way, the grammer will
!     still read it, and may fail.
! (2) The parser consumes all assembler statements, but is too tolerant in accepting
!     input. Groups of several <AsmItem> does not belong to a single <AsmInstruction>
!     because a 'newline' is regarded as whitespace while it should be a terminator here.
! (3) Lexemes like 'protected' , 'forward' can be both a keyword as well as an identifier
!     in Delphi (even in the same object declaration), and when these lexemes should mean
!     an identifier, the current grammar cannot handle it correctly.
!     For several of them a workaround was created, but a better solution should be 
!     developped.
! (4) Strings with characters above #127 cannot be handled by the current Grammar. 
!     This should be very simple, but if the grammar defines string characters
!     as the range {#32 .. #255}, Goldparser also adds {#376} and {#956}. 
!     This looks like a bug in Gold Parser.
! (5) The inclusion of an adequate number of error productions (SynError) is still 
!     to be done.
! (6) constructs that are considered (for the timebeing) as too weird, are not
!     supported; see below.
! -----------------------------------------------------------------------
! This grammar supports also most of 'weird' constructs that Borland has added 
! to Delphi. This refers to the inconsistent syntax for several directives 
! like in <CallConvention> and <MethodDirective>. Sometimes these directives have
! to be separated by an ';' sometimes not and somtimes both is alowed.  
! An example of a syntax that was considered as too weird to be covered by this 
! grammar was found in library routine "IdSSLOpenSSLHeaders.pas" (comes with Delphi) 
!   VAR
!      IdSslCtxSetVerifyDepth : procedure(ctx: PSSL_CTX; depth: Integer); cdecl = nil;
!      IdSslCtxGetVerifyDepth : function (ctx: PSSL_CTX):Integer;  cdecl = nil;
! In a consistent syntax, cdecl should refer to some variable that is set to "nil', but
! the ';' does not close the <TypeSpec> and the rest is still part of the syntax
!
! -----------------------------------------------------------------------
! Version history
!  V1.0 - June 2006, derived from scratch, using Delphi 7.0 help and code files
!  V1.1 - Aug 2006,  lots of refinements to cover almost evberything of the language
!                    Consumes assembler code as well.
! -----------------------------------------------------------------------

"Name"    = 'ObjectPascal' 
"Version" = '1.1, Aug 2006'
"Author"  = 'Rob F.M. van den Brink' 
"About"   = 'Derived from scratch, from Delphi 7.0 help and experiments with code files'
"Start Symbol"  = <ObjectPascal> 

!------------------------------------------------------------------------------
"Case Sensitive" = False
"Virtual Terminals" = SynError CommentStart2 CommentEnd2


Comment Line     =  '//'
Comment Start 	 =  '{'
Comment End      =  '}'

CommentStart1    =  '(*'
CommentEnd1      =  '*)'


{Hex Digit}      = {Digit} + [abcdefABCDEF]

{Id Head}        = {Letter} + [_]

{Id Tail}        = {Id Head} + {Digit}

!{String Ch}      = {#32 .. #255} - [''] + {HT} !WHY DOES GOLS ADD character #376 and #956 ??

{String Ch}      = {printable} - [''] + {HT}


DecLiteral       = {digit}+

HexLiteral       = '$'{Hex Digit}+

FloatLiteral     = {Digit}+.{Digit}+

RealLiteral      = {Digit}+ ('.' {Digit}* | {Digit}*) ('E' '+' | 'E' '-' | 'E') {digit}+


StringLiteral    = (  '' {String Ch}* ''  |  '#' {digit}+  |  '#' '$' {hex digit}+  |  ''''  )+

!StringLiteral	 = ( ( '' {String Ch}* '' )
!		   | ( '#' {digit}+ )
!		   | ( '#' '$' {hex digit}+ )
!		   | ( '''' )
!		   )+

id               = {Id Head}{Id Tail}*




<LCONST>		::= DecLiteral

<ICONST>		::= DecLiteral
			  | HexLiteral

<RCONST>		::= FloatLiteral
			  | RealLiteral

<SCONST>		::= StringLiteral
			  | '^' id	! handles characters like ^H and ^V

		       
!------------------------------------------------------------------------------

!<UnitId>		::= id

<IdList>		::= <IdList> ',' <RefId>
			  | <RefId>

<LabelId>		::= id			  

<TypeId>		::= id
!			  | id '.' <RefId>
			  | NAME
			  
<TypeName>		::= <TypeId>
			  | id '.' <RefId>	!!accepts UnitId.Id as well
			  

<TypeList>		::= <TypeName>
			  | <TypeList> ',' <TypeName>
			  

<RefId>			::= id 
			  | AT | ON | READ | WRITE | READLN | WRITELN | NAME | INDEX 
			  | VIRTUAL | ABSOLUTE | MESSAGE  | DEFAULT | OVERRIDE | ABSTRACT
			  | DISPID | REINTRODUCE
			  | REGISTER | PASCAL | CDECL | STDCALL | SAFECALL
			  | STRING  | WIDESTRING | ANSISTRING 
			  | VARIANT | OLEVARIANT
			  | READONLY | IMPLEMENTS | NODEFAULT | STORED 
		          | OVERLOAD	| LOCAL	| VARARGS  
		          | FORWARD
		          | CONTAINS | PACKAGE | REQUIRES | LIBRARY
			  | IMPORT | EXPORT
			  | PLATFORM | DEPRECATED 
			  | EXTERNAL 
			   
		         ! PROTECTED | PUBLISHED | PRIVATE | PUBLIC !THIS FAILS IN FIELDS


<FieldDesignator>	::= <RefId>
			  | <FieldDesignator> '.' <RefId>



!* predefined identifiers are no part of a syntax			  
<RealTypeId>		::= REAL48
			  | REAL
			  | SINGLE
			  | DOUBLE
			  | EXTENDED
			  | CURRENCY
			  | COMP
         

<OrdTypeId>		::= SHORTINT
			  | SMALLINT
			  | INTEGER
			  | BYTE
			  | LONGINT
			  | INT64
			  | WORD
			  | BOOLEAN
			  | CHAR
			  | WIDECHAR
			  | LONGWORD
			  | PCHAR
*!

!------------------------------------------------------------------------------
! M O D U L E S
!------------------------------------------------------------------------------

<ObjectPascal>		::= <Program> | <Unit> | <Package> | <Library> 

<Program>		::= <ProgHeader> <OptUsesSection> <Block> '.'

<ProgHeader>		::= PROGRAM <RefId> <OptProgParamList> ';'

<OptProgParamList>	::= '(' <IdList> ')' 
			  | 
			

           
<Unit>			::= <UnitHeader>  <InterfaceSection> <ImplementationSection> <InitSection> '.'

<UnitHeader>		::= UNIT <RefId> <OptPortDirectives> ';'
           

<Package>		::= <PackageHeader> <OptRequiresClause> <OptContainsClause> END '.'


<PackageHeader>		::= PACKAGE <RefId> ';'

<OptRequiresClause>	::= REQUIRES <IdList> ';'
			  |

<OptContainsClause>	::= CONTAINS <IdList> ';'
			  |

<LibraryHeader>		::= LIBRARY <RefId>  ';'

<Library>		::= <LibraryHeader> <OptUsesSection> <Block> '.'



<InterfaceSection>	::= INTERFACE <OptUsesSection> <OptExportDeclList> 

<OptUsesSection>	::= <UsesSection>
			  | 


<UsesClause>		::= USES <IdList> ';'
			  | SynError

<UsesSection>		::= <UsesClause>
			  | <UsesSection> <UsesClause> 

<OptExportDeclList>	::= <ExportDeclList> 
			  |

<ExportDeclList>	::= <ExportDeclItem> 
			  | <ExportDeclList>  <ExportDeclItem>

<ExportDeclItem>	::= <ConstSection>
			  | <TypeSection> 
			  | <VarSection>
			  | <CallSection>
			  | <CallSection>  FORWARD ';'
		! The forward directive has no effect in the interface section of a unit,
		! but is not forbidden here. 

<CallSection>		::= <ProcHeading>  
			  | <FuncHeading>   



<ImplementationSection>	::= IMPLEMENTATION <OptUsesSection> <OptDeclSection> <OptExportBlock>
                         
<InitSection>		::= INITIALIZATION <StmtList> END
			  | INITIALIZATION <StmtList> FINALIZATION <StmtList> END
			  | <CompoundStmt>
			  | END

<Block>			::= <OptDeclSection> <OptExportBlock> <CompoundStmt> <OptExportBlock> 


<OptExportBlock>	::= <ExportStmt>
			  | <OptExportBlock>  <ExportStmt>	
			  |

<ExportStmt>		::= EXPORTS <ExportList> ';'


<ExportList>		::= <ExportItem>
			  | <ExportList> ',' <ExportItem>

<ExportItem>		::= id 
			  | id NAME  '' <ConstExpr> ''
			  | Id INDEX '' <ConstExpr> ''
			  |    NAME  '' <ConstExpr> ''
			  |    INDEX '' <ConstExpr> ''
                     

!------------------------------------------------------------------------------
! D E C L A R A T I O N S
!------------------------------------------------------------------------------

<OptDeclSection>	::= <DeclSection>
			  |

<DeclSection>		::= <DeclItem>
			  | <DeclSection>  <DeclItem>

<DeclItem>		::= <LabelSection>
			  | <ConstSection>
			  | <TypeSection> 
			  | <VarSection>
			  | <ProcedureDeclSection>
			  |  SynError
			  
            
<LabelSection>		::= LABEL <LabelList> ';'

<LabelList>		::= <LabelId>
			  | <LabelList> ',' <LabelId>

!-----CONSTS-------------------------------------------------------------------

<ConstSection>		::= CONST          <ConstantDeclList> 
			  | RESOURCESTRING <ConstantDeclList>  !all these constants should be string

<ConstantDeclList>	::= <ConstantDecl>  
			  | <ConstantDeclList>  <ConstantDecl>	

<ConstantDecl>		::= <RefId>            '=' <ConstExpr>     <OptPortDirectives> ';'
			  | <RefId> ':' <Type> '=' <TypedConstant> <OptPortDirectives> ';'
			  | SynError ';'
             

<TypedConstant>		::= <ConstExpr> 
			  | <ArrayConstant> 
			  | <RecordConstant>

<ArrayConstant>		::= '(' <TypedConstList> ')'

<RecordConstant>	::= '(' <RecordFieldConstList>     ')'
			  | '(' <RecordFieldConstList> ';' ')'
			  | '(' ')'	!only to initialize globar vars"

<RecordFieldConstList>	::= <RecordFieldConstant>
			  | <RecordFieldConstList> ';' <RecordFieldConstant>

<RecordFieldConstant>	::= <RefId> ':' <TypedConstant>

<TypedConstList>	::= <TypedConstant>
			  | <TypedConstList> ',' <TypedConstant>


!-----TYPES--------------------------------------------------------------------


<TypeSection>		::= TYPE <TypeDeclList> 

<TypeDeclList>		::= <TypeDecl>  
			  | <TypeDeclList>  <TypeDecl> 

<TypeDecl>		::= <TypeId> '=' <TypeSpec>
			  | SynError ';'


<TypeSpec>		::= <GenericType>    ';'		  
			  | <RestrictedType> <OptPortDirectives> ';'	  
			  | <CallType>       ';' 
			  | <CallType>       ';' <CallConventions>  ';' 
			  |  SynError        ';'

<Type>			::= <GenericType> 
 			  | <CallType>

<TypeRef>		::= <TypeName>
			  | <StringType>
			  | <VariantType>

<GenericType>		::= <TypeName>       
			  | <StringType>
			  | <VariantType>
			  | <SubrangeType> 
			  | <EnumType>
			  | <StructType>  
			  | <PointerType> 
			  | <ClassRefType>
			  | <ClonedType>


<ClonedType>		::= TYPE <TypeRef>


<StringType>		::= STRING
			  | ANSISTRING
			  | WIDESTRING
			  | STRING '[' <ConstExpr> ']'
		          
<VariantType>		::= VARIANT
			  | OLEVARIANT
            
<OrdinalType>		::= <SubrangeType> | <EnumType> | <TypeName>

<SubrangeType>		::=  <ConstOrdExpr> '..' <ConstOrdExpr>
			  |  <ConstOrdExpr>  SynError
			  | '(' <RefId> ')' '..' <ConstOrdExpr>




<EnumType>		::= '(' <EnumList> ')' 
			  | '(' <RefId> ')'

<EnumList>		::= <EnumId>  
			  | <EnumList> ',' <EnumId>
			  
<EnumId>		::= <RefId>
			  | <RefId> '=' <ConstExpr>


<OptPacked>		::= PACKED
			  |
			  
<StructType>		::= <ArrayType>
			  | <SetType>
			  | <FileType>
			  | <RecType>


<ArrayType>		::= <OptPacked> ARRAY '[' <OrdinalTypeList> ']' OF <Type> 
			  | <OptPacked> ARRAY OF CONST
			  | <OptPacked> ARRAY OF <Type> !dynamic array, starting from 0
!    FCells: array of array of TIWGridCell;


<OrdinalTypeList>	::= <OrdinalType>
			  | <OrdinalTypeList> ',' <OrdinalType>



<RecType>		::= <OptPacked> RECORD <RecFieldList> END <OptPortDirectives>

<RecFieldList>		::= 
			  | <RecField1> 
			  | <RecField2> 
			  | <RecField1> ';'                      <RecFieldList>
			  | <RecField2> ';'                      <RecFieldList>
			  | <RecField2> ';' <CallConvention>
			  | <RecField2> ';' <CallConvention> ';' <RecFieldList>
			  | CASE <Selector> OF <RecVariantList>

<RecVariantList>	::= 
		 	  | <RecVariant> 
			  | <RecVariant> ';' <RecVariantList>

<RecField1>		::= <IdList> ':' <GenericType> <OptPortDirectives>

<RecField2>		::= <IdList> ':' <CallType> 

<RecVariant>		::= <ConstExprList> ':' '(' <RecFieldList> ')'





<Selector>		::= <RefId> ':' <TypeName> 
			  | <TypeName> 


<SetType>		::= <OptPacked> SET OF <OrdinalType>	

<FileType>		::= <OptPacked> FILE OF <TypeRef>	
			  | FILE

<PointerType>		::= '^' <TypeRef>			

<CallType>		::= PROCEDURE   <OptFormalParms>                            <OptCallConventions>
			  | PROCEDURE   <OptFormalParms>                  OF OBJECT <OptCallConventions>
			  | FUNCTION    <OptFormalParms> ':' <ResultType>           <OptCallConventions>
			  | FUNCTION    <OptFormalParms> ':' <ResultType> OF OBJECT <OptCallConventions>




 
!-----CLASSES AND OBJECTS------------------------------------------------------

<RestrictedType>	::= <ObjectType>	
			  | <ClassType>		
			  | <InterfaceType>	
			  
<ObjectType>		::= <OptPacked> OBJECT <OptObjectHeritage> <ObjectMemberList> END

<ClassType>		::= CLASS  <OptClassHeritage>  <ClassMemberList>  END
			  | CLASS  <OptClassHeritage>  

<ClassRefType>		::= CLASS OF <TypeName>

<InterfaceType>		::= INTERFACE     <OptClassHeritage> <OptClassGUID> <OptClassMethodList> END
			  | DISPINTERFACE <OptClassHeritage> <OptClassGUID> <OptClassMethodList> END
			  | INTERFACE
			  | DISPINTERFACE


<OptObjectHeritage>	::= '(' <TypeName> ')'
			  |


<OptClassHeritage>	::='(' <TypeList> ')'	
			  |
			  
<OptClassGUID>		::= '[' <ConstStrExpr> ']'	! <SCONST> globally unique identifier
			  |

<ObjectMemberList>	::=                                <OptFieldList> <OptObjectMethodList> 
			  | <ObjectMemberList> PUBLIC      <OptFieldList> <OptObjectMethodList>
			  | <ObjectMemberList> PRIVATE     <OptFieldList> <OptObjectMethodList>
			  | <ObjectMemberList> PROTECTED   <OptFieldList> <OptObjectMethodList>

<ClassMemberList>	::=                                <OptFieldList> <OptClassMethodList> 
			  | <ClassMemberList>  PUBLIC      <OptFieldList> <OptClassMethodList>
			  | <ClassMemberList>  PRIVATE     <OptFieldList> <OptClassMethodList>
			  | <ClassMemberList>  PROTECTED   <OptFieldList> <OptClassMethodList>
			  | <ClassMemberList>  PUBLISHED   <OptFieldList> <OptClassMethodList>


<OptFieldList>		::= <FieldList>
			  |

<OptObjectMethodList>	::= <ObjectMethodList>  
			  |

<OptClassMethodList>	::=  <ClassMethodList>                 
			  |

<FieldList>		::= <FieldSpec>
			  | <FieldList>  <FieldSpec>

<ObjectMethodList>	::= <ObjectMethodSpec> 
			  | <ObjectMethodList>  <ObjectMethodSpec> 

<ClassMethodList>	::= <ClassMethodSpec> 
			  | <ClassMethodList>   <ClassMethodSpec> 


<FieldSpec>		::= <IdList> ':' <Type> <OptPortDirectives> ';'
			  | SynError              ';'


<ObjectMethodSpec>	::= <MethodSpec>        <OptMethodDirectives> 
			  | <PropertySpec>    <OptPropertyDirectives> 
			  |  SynError	

<ClassMethodSpec>	::= <MethodSpec>	<OptMethodDirectives>
			  | <ResolutionSpec>	<OptMethodDirectives>
			  |  CLASS <ProcSpec> 	<OptMethodDirectives>
			  |  CLASS <FuncSpec>	<OptMethodDirectives>
			  | <PropertySpec>    <OptPropertyDirectives> 
			  |  SynError	
            
<MethodSpec>		::= <ConstructorSpec>	
			  | <DestructorSpec>	
			  | <ProcSpec> 		
			  | <FuncSpec>		


<ConstructorSpec>	::= CONSTRUCTOR <RefId> <OptFormalParms> ';'

<DestructorSpec>	::= DESTRUCTOR  <RefId> <OptFormalParms> ';'

<ProcSpec>		::= PROCEDURE   <RefId> <OptFormalParms> <OptCallConventions> ';'

<FuncSpec>		::= FUNCTION    <RefId> <OptFormalParms> ':' <ResultType> <OptCallConventions> ';'

<ResolutionSpec>	::= PROCEDURE   <RefId> '.' <RefId> '=' <RefId> ';'
			  | FUNCTION    <RefId> '.' <RefId> '=' <RefId> ';'

<PropertySpec>		::= PROPERTY <PropertyDecl> <OptPropSpecifiers> ';' 

<PropertyDecl>		::= <RefId>                     ':' <TypeRef>
			  | <RefId> '[' <IndexList> ']' ':' <TypeRef>
			  | <RefId> 

<IndexList>		::= <IndexDecl>
			  | <IndexList> ';' <IndexDecl>	
			  
<IndexDecl>		::= <IdDecl>
			  | CONST <IdDecl>

<IdDecl>		::= <IdList> ':' <Type>


<OptPropSpecifiers>	::= <PropertySpecifiers>
			  | 

<PropertySpecifiers>	::= <PropertySpecifier>
			  | <PropertySpecifiers>  <PropertySpecifier>


<PropertySpecifier>	::= INDEX      <ConstExpr>	!StorageSpecifier
			  | READ       <FieldDesignator>
			  | WRITE      <FieldDesignator>
			  | STORED     <FieldDesignator>
!			  | STORED     <ConstExpr>	
			  | DEFAULT    <ConstExpr> 
			  | NODEFAULT
			  | WRITEONLY 	
			  | READONLY 	
			  | DISPID <ConstExpr>        !Only within InterfaceTypes              
			  | <ImplementsSpecifier>

<ImplementsSpecifier>	::= IMPLEMENTS <TypeRef>	
			  | <ImplementsSpecifier> ',' <TypeRef>
		! The implements directive must be the last specifier in the property 
		! declaration and can list more than one interface, separated by commas

!-----VARS---------------------------------------------------------------------

<VarSection>		::= VAR <VarDeclList>
			  | THREADVAR <ThreadVarDeclList> 

<VarDeclList>		::= <VarDecl>
			  | <VarDeclList>  <VarDecl>	

<VarDecl>		::= <IdList> ':' <Type> <OptAbsoluteClause> <OptPortDirectives> ';'
			  | <IdList> ':' <Type> '=' <TypedConstant> <OptPortDirectives> ';'
			  | <IdList> ':' <TypeSpec> 
			  | SynError ';'

<ThreadVarDeclList>	::= <ThreadVarDecl> 
			  | <ThreadVarDeclList>  <ThreadVarDecl> 

<ThreadVarDecl>		::= <IdList> ':' <TypeSpec> 
			  | SynError ';'



<OptAbsoluteClause>	::= ABSOLUTE <RefId>
!			  | ABSOLUTE <ConstExpr>	!on windows only, not on linux
			  |




!------------------------------------------------------------------------------
! E X P R E S S I O N S
!------------------------------------------------------------------------------

<ConstExpr>		::= <Expr>

<ConstOrdExpr>		::= <AddExpr>

<ConstStrExpr>		::= <AddExpr>

<Expr>			::= <AddExpr>
			  | <AddExpr> <RelOp> <AddExpr>
			  | SynError

<AddExpr>		::= <MulExpr>
			  | <AddExpr> <AddOp> <MulExpr>

<MulExpr>		::= <Factor>
			  | <MulExpr> <MulOp> <Factor>


<Factor>		::= NIL
			  | <ICONST>
			  | <RCONST>
			  | <SCONST>
			  | <Designator>
			  | <SetConstructor>
			  | '@' <Designator>
			  | '@' '@' <Designator> !returns memory address of a procedural variable 
			  | '(' <Expr> ')'
			  | '(' <Expr> ')' '^'
			  | '+' <Factor>
			  | '-' <Factor>
			  | NOT <Factor>
			!---PortArray	  


<Designator>		::= <FieldDesignator>
			  | <Designator> '.' <FieldDesignator>
			  | <Designator> '^'
			  | <Designator> '[' <ExprList> ']'
			  | <Designator> '(' <ExprList> ')' !FunctionCall or TypeCast
			  | <Designator> '('  ')'           !FunctionCall 
			  | <Designator> AS <TypeRef>	!eg "with Source as TListItem do ..."
			  | '(' <Designator> ')'
			  | INHERITED <Designator>


<AsnOp>			::= ':=' 
			  | '+=' | '-=' | '*=' | '/=' 


<RelOp>			::= '=' | '>' | '<' | '<=' | '>=' | '<>'
	 	 	  | IN  | IS  |  AS  
			
<AddOp>			::= '+' |'-'
			  | OR  | XOR 
			
<MulOp>			::='*' | '/'
			  | DIV | MOD | AND | SHL | SHR
			
			
                        

<SetConstructor>	::= '[' <SetElementList> ']'
			  | '[' ']'

<SetElementList>	::= <SetElement>
			  | <SetElementList> ',' <SetElement>
			  

<SetElement>		::= <Expr>
			  | <Expr> '..' <Expr>

<ExprList>		::= <Expr> 
			  | <ExprList> ',' <Expr>
			  
<FmtExpr>		::= <Expr> 
			  | <Expr> ':' <Expr>
			  | <Expr> ':' <Expr> ':' <Expr>

<FmtExprList>		::= <FmtExpr> 
			  | <FmtExprList> ',' <FmtExpr>


<ConstExprList>		::= <ConstExpr> 
			  | <ConstExprList> ',' <ConstExpr>

!------------------------------------------------------------------------------
! S T A T E M E N T S
!------------------------------------------------------------------------------


<StmtList>		::= <Statement> 
			  | <StmtList> ';' <Statement> 

<Statement>		::= <Label> <Statement>
			  | <AssignmentStmt>
			  | <CallStmt>
			  | <GotoStatement>
			  | <CompoundStmt>
			  | <IfStatement>
			  | <CaseStatement>
			  | <ForStatement>
			  | <WhileStatement>
			  | <RepeatStatement>
			  | <WithStatement>
			  | <TryFinallyStmt>
			  | <TryExceptStmt>
			  | <RaiseStmt>
			  | <AssemblerStmt>
			  |  SynError
			  |
			  
<Label>			::= <LCONST>  ':' 
			  | <LabelId> ':' 
			  

<AssignmentStmt>	::= <Designator> <AsnOp> <Expr>
			  | '@' <RefId> ':=' <Factor> 	

			  
		!EXAMPLE of this '@' <RefId>, that calls the GetProcAddress 
		!function and points a var StrComp to the result.
		!  var StrComp: function(Str1, Str2: PChar): Integer;
		!   ...
		!  @StrComp := GetProcAddress(KernelHandle, 'lstrcmpi');

			  
			  
<CallStmt>		::= <Designator> 		!procedure, function, method, typecast
			  | WRITE   '(' <FmtExprList> ')'
			  | WRITELN '(' <FmtExprList> ')'
!			  | INHERITED <CallStmt>
			  | INHERITED


<GotoStatement>		::= GOTO <LCONST> 
			  | GOTO <RefId> 			  

<CompoundStmt>		::= BEGIN <StmtList> END


<IfStatement>		::= IF <Expr> THEN <Statement> ELSE <Statement>
	                  | IF <Expr> THEN <Statement>
	                  | IF SynError THEN <Statement>

		  
<CaseStatement>		::= CASE <Expr> OF <CaseList> <OtherWise> END

<ForStatement>		::= FOR <RefId> ':=' <Expr> <Dir> <Expr> DO <Statement>

<Dir>			::= TO | DOWNTO

<WhileStatement>	::= WHILE <Expr> DO <Statement>

<WithStatement>		::= WITH <DesignatorList> DO <Statement> 

<DesignatorList>	::= <Designator>
			  | <DesignatorList> ',' <Designator>

<RepeatStatement>	::= REPEAT <StmtList> UNTIL <Expr>


<AssemblerStmt>		::= ASM <AsmLanguage> END
                
	  

<OtherWise>		::= OTHERWISE <StmtList>
			  | ELSE      <StmtList>     
			  |

<CaseList>		::= <CaseSelector> 
			  | <CaseList> ';' <CaseSelector>
			  | <CaseList> ';' 


<CaseSelector>		::= <CaseLabels> ':' <Statement> 

<CaseLabels>		::= <CaseLabel>
			  | <CaseLabels> ',' <CaseLabel>
			  
<CaseLabel>		::= <ConstExpr>
			  | <ConstExpr> '..' <ConstExpr>
			  

<RaiseStmt>		::= RAISE SynError	![object] [AT address]
			  | RAISE <OptExceptInstance> 
			  | RAISE <OptExceptInstance> AT <Address>

<TryFinallyStmt>	::= TRY <StmtList> FINALLY <StmtList> END

<TryExceptStmt>		::= TRY <StmtList> EXCEPT  <ExceptionBlock> <OptExceptionElse> END

<ExceptionBlock>	::= <ExceptionStmt>
			  | <ExceptionBlock> ';' <ExceptionStmt>

<ExceptionStmt>		::= ON <Selector> DO <Statement>
!			  | ELSE <Statement> 
			  | <Statement> 

<OptExceptionElse>	::= ELSE <StmtList> 
			  |

<OptExceptInstance>	::= <Designator> !usually a method call (??)
			  |

<Address>		::= <Designator> !usually a functiion call, returning an adress






<OptSemi>		::= ';'
			  |

!------------------------------------------------------------------------------
! R O U T I N E S
!------------------------------------------------------------------------------

<ProcedureDeclSection>	::= <ProcedureDecl>
			  | <FunctionDecl>
			  | <MethodDecl>
                     
                     
<ProcedureDecl>		::= <ProcHeading>  <CallBody> <OptSemi>

<FunctionDecl>		::= <FuncHeading>  <CallBody> <OptSemi>
			    
<MethodDecl>		::= <MethHeading>  <CallBody> <OptSemi>
			    

<ProcHeading>		::= PROCEDURE <RefId> <OptFormalParms>                  <OptCallSpecifiers> ';'
			  | <ProcHeading> <CallDirectives> <OptSemi>


<FuncHeading>		::= FUNCTION  <RefId> <OptFormalParms> ':' <ResultType> <OptCallSpecifiers> ';'
			  | FUNCTION  <RefId> ';'
			  | <FuncHeading> <CallDirectives> <OptSemi>
			  !
			  ! if the heading is 'incomplete' it was declared before
			  ! and must be followed by a <CallBody> TO BE IMPROVED

<MethHeading>		::= PROCEDURE         <RefId> '.' <RefId> <OptFormalParms>                  <OptCallSpecifiers> ';'
			  | FUNCTION          <RefId> '.' <RefId> <OptFormalParms> ':' <ResultType> <OptCallSpecifiers> ';'
			  | FUNCTION          <RefId> '.' <RefId>  ';'
			  | CONSTRUCTOR       <RefId> '.' <RefId> <OptFormalParms>		    <OptCallSpecifiers> ';'
			  | DESTRUCTOR        <RefId> '.' <RefId> <OptFormalParms>                  <OptCallSpecifiers> ';'
			  | CLASS PROCEDURE   <RefId> '.' <RefId> <OptFormalParms>                  <OptCallSpecifiers> ';'
			  | CLASS FUNCTION    <RefId> '.' <RefId> <OptFormalParms> ':' <ResultType> <OptCallSpecifiers> ';'
			  | <MethHeading> <CallDirectives> ';'
			  !
			  ! the class methods operates on classes instead of objects

<ResultType>		::= <TypeRef>


<OptFormalParms>	::= '(' <FormalParmList> ')'
			  | '(' ')'
			  |
			  

<FormalParmList>	::= <FormalParm>
			  | <FormalParmList> ';' <FormalParm>

<FormalParm>		::= <Parameter>
			  | CONST <Parameter>
			  | VAR   <Parameter>
			  | OUT   <Parameter>

<Parameter>		::= <IdList>
			  | <IdList> ':' <ParmType>
			  | <IdList> ':' <TypeRef> '=' <ConstExpr>

<ParmType>		::= <TypeRef>
			  | ARRAY OF <TypeRef>
			  | ARRAY OF CONST
			  | FILE
			  
<CallBody>		::= <OptDeclSection> <CompoundStmt>
			  | <OptDeclSection> <AssemblerStmt>
			  | <ExternalDeclaration>
			  | FORWARD

!-----DIRECTIVES---------------------------------------------------------------
! <PortDirectives> are to produce warnings at compile time when source code is compiled 
! in the {$HINTS ON} {$WARNINGS ON} state. It can be applied to declarations
!
! <PortDirectives are accepted:
!	WITHIN const and var declarations (not after), 
!	WITHIN unit headers (not after)
!	AFTER function/procedure headings (not within) (ONE terminating ';' is optional)
! <PortDirectives are NOT accepted:
! 	in/after type declarations
!------------------------------------------------------------------------------


<OptPortDirectives>	::= <PortDirectives>
			  |
			  
<PortDirectives>	::= <PortDirective>
			  | <PortDirectives> <PortDirective>

<PortDirective>		::= PLATFORM    ! to warn that it is specific to a particular operating environment (such as Windows or Linux)
			  | PLATFORM '=' <ConstExpr>
			  | DEPRECATED  ! to warn it is obsolete or supported only for backward compatibility
			  | LIBRARY  	! to warn dependencies on a particular library or component framework (such as CLX).



!------------------------
			  
<OptMethodDirectives>	::=  <MethodDirectives> 
			   | <OptMethodDirectives> <PortDirective> ';'
			   |

<MethodDirectives>	::= <MethodDirective> ';'
			  | <MethodDirectives>     <MethodDirective> ';'

<MethodDirective>	::= VIRTUAL 
			  | VIRTUAL <ConstExpr> 
			  | DYNAMIC 		!for classes only
			  | OVERRIDE 
			  | ABSTRACT 
			  | MESSAGE <ConstExpr> 
			  | OVERLOAD 
			  | REINTRODUCE 
			  | DISPID <ConstExpr> !only within an <InterfaceType>
			  | <CallConvention> 
		!TODO NOT ALL THESE METHOD DIRECTIVES CAN BE COMBINED WITH EACH OTHER

!------------------------

<OptPropertyDirectives>	::=  <PropertyDirective> ';'
			   | <OptPropertyDirectives>  <PortDirective> ';'
			   | 

<PropertyDirective>	::= DEFAULT 



!------------------------
			  
<ExternalDeclaration>	::= EXTERNAL
			  | EXTERNAL <ConstStrExpr>
			  | EXTERNAL <ConstStrExpr> NAME <ConstStrExpr>
!			  | EXTERNAL <SCONST>
!			  | EXTERNAL <SCONST> NAME <SCONST>			  


!------------------------

<CallDirectives>	::= <CallDirective>
			  | <CallDirectives> <CallDirective>

<CallDirective>		::= <CallConvention>
			  | <CallObsolete>
			  | <PortDirective>
			  | VARARGS	!works only with external routines and cdecl calling convention.
			  | LOCAL	!prevents exporting in a library
			  | <SCONST>	!for PasPro only
			  | OVERLOAD 

<OptCallSpecifiers>	::= <CallSpecifier>
			  | <OptCallSpecifiers> <CallSpecifier>
			  |
			  
<CallSpecifier>		::= <CallConvention>
			  | <CallObsolete>
			  
<CallConventions>       ::= <CallConvention>
			  | <CallConventions> <CallConvention>

<OptCallConventions>    ::= <CallConvention>
			  | <OptCallConventions> <CallConvention>
			  |
			  
			  
						![ParmOrder]	[CleanUp]	[RegParms]	
<CallConvention>	::= REGISTER		!Left-to-right	Routine		Yes
			  | PASCAL		!Left-to-right	Routine		No
			  | CDECL		!Right-to-left	Caller		No
			  | STDCALL		!Right-to-left	Routine		No
			  | SAFECALL		!Right-to-left	Routine		No

<CallObsolete>		::= INLINE	!for backward compatibility only; has no effect on the compiler.
			  | ASSEMBLER	!for backward compatibility only; has no effect on the compiler.
			  | NEAR	!for 16-bits programming only, has no effect in 32 bit applications
			  | FAR		!for 16-bits programming only, has no effect in 32 bit applications
			  | EXPORT	!for 16-bits programming only, has no effect in 32 bit applications


!------------------------------------------------------------------------------
! A S S E M B L E R   I N S T R U C T I O N S
!------------------------------------------------------------------------------
! The asm 'grammar' below is rather tolerant in accepting assembler code and needs
! further elaboration. The main problem is that end of lines are not detected, so 
! the separators between the instructions cannot be found, so an <AsmItem> cannot 
! be grouped in a meaningfull way with another <AsmItem> into a true <AsmInstruction>
! A fundamental solution could be to start a new lexical "context" in this grammar, with 
! that forces the lexical scanner to recognize an assembler specific list of keywords 
! Unfortunately, this is not supported by the Gold parser

<AsmLanguage>		::= <AsmInstruction>
			  | <AsmLanguage> <AsmInstruction>

<AsmInstruction>	::= <AsmItem>
			  | <AsmInstruction> <AsmItem>
			  | <AsmInstruction> ',' <AsmItem>
			  | <AsmInstruction> ';' 

<AsmItem>		::= <AsmLabel>
			  | <AsmExpr>

<AsmLabel>		::= <AsmLocal> ':'
			  | <AsmId>    ':'

<AsmExpr>		::= <AsmFactor>
			  | '-' <AsmFactor>
			  | <AsmExpr> '+' <AsmFactor>
			  | <AsmExpr> '*' <AsmFactor>
			  | <AsmExpr> '-' <AsmFactor>
			  | <AsmExpr> '.' <AsmFactor>
			  | '[' <AsmExpr> ']'
			  | '(' <AsmExpr> ')'
			  ! <AsmId> '(' <AsmExpr> ')'
			  | SynError

<AsmFactor>		::= <AsmId>
			  | <AsmLocal>
			  | <ICONST>
			  | <RCONST>
			  | <SCONST>

<AsmId>			::= <RefId>
			  | '&' <RefId>	
			  | REPEAT | WHILE | IF
			  | AND | OR | XOR | SHR | SHL | DIV | NOT
			  ! plus many other keywords as well that may serve as an identifier

<AsmLocal>		::= '@' <LCONST>
			  | '@' <AsmId>
			  | '@' <AsmLocal>	
			  | '@' END

Java

The BNF description follows, BNF index of Java Language Grammar

JavaScript

The BNF description follows, JavaScript Syntax

Lisp

Outside of particularly restricted variants, no static grammar can exactly describe Lisp due to macros and reader-macros.

! -----------------------------------------------------------------------
! LISP
!
! LISt Programming
!
!    "One can even conjecture that Lisp owes its survival specifically to the 
!     fact that its programs are lists, which everyone, including me, has 
!     regarded as a disadvantage."
!
!     - John McCarthy, "Early History of Lisp"
!
!
!    "Lisp is worth learning for the profound enlightenment experience you will 
!     have when you finally get it; that experience will make you a better programmer
!     for the rest of your days, even if you never actually use Lisp itself a lot."
!  
!     - Eric Raymond, "How to Become a Hacker"
!
!
!    "Lisp was far more powerful and flexible than any other language of its day; in 
!     fact, it is still a better design than most languages of today, twenty-five 
!     years later. Lisp freed ITS's hackers to think in unusual and creative ways. It 
!     was a major factor in their successes, and remains one of hackerdom's favorite 
!     languages."
!
!     - Eric Raymond, in Open Sources on MIT's first OS, ITS 
!
! The LISP programming language is one of the oldest still use today; second only to 
! FORTRAN. It was invented by mathematician John McCarthy and organizes information into
! abstract "lists". This metaphor is used universially for both data and functions; 
! in fact, the LISP runtime engine makes no differentiation between the two. This allows 
! the programmer to perform actions that would be impossible in most programming languages 
! such as, but not limited to, passing code as a parameter to a function, executing data, 
! and modifying the program at runtime.
!
! For more information on LISP, please visit www.lisp.org.
!
! Updates:
!    3/5/2003: Added dotted pairs and backslash overrides to the language.
!
! Note: This is an ad hoc version of the language. If there are any flaws, 
! please visit www.DevinCook.com/GOLDParser and I will update the grammar. 
!
!
! -----------------------------------------------------------------------


"Name"    = 'LISP'
"Author"  = 'John McCarthy'
"Version" = 'Standard'
"About"   = 'LISP is an abstract language that organizes ALL data around "lists".'

"Start Symbol" = <s-Expression>

{Atom Char}   = {Printable} - {Whitespace} - [()"\'']
{String Char} = {Printable} - ["\]

Atom   = ( {Atom Char} | '\'{Printable} )+

String = '"' ( {String Char} | '\'{Printable} )* '"'


<s-Expression> ::= <Quote> Atom
                 | <Quote> '(' <Series> ')'
                 | <Quote> '(' <s-Expression> '.' <s-Expression> ')'   !Dotted Pair
                 | String                                              !Strings are never evaluated

<Series> ::= <s-Expression> <Series>
           |

<Quote>  ::= ''           !Quote = do not evaluate
           |

Pascal

The ISO 7185 standard for Pascal uses Extended Backus–Naur Form. Also Van Wijngaarden's grammar can be used to define Pascal's grammar[1].

Perl

The BNF description follows, Perl Syntax

Python

The best EBNF syntax so far is at, Python EBNF Syntax

SQL

Syntax for SQL follows, BNF Sytax for SQL Database Language

Smalltalk

! -----------------------------------------------------------------------
! SmallTalk IV
!
! The first object-oriented programming language.
!
!     "Smalltalk was developed in the Learning Research Group at Xerox's Palo
!      Alto Research Center in the early 70s. The major ideas in Smalltalk 
!      are generally credited to Alan Kay with many roots in Simula, LISP 
!      and SketchPad. Dan Engalls wrote the first overlapping windows, opaque
!      pop-up menus and BitBlt. Guess where Apple's OS and Microsoft Windows
!      "found" their roots? Right, Smalltalk! Adele Goldberg and Dave Robson
!      wrote the reference manuals for Smalltalk and were key development team
!      members." 
!
!      - Randy Best, STIC Director
!
!
!     "Why Smalltalk? Smalltalk uses a simplified version of English. Nouns 
!      and verbs. Object are the nouns. Verbs are messages sent from one 
!      object to the next. Easy as 1, 2, 3. It is no longer necessary to  
!      write cryptic programs. This means that almost anyone can learn to
!      write Smalltalk programs." 
!       
!      - Peter William Lount 
!
!
!     "I invented the term Object-Oriented, and I can tell you I did not have
!      C++ in mind." 
!
!      - Alan Kay (Inventor of Smalltalk)
!
! The Smalltalk programming language was the first language to incorporate the
! concept of object-oriented programming. Developed in the Xerox labs at Palo
! Alto, Smalltalk was one of a series of ground-breaking ideas that defined
! modern computer science. 
!
! In the language's metaphor, everything is an object and every interaction 
! between objects are known as messages. Due to a strict adherence to this 
! concept, Smalltalk is recognized as a pure object-oriented language.
! 
! For more information, please visit:  http://www.smalltalk.org
! 
! The SmallTalk grammar is amazingly simple with only three levels of 
! operator precedence. In addition, the grammar contains no reserved words,
! and only a minimum of symbols. As a result, Smalltalk programs are mainly 
! (if not entirely) defined by programmar-defined objects and method names.
!
! This is version IV of the grammar, which allows methods to be defined, but
! not yet the objects themselves.
!
! It should also be noted that comments in SmallTalk are defined as a series 
! of characters delimited by Double-Quotes ("). The 'Comment Start' and 
! 'Comment End' terminals in the normal GOLD Parser Builder Grammar cannot
! be used since the start and end terminals are identical. However, since
! they are identical, Smalltalk comments cannot be nested and the normal
! 'Whitespace' terminal can be used.
!
! Note: This is an ad hoc version of the grammar. If there are any flaws, 
! please e-mail GOLDParser@DevinCook.com and I will update the grammar. 
! -----------------------------------------------------------------------


"Name"    = 'Smalltalk IV'
"Author"  = 'Alan Kay'
"Version" = 'IV'
"About"   = 'Smalltalk is considered one of the "purest" object-oriented'
          | 'languages ever created.'


"Case Sensitive" = True

"Start Symbol" = <Program>


{Id Tail}       = {Alphanumeric} + [_]
{Integer Tail}  = [ABCDEFGHIJKLMNOPQRSTUVWXYZ] + {Digit}
{String Chars}  = {Printable} - ['']
{Selector Char} = [!%&*+/<=>?@\~,]
{Comment Char}  = {Printable} + {Whitespace} - ["]

! The whitespace character has been modified to accept all double-quoted strings
Whitespace = {Whitespace}+ | '"'{Comment Char}*'"'

! The Keyword token is used in SmallTalk to represent a binary message. Essentially,
! this is an object defined operator
KeyWord          = {Letter}{Id Tail}*':'

Identifier       = {Letter}{Id Tail}*
BinarySelector  = {Selector Char}+                              
IntegerLiteral  = {Digit}+ | {Digit}+ 'r' {Integer Tail}+
FloatLiteral    = {Digit}+ '.'{Digit}+ ( [edq] '-'? {Digit}+ )?                               
ScaledLiteral   = {Digit}+ ( '.' {Digit}+ )? 's' ( {Digit}+ )?     
QuotedString    =  '' ( {String Chars} | '' '' )*  ''  


! ---------------------------------------------------- Grammar rules
<Program> ::= <Temporaries>  <Sentences>
   

<Temporaries> ::= '|' '|'
                | '|' <Identifier List> '|'
                |
      

<Identifier List> ::= <Identifier List> Identifier
                    | Identifier
    
    
<Sentences> ::= <Sentence List>
              |

<Sentence List> ::= <Sentence List> <Expresion> '.'
                  | <Expresion> '.'
    
! ---------------------------------------------------- Expressions
<Expresion> ::= Identifier ':=' <Message Exp>
              | Identifier ':=' <Primary>
              | <Message Exp>
              | <Primary>
   
<Primary> ::= Identifier
            | <Literal>
            | <Block>
            | '(' <Message Exp> ')'
            | '(' <Primary> ')'

<Message Exp> ::= <Unary Exp>
                | <Binary Exp>
                | <KeyWord Exp>
   
<Unary Exp>  ::= <Primary> <Unary Exp List> 
    

<Unary Exp List> ::= <Unary Exp List> <Unary Message>
                   | <Unary Message>
    
<Binary Exp> ::= <Unary Exp>  <Binary Exp List>
               | <Primary> <Binary Exp List>

<Binary Exp List> ::= <Binary Exp List> <Binary Message>
                    | <Binary Message>
    
<KeyWord Exp> ::= <Binary Exp> <KeyWord Message>
                | <Primary> <KeyWord Message>
                | <Unary Exp> <KeyWord Message>
    
! ---------------------------------------------------- Messages
<Unary Message> ::= <Unary Selector>
    
<Binary Message> ::= <Binary Selector> <Unary Exp>
                   | <Binary Selector> <Primary>
    
<KeyWord Message> ::= KeyWord <Binary Exp>  <KeyWord Message>
                    | KeyWord <Primary> <KeyWord Message>
                    | KeyWord <Primary>
                    | KeyWord <Binary Exp>
                    | KeyWord <Unary Exp> <KeyWord Message>
                    | KeyWord <Unary Exp>
    
<Block> ::= '[' ':' Identifier '|' <Sentences> ']'
          | '[' <Sentences> ']'


<Binary Selector> ::= BinarySelector
   

<Unary Selector> ::= Identifier

! ---------------------------------------------------- Literals
<Literal> ::= <Literal Item>
            | '#' '(' ')'
            | '#' '(' <Literal List> ')'

<Literal List> ::= <Literal List> <Literal Item>


<Literal Item> ::= IntegerLiteral
                 | QuotedString
                 | FloatLiteral
                 | ScaledLiteral 

VBScript

!===============================
! VB Script grammar.
!
! To create the grammar I was using Microsoft's VB Script documentation
! available from http://msdn.microsoft.com/scripting,
! VB Script parser from ArrowHead project http://www.tripi.com/arrowhead/,
! and Visual Basic .Net grammar file written by Devin Cook.
!
! This grammar cannot cover all aspects of VBScript and may have some errors.
! Feel free to contact me if you find any flaws in the grammar.
!
! Vladimir Morozov   vmoroz@hotmail.com
!
! Special thanks to Nathan Baulch for the grammar updates. 
!
! USE GOLD PARSER BUILDER VERSION 2.1 AND LATER TO COMPILE THIS GRAMMAR.
!===============================

"Name"            = 'VB Script'
"Author"          = 'John G. Kemeny and Thomas E. Kurtz'
"Version"         = '5.0'
"About"           = 'VB Script grammar.'
"Case Sensitive"  = False
"Start Symbol"    = <Program>

!===============================
! Character sets
!===============================

{String Char}   = {All Valid} - ["]
{Date Char}     = {Printable} - [#]
{ID Name Char}  = {Printable} - ['['']']
{Hex Digit}     = {Digit} + [abcdef]
{Oct Digit}     = [01234567]
{WS}            = {Whitespace} - {CR} - {LF}
{ID Tail}       = {Alphanumeric} + [_]

!===============================
! Terminals
!===============================

NewLine        = {CR} {LF}
               | {CR}
               | {LF}
               | ':'

! Special white space definition. Whitespace is either space or tab, which
! can be followed by continuation symbol '_' followed by new line character
Whitespace     = {WS}+
               | '_' {WS}* {CR}? {LF}?

! Special comment definition
Comment Line   = ''
               | 'Rem'

! Literals
StringLiteral  = '"' ( {String Char} | '""' )* '"'
IntLiteral     = {Digit}+
HexLiteral     = '&H' {Hex Digit}+ '&'?
OctLiteral     = '&' {Oct Digit}+ '&'?
FloatLiteral   = {Digit}* '.' {Digit}+ ( 'E' [+-]? {Digit}+ )?
               | {Digit}+ 'E' [+-]? {Digit}+
DateLiteral    = '#' {Date Char}+ '#'

! Identifier is either starts with letter and followed by letter,
! number or underscore, or it can be escaped sequence of any printable
! characters ([] and [_$% :-) @] are valid identifiers)
ID             = {Letter} {ID Tail}*
               | '[' {ID Name Char}* ']'

! White space is not allowed to be before dot, but allowed to be after it.
IDDot          = {Letter} {ID Tail}* '.'
               | '[' {ID Name Char}* ']' '.'
               | 'And.'
               | 'ByRef.'
               | 'ByVal.'
               | 'Call.'
               | 'Case.'
               | 'Class.'
               | 'Const.'
               | 'Default.'
               | 'Dim.'
               | 'Do.'
               | 'Each.'
               | 'Else.'
               | 'ElseIf.'
               | 'Empty.'
               | 'End.'
               | 'Eqv.'
               | 'Erase.'
               | 'Error.'
               | 'Exit.'
               | 'Explicit.'
               | 'False.'
               | 'For.'
               | 'Function.'
               | 'Get.'
               | 'GoTo.'
               | 'If.'
               | 'Imp.'
               | 'In.'
               | 'Is.'
               | 'Let.'
               | 'Loop.'
               | 'Mod.'
               | 'New.'
               | 'Next.'
               | 'Not.'
               | 'Nothing.'
               | 'Null.'
               | 'On.'
               | 'Option.'
               | 'Or.'
               | 'Preserve.'
               | 'Private.'
               | 'Property.'
               | 'Public.'
               | 'Redim.'
               | 'Rem.'
               | 'Resume.'
               | 'Select.'
               | 'Set.'
               | 'Step.'
               | 'Sub.'
               | 'Then.'
               | 'To.'
               | 'True.'
               | 'Until.'
               | 'WEnd.'
               | 'While.'
               | 'With.'
               | 'Xor.'

! The following identifiers should only be used in With statement.
! This rule must be checked by contextual analyzer.
DotID          = '.' {Letter} {ID Tail}*
               | '.' '[' {ID Name Char}* ']'
               | '.And'
               | '.ByRef'
               | '.ByVal'
               | '.Call'
               | '.Case'
               | '.Class'
               | '.Const'
               | '.Default'
               | '.Dim'
               | '.Do'
               | '.Each'
               | '.Else'
               | '.ElseIf'
               | '.Empty'
               | '.End'
               | '.Eqv'
               | '.Erase'
               | '.Error'
               | '.Exit'
               | '.Explicit'
               | '.False'
               | '.For'
               | '.Function'
               | '.Get'
               | '.GoTo'
               | '.If'
               | '.Imp'
               | '.In'
               | '.Is'
               | '.Let'
               | '.Loop'
               | '.Mod'
               | '.New'
               | '.Next'
               | '.Not'
               | '.Nothing'
               | '.Null'
               | '.On'
               | '.Option'
               | '.Or'
               | '.Preserve'
               | '.Private'
               | '.Property'
               | '.Public'
               | '.Redim'
               | '.Rem' 
               | '.Resume'
               | '.Select'
               | '.Set'
               | '.Step'
               | '.Sub'
               | '.Then'
               | '.To'
               | '.True'
               | '.Until'
               | '.WEnd'
               | '.While'
               | '.With'
               | '.Xor'

DotIDDot       = '.' {Letter}{ID Tail}* '.'
               | '.' '[' {ID Name Char}* ']' '.'
               | '.And.'
               | '.ByRef.'
               | '.ByVal.'
               | '.Call.'
               | '.Case.'
               | '.Class.'
               | '.Const.'
               | '.Default.'
               | '.Dim.'
               | '.Do.'
               | '.Each.'
               | '.Else.'
               | '.ElseIf.'
               | '.Empty.'
               | '.End.'
               | '.Eqv.'
               | '.Erase.'
               | '.Error.'
               | '.Exit.'
               | '.Explicit.'
               | '.False.'
               | '.For.'
               | '.Function.'
               | '.Get.'
               | '.GoTo.'
               | '.If.'
               | '.Imp.'
               | '.In.'
               | '.Is.'
               | '.Let.'
               | '.Loop.'
               | '.Mod.'
               | '.New.'
               | '.Next.'
               | '.Not.'
               | '.Nothing.'
               | '.Null.'
               | '.On.'
               | '.Option.'
               | '.Or.'
               | '.Preserve.'
               | '.Private.'
               | '.Property.'
               | '.Public.'
               | '.Redim.'
               | '.Rem.'
               | '.Resume.'
               | '.Select.'
               | '.Set.'
               | '.Step.'
               | '.Sub.'
               | '.Then.'
               | '.To.'
               | '.True.'
               | '.Until.'
               | '.WEnd.'
               | '.While.'
               | '.With.'
               | '.Xor.'

!===============================
! Rules
!===============================

<NL>                   ::= NewLine <NL>
                         | NewLine

<Program>              ::= <NLOpt> <GlobalStmtList>

!===============================
! Rules : Declarations
!===============================

<ClassDecl>            ::= 'Class' <ExtendedID> <NL> <MemberDeclList> 'End' 'Class' <NL>

<MemberDeclList>       ::= <MemberDecl> <MemberDeclList>
                         |

<MemberDecl>           ::= <FieldDecl>
                         | <VarDecl>
                         | <ConstDecl>
                         | <SubDecl>
                         | <FunctionDecl>
                         | <PropertyDecl>

<FieldDecl>            ::= 'Private' <FieldName> <OtherVarsOpt> <NL>
                         | 'Public' <FieldName> <OtherVarsOpt> <NL>

<FieldName>            ::= <FieldID> '(' <ArrayRankList> ')'
                         | <FieldID>

<FieldID>              ::= ID
                         | 'Default'
                         | 'Erase'
                         | 'Error'
                         | 'Explicit'
                         | 'Step'

<VarDecl>              ::= 'Dim' <VarName> <OtherVarsOpt> <NL>

<VarName>              ::= <ExtendedID> '(' <ArrayRankList> ')'
                         | <ExtendedID>

<OtherVarsOpt>         ::= ',' <VarName> <OtherVarsOpt>
                         |

<ArrayRankList>        ::= <IntLiteral> ',' <ArrayRankList>
                         | <IntLiteral>
                         |

<ConstDecl>            ::= <AccessModifierOpt> 'Const' <ConstList> <NL>

<ConstList>            ::= <ExtendedID> '=' <ConstExprDef> ',' <ConstList>
                         | <ExtendedID> '=' <ConstExprDef>

<ConstExprDef>         ::= '(' <ConstExprDef> ')'
                         | '-' <ConstExprDef>
                         | '+' <ConstExprDef> 
                         | <ConstExpr> 

<SubDecl>              ::= <MethodAccessOpt> 'Sub' <ExtendedID> <MethodArgList> <NL> <MethodStmtList> 'End' 'Sub' <NL>
                         | <MethodAccessOpt> 'Sub' <ExtendedID> <MethodArgList> <InlineStmt> 'End' 'Sub' <NL>

<FunctionDecl>         ::= <MethodAccessOpt> 'Function' <ExtendedID> <MethodArgList> <NL> <MethodStmtList> 'End' 'Function' <NL>
                         | <MethodAccessOpt> 'Function' <ExtendedID> <MethodArgList> <InlineStmt> 'End' 'Function' <NL>

<MethodAccessOpt>      ::= 'Public' 'Default'
                         | <AccessModifierOpt>

<AccessModifierOpt>    ::= 'Public'
                         | 'Private'
                         |

<MethodArgList>        ::= '(' <ArgList> ')'
                         | '(' ')'
                         |

<ArgList>              ::= <Arg> ',' <ArgList>
                         | <Arg>

<Arg>                  ::= <ArgModifierOpt> <ExtendedID> '(' ')'
                         | <ArgModifierOpt> <ExtendedID>

<ArgModifierOpt>       ::= 'ByVal'
                         | 'ByRef'
                         |

<PropertyDecl>         ::= <MethodAccessOpt> 'Property' <PropertyAccessType> <ExtendedID> <MethodArgList> <NL> <MethodStmtList> 'End' 'Property' <NL>                        

<PropertyAccessType>   ::= 'Get'
                         | 'Let'
                         | 'Set'

!===============================
! Rules : Statements
!===============================

<GlobalStmt>           ::= <OptionExplicit>
                         | <ClassDecl>
                         | <FieldDecl>
                         | <ConstDecl>
                         | <SubDecl>
                         | <FunctionDecl>
                         | <BlockStmt>

<MethodStmt>           ::= <ConstDecl>
                         | <BlockStmt>

<BlockStmt>            ::= <VarDecl>
                         | <RedimStmt>
                         | <IfStmt>
                         | <WithStmt>
                         | <SelectStmt>
                         | <LoopStmt>
                         | <ForStmt>
                         | <InlineStmt> <NL>

<InlineStmt>           ::= <AssignStmt>
                         | <CallStmt>
                         | <SubCallStmt>
                         | <ErrorStmt>
                         | <ExitStmt>
                         | 'Erase' <ExtendedID>

<GlobalStmtList>       ::= <GlobalStmt> <GlobalStmtList>
                         | 

<MethodStmtList>       ::= <MethodStmt> <MethodStmtList>
                         |
                        
<BlockStmtList>        ::= <BlockStmt> <BlockStmtList>
                         |
                        
<OptionExplicit>       ::= 'Option' 'Explicit' <NL>

<ErrorStmt>            ::= 'On' 'Error' 'Resume' 'Next'
                         | 'On' 'Error' 'GoTo' IntLiteral  ! must be 0

<ExitStmt>             ::= 'Exit' 'Do'
                         | 'Exit' 'For'
                         | 'Exit' 'Function'
                         | 'Exit' 'Property'
                         | 'Exit' 'Sub'

<AssignStmt>           ::= <LeftExpr> '=' <Expr>
                         | 'Set' <LeftExpr> '=' <Expr>
                         | 'Set' <LeftExpr> '=' 'New' <LeftExpr>

! Hack: VB Script allows to have construct a = b = c, which means a = (b = c)
! In this grammar we do not allow it in order to prevent complications with
! interpretation of a(1) = 2, which may be considered as array element assignment
! or a subroutine call: a ((1) = 2).
! Note: VBScript allows to have missed parameters: a ,,2,3,
! VM: If somebody knows a better way to do it, please let me know
<SubCallStmt>          ::= <QualifiedID> <SubSafeExprOpt> <CommaExprList>
                         | <QualifiedID> <SubSafeExprOpt>
                         | <QualifiedID> '(' <Expr> ')' <CommaExprList>
                         | <QualifiedID> '(' <Expr> ')'
                         | <QualifiedID> '(' ')'
                         | <QualifiedID> <IndexOrParamsList> '.' <LeftExprTail> <SubSafeExprOpt> <CommaExprList>
                         | <QualifiedID> <IndexOrParamsListDot> <LeftExprTail> <SubSafeExprOpt> <CommaExprList>
                         | <QualifiedID> <IndexOrParamsList> '.' <LeftExprTail> <SubSafeExprOpt>
                         | <QualifiedID> <IndexOrParamsListDot> <LeftExprTail> <SubSafeExprOpt>

! This very simplified case - the problem is that we cannot use parenthesis in aaa(bbb).ccc (ddd)
<SubSafeExprOpt>       ::= <SubSafeExpr>
                         |

<CallStmt>             ::= 'Call' <LeftExpr>

<LeftExpr>             ::= <QualifiedID> <IndexOrParamsList> '.' <LeftExprTail>
                         | <QualifiedID> <IndexOrParamsListDot> <LeftExprTail>
                         | <QualifiedID> <IndexOrParamsList>
                         | <QualifiedID>
                         | <SafeKeywordID>

<LeftExprTail>         ::= <QualifiedIDTail> <IndexOrParamsList> '.' <LeftExprTail>
                         | <QualifiedIDTail> <IndexOrParamsListDot> <LeftExprTail>
                         | <QualifiedIDTail> <IndexOrParamsList>
                         | <QualifiedIDTail>

! VB Script does not allow to have space between Identifier and dot:
! a . b - Error ; a. b or a.b - OK
<QualifiedID>          ::= IDDot <QualifiedIDTail>
                         | DotIDDot <QualifiedIDTail>
                         | ID
                         | DotID

<QualifiedIDTail>      ::= IDDot <QualifiedIDTail>
                         | ID
                         | <KeywordID>

<KeywordID>            ::= <SafeKeywordID>
                         | 'And'
                         | 'ByRef'
                         | 'ByVal'
                         | 'Call'
                         | 'Case'
                         | 'Class'
                         | 'Const'
                         | 'Dim'
                         | 'Do'
                         | 'Each'
                         | 'Else'
                         | 'ElseIf'
                         | 'Empty'
                         | 'End'
                         | 'Eqv'
                         | 'Exit'
                         | 'False'
                         | 'For'
                         | 'Function'
                         | 'Get'
                         | 'GoTo'
                         | 'If'
                         | 'Imp'
                         | 'In'
                         | 'Is'
                         | 'Let'
                         | 'Loop'
                         | 'Mod'
                         | 'New'
                         | 'Next'
                         | 'Not'
                         | 'Nothing'
                         | 'Null'
                         | 'On'
                         | 'Option'
                         | 'Or'
                         | 'Preserve'
                         | 'Private'
                         | 'Public'
                         | 'Redim'
                         | 'Resume'
                         | 'Select'
                         | 'Set'
                         | 'Sub'
                         | 'Then'
                         | 'To'
                         | 'True'
                         | 'Until'
                         | 'WEnd'
                         | 'While'
                         | 'With'
                         | 'Xor'

<SafeKeywordID>        ::= 'Default'
                         | 'Erase'
                         | 'Error'
                         | 'Explicit'
                         | 'Property'
                         | 'Step'

<ExtendedID>           ::= <SafeKeywordID>
                         | ID

<IndexOrParamsList>    ::= <IndexOrParams> <IndexOrParamsList>
                         | <IndexOrParams>

<IndexOrParams>        ::= '(' <Expr> <CommaExprList> ')'
                         | '(' <CommaExprList> ')'
                         | '(' <Expr> ')'
                         | '(' ')'

<IndexOrParamsListDot> ::= <IndexOrParams> <IndexOrParamsListDot>
                         | <IndexOrParamsDot>

<IndexOrParamsDot>     ::= '(' <Expr> <CommaExprList> ').'
                         | '(' <CommaExprList> ').'
                         | '(' <Expr> ').'
                         | '(' ').'

<CommaExprList>        ::= ',' <Expr> <CommaExprList>
                         | ',' <CommaExprList>
                         | ',' <Expr>
                         | ','

!========= Redim Statement

<RedimStmt>            ::= 'Redim' <RedimDeclList> <NL>
                         | 'Redim' 'Preserve' <RedimDeclList> <NL>

<RedimDeclList>        ::= <RedimDecl> ',' <RedimDeclList>
                         | <RedimDecl>

<RedimDecl>            ::= <ExtendedID> '(' <ExprList> ')'

!========= If Statement

<IfStmt>               ::= 'If' <Expr> 'Then' <NL> <BlockStmtList> <ElseStmtList> 'End' 'If' <NL>
                         | 'If' <Expr> 'Then' <InlineStmt> <ElseOpt> <EndIfOpt> <NL>

<ElseStmtList>         ::= 'ElseIf' <Expr> 'Then' <NL> <BlockStmtList> <ElseStmtList>
                         | 'ElseIf' <Expr> 'Then' <InlineStmt> <NL> <ElseStmtList>
                         | 'Else' <InlineStmt> <NL>
                         | 'Else' <NL> <BlockStmtList>
                         |

<ElseOpt>              ::= 'Else' <InlineStmt>
                         |

<EndIfOpt>             ::= 'End' 'If'
                         |

!========= With Statement

<WithStmt>             ::= 'With' <Expr> <NL> <BlockStmtList> 'End' 'With' <NL>

!========= Loop Statement

<LoopStmt>             ::= 'Do' <LoopType> <Expr> <NL> <BlockStmtList> 'Loop' <NL>
                         | 'Do' <NL> <BlockStmtList> 'Loop' <LoopType> <Expr> <NL>
                         | 'Do' <NL> <BlockStmtList> 'Loop' <NL>
                         | 'While' <Expr> <NL> <BlockStmtList> 'WEnd' <NL>

<LoopType>             ::= 'While'
                         | 'Until'

!========= For Statement

<ForStmt>              ::= 'For' <ExtendedID> '=' <Expr> 'To' <Expr> <StepOpt> <NL> <BlockStmtList> 'Next' <NL>
                         | 'For' 'Each' <ExtendedID> 'In' <Expr> <NL> <BlockStmtList> 'Next' <NL>

<StepOpt>              ::= 'Step' <Expr>
                         |

!========= Select Statement

<SelectStmt>           ::= 'Select' 'Case' <Expr> <NL> <CaseStmtList> 'End' 'Select' <NL>

<CaseStmtList>         ::= 'Case' <ExprList> <NLOpt> <BlockStmtList> <CaseStmtList>
                         | 'Case' 'Else' <NLOpt> <BlockStmtList>
                         |

<NLOpt>                ::= <NL>
                         |

<ExprList>             ::= <Expr> ',' <ExprList>
                         | <Expr>

!===============================
! Rules : Expressions
!===============================

<SubSafeExpr>          ::= <SubSafeImpExpr>

<SubSafeImpExpr>       ::= <SubSafeImpExpr> 'Imp' <EqvExpr>
                         | <SubSafeEqvExpr>

<SubSafeEqvExpr>       ::= <SubSafeEqvExpr> 'Eqv' <XorExpr>
                         | <SubSafeXorExpr>

<SubSafeXorExpr>       ::= <SubSafeXorExpr> 'Xor' <OrExpr>
                         | <SubSafeOrExpr>

<SubSafeOrExpr>        ::= <SubSafeOrExpr> 'Or' <AndExpr>
                         | <SubSafeAndExpr>

<SubSafeAndExpr>       ::= <SubSafeAndExpr> 'And' <NotExpr>
                         | <SubSafeNotExpr>

<SubSafeNotExpr>       ::= 'Not' <NotExpr>
                         | <SubSafeCompareExpr>

<SubSafeCompareExpr>   ::= <SubSafeCompareExpr> 'Is' <ConcatExpr>
                         | <SubSafeCompareExpr> 'Is' 'Not' <ConcatExpr>
                         | <SubSafeCompareExpr> '>=' <ConcatExpr>
                         | <SubSafeCompareExpr> '=>' <ConcatExpr>
                         | <SubSafeCompareExpr> '<=' <ConcatExpr>
                         | <SubSafeCompareExpr> '=<' <ConcatExpr>
                         | <SubSafeCompareExpr> '>'  <ConcatExpr>
                         | <SubSafeCompareExpr> '<'  <ConcatExpr>
                         | <SubSafeCompareExpr> '<>' <ConcatExpr>
                         | <SubSafeCompareExpr> '='  <ConcatExpr>
                         | <SubSafeConcatExpr>

<SubSafeConcatExpr>    ::= <SubSafeConcatExpr> '&' <AddExpr>
                         | <SubSafeAddExpr>

<SubSafeAddExpr>       ::= <SubSafeAddExpr> '+' <ModExpr>
                         | <SubSafeAddExpr> '-' <ModExpr>
                         | <SubSafeModExpr>

<SubSafeModExpr>       ::= <SubSafeModExpr> 'Mod' <IntDivExpr>
                         | <SubSafeIntDivExpr>

<SubSafeIntDivExpr>    ::= <SubSafeIntDivExpr> '\' <MultExpr>
                         | <SubSafeMultExpr>

<SubSafeMultExpr>      ::= <SubSafeMultExpr> '*' <UnaryExpr>
                         | <SubSafeMultExpr> '/' <UnaryExpr>
                         | <SubSafeUnaryExpr>

<SubSafeUnaryExpr>     ::= '-' <UnaryExpr>
                         | '+' <UnaryExpr>
                         | <SubSafeExpExpr>

<SubSafeExpExpr>       ::= <SubSafeValue> '^' <ExpExpr>
                         | <SubSafeValue>

<SubSafeValue>         ::= <ConstExpr>
                         | <LeftExpr>
!                         | '(' <Expr> ')'

<Expr>                 ::= <ImpExpr>

<ImpExpr>              ::= <ImpExpr> 'Imp' <EqvExpr>
                         | <EqvExpr>

<EqvExpr>              ::= <EqvExpr> 'Eqv' <XorExpr>
                         | <XorExpr>

<XorExpr>              ::= <XorExpr> 'Xor' <OrExpr>
                         | <OrExpr>

<OrExpr>               ::= <OrExpr> 'Or' <AndExpr>
                         | <AndExpr>

<AndExpr>              ::= <AndExpr> 'And' <NotExpr>
                         | <NotExpr>

<NotExpr>              ::= 'Not' <NotExpr>
                         | <CompareExpr>

<CompareExpr>          ::= <CompareExpr> 'Is' <ConcatExpr>
                         | <CompareExpr> 'Is' 'Not' <ConcatExpr>
                         | <CompareExpr> '>=' <ConcatExpr>
                         | <CompareExpr> '=>' <ConcatExpr>
                         | <CompareExpr> '<=' <ConcatExpr>
                         | <CompareExpr> '=<' <ConcatExpr>
                         | <CompareExpr> '>'  <ConcatExpr>
                         | <CompareExpr> '<'  <ConcatExpr>
                         | <CompareExpr> '<>' <ConcatExpr>
                         | <CompareExpr> '='  <ConcatExpr>
                         | <ConcatExpr>

<ConcatExpr>           ::= <ConcatExpr> '&' <AddExpr>
                         | <AddExpr>

<AddExpr>              ::= <AddExpr> '+' <ModExpr>
                         | <AddExpr> '-' <ModExpr>
                         | <ModExpr>

<ModExpr>              ::= <ModExpr> 'Mod' <IntDivExpr>
                         | <IntDivExpr>

<IntDivExpr>           ::= <IntDivExpr> '\' <MultExpr>
                         | <MultExpr>

<MultExpr>             ::= <MultExpr> '*' <UnaryExpr>
                         | <MultExpr> '/' <UnaryExpr>
                         | <UnaryExpr>

<UnaryExpr>            ::= '-' <UnaryExpr>
                         | '+' <UnaryExpr>
                         | <ExpExpr>

<ExpExpr>              ::= <Value> '^' <ExpExpr>
                         | <Value>

<Value>                ::= <ConstExpr>
                         | <LeftExpr>
                         | '(' <Expr> ')'

<ConstExpr>            ::= <BoolLiteral>
                         | <IntLiteral>
                         | FloatLiteral
                         | StringLiteral
                         | DateLiteral
                         | <Nothing>

<BoolLiteral>          ::= 'True'
                         | 'False'

<IntLiteral>           ::= IntLiteral
                         | HexLiteral
                         | OctLiteral

<Nothing>              ::= 'Nothing'
                         | 'Null'
                         | 'Empty'

Visual Basic .NET

! -----------------------------------------------------------------------
! Visual Basic .NET
! 
! Visual Basic .NET is the latest version in the long evoluation of the 
! BASIC programming language. The Visual Basic .NET programming language 
! is far more "clean" and orthagonal than its predecessors. Although some 
! of the old constructs exist, the language is far easier to read and write.
! 
! Major syntax changes include, but are not limited to:
! 
! 1. The primative file access of VB6 was replaced by a class library. As 
!    a result, special statements such as 
!    
!    Open "test" For Input As #1
!    
!    no longer exist. 
! 
! 2. Class module files were replaced by 'Class ... End Class' declarations
! 
! 3. Module files were replaced by 'Module ... End Module' declarations
!
! 4. Structured error handling was added with C++ style Try ... Catch 
!    statements. The old nonstructured approach is still, unfortunately,
!    available.
! 
! Unfortnately, the designers of Visual Basic .NET did not remove the 
! datatype postfix characters on identifiers. In the original BASIC, 
! variables types were determined by $ for strings and % for integers.
! QuickBasic expanded the postix notation to include other symbols 
! for long integers, singles, etc... 
!
! Part of the ID terminal definition was commented out to prevent the
! old format. You can allow the postfix characters if you like.
!
! This grammar also does not contain the compiler directives.
!
! Note: This is an ad hoc version of the language. If there are any flaws, 
! please visit www.DevinCook.com/GOLDParser
!
! Updates:
!     04/082005
!         Devin Cook
!         1. Removed minus sign from the IntLiteral and RealLiteral 
!            definitions. These can cause some parse errors when expressions
!            like "2-2" are read. In this case it would have been interpreted
!            as "2" and "-2" rather than "2", "-" and "2".
!         2. Members of an enumeration can be defined with any expression.
!         3. Made some very minor comment changes - mainly for readability.
!
!     03/27/2005
!         Adrian Moore [adrianrob@hotmail.com]
!         1. Add support for Implements in Class
!         2. Add support for AddressOf keyword
!         3. No longer fails if variable starts with _
!
!     02/24/2004
!         Vladimir Morozov [vmoroz@hotmail.com] fixed a few flaws in the
!         grammar. 1. The definition for strings did not allow the double 
!         double-quote override. 2. A real literal does not need to have a 
!         fraction if followed by an exponent. 3. Escaped identifiers can 
!         contain a null string and 4. Rem works the same as the '
!
!
! USE GOLD PARSER BUILDER VERSION 2.1 AND LATER TO COMPILE THIS GRAMMAR.
! Earlier versions cannot handle the complexity.
! -----------------------------------------------------------------------

"Name"     = 'Visual Basic .NET' 
"Author"   = 'John G. Kemeny and Thomas E. Kurtz'
"Version"  = '.NET'
"About"    = 'Visual Basic .NET is the latest version in the long evoluation of the'
           | 'BASIC programming language.'
                 

"Case Sensitive" = False 
"Start Symbol"   = <Program>

! ----------------------------------------------------------------- Sets

{String Chars}  = {Printable} - ["]
{Date Chars}    = {Printable} - [#]
{ID Name Chars} = {Printable} - ['['']']
{Hex Digit}     = {Digit} + [abcdef]
{Oct Digit}     = [01234567]

{WS}            = {Whitespace} - {CR} - {LF}
{Id Tail}       = {Alphanumeric} + [_]

! ----------------------------------------------------------------- Terminals

NewLine        = {CR}{LF} | {CR} | ':' 
Whitespace     = {WS}+  | '_' {WS}* {CR} {LF}?

Comment Line   = '' | Rem                !Fixed by Vladimir Morozov 

LABEL          = {Letter}{ID Tail}*':'

!Fixed by Vladimir Morozov 

ID             = [_]?{Letter}{ID Tail}*           ! [%&@!#$]?   !Archaic postfix chars
               | '[' {ID Name Chars}* ']'
     
QualifiedID    = ({Letter}{ID Tail}* | '['{ID Name Chars}*']')  ( '.'({Letter}{ID Tail}* | '['{ID Name Chars}*']') )+

MemberID       = '.' {Letter}{ID Tail}* 
               | '.[' {ID Name Chars}* ']'
               
!Fixed by Vladimir Morozov 
StringLiteral  = '"' ( {String Chars} | '""' )* '"'


CharLiteral    = '"' {String Chars}* '"C'
IntLiteral     = {digit}+ [FRDSIL]?

RealLiteral    = {digit}* '.' {digit}+ ( 'E' [+-]? {Digit}+ )? [FR]?
               | {digit}+ 'E' [+-]? {Digit}+  [FR]?


DateLiteral    = '#'{Date chars}'#'

HexLiteral     = '&H'{Hex Digit}+ [SIL]?
OctLiteral     = '&O'{Oct Digit}+ [SIL]?

! ----------------------------------------------------------------- Rules

<Program>    ::= <NameSpace Item>  <Program>
               | <Imports>         <Program>
               | <Option Decl>     <Program>
               |

! -------------------------------------------------------------------
! (Shared attributes)
! -------------------------------------------------------------------

<NL>    ::= NewLine <NL> 
          | NewLine

<Modifiers> ::= <Modifier> <Modifiers>
              | 

<Modifier> ::= Shadows
             | Shared
             | MustInherit 
             | NotInheritable

             | Overridable 
             | NotOverridable 
             | MustOverride 
             | Overrides 
             | Overloads
                  
             | Default 
             | ReadOnly
             | WriteOnly
            
             | <Access>

<Access Opt> ::= <Access>
               |

<Access>  ::= Public
            | Private
            | Friend
            | Protected
            

<Var Member>   ::=  <Attributes> <Access> <Var Decl> <NL>               !Variables                    
                 |  <Attributes> <Access Opt> Const  <Var Decl> <NL>    !Constants
                 |  <Attributes> <Access Opt> Static <Var Decl> <NL>                         
                
<Implements>   ::= Implements <ID List> 

<ID List>  ::= <Identifier> ',' <ID List>
             | <Identifier>
               
<Option Decl>  ::= Option <IDs> <NL>

<IDs> ::= ID <IDs> 
        | ID
   
<Type>  ::= As <Attributes> <Identifier> 
          |

<Compare Op>  ::= '=' | '<>' | '<' | '>' | '>=' | '<='

! -------------------------------------------------------------------
! NameSpace
! -------------------------------------------------------------------

<NameSpace>       ::= NameSpace ID <NL> <NameSpace Items> End NameSpace <NL>

<NameSpace Items> ::= <NameSpace Item> <NameSpace Items>                    
                    | 

<NameSpace Item> ::= <Class>      
                   | <Declare>
                   | <Delegate>
                   | <Enumeration> 
                   | <Interface>
                   | <Structure> 
                   | <Module>              
                   | <Namespace>
          

! -------------------------------------------------------------------
! Attributes
! -------------------------------------------------------------------

<Attributes> ::= '<' <Attribute List> '>'
               |

<Attribute List> ::= <Attribute> ',' <Attribute List>
                   | <Attribute>
                   
<Attribute>     ::= <Attribute Mod> ID <Argument List Opt>                  
   
<Attribute Mod> ::= Assembly 
                  | Module 
                  | 
                             
! -------------------------------------------------------------------
! Delegates
! -------------------------------------------------------------------
<Delegate> ::= <Attributes> <Modifiers> Delegate <Method>   
             | <Attributes> <Modifiers> Delegate <Declare>   
            

! -------------------------------------------------------------------
! Imports
! -------------------------------------------------------------------

<Imports> ::= Imports <Identifier> <NL> 
            | Imports ID '=' <Identifier> <NL>

! -------------------------------------------------------------------
! Events
! -------------------------------------------------------------------

<Event Member> ::= <Attributes> <Modifiers> Event ID <Parameters Or Type> <Implements Opt> <NL>

<Parameters Or Type> ::= <Param List>
                       | As <Identifier> 

<Implements Opt> ::= <Implements>
                   |
                                         
! -------------------------------------------------------------------
! Class
! -------------------------------------------------------------------

<Class>       ::= <Attributes> <Modifiers> Class ID <NL> <Class Items> End Class <NL>


<Class Items> ::= <Class Item> <Class Items>                
                |

<Class Item>  ::= <Declare>
                | <Method>        
                | <Property>   
                | <Var Member>                
                | <Enumeration>
                | <Inherits>
                | <Class Implements>
                
<Inherits> ::= Inherits <Identifier> <NL>
               
<Class Implements> ::= Implements <ID List> <NL>

! -------------------------------------------------------------------
! Structures
! -------------------------------------------------------------------

<Structure>    ::= <Attributes> <Modifiers> Structure ID <NL> <Structure List> End Structure <NL>

<Structure List> ::= <Structure Item> <Structure List>
                   | 

<Structure Item> ::= <Implements>
                   | <Enumeration>
                   | <Structure>
                   | <Class>
                   | <Delegate>   
                   | <Var Member>                    
                   | <Event Member>
                   | <Declare>
                   | <Method>
                   | <Property>

! -------------------------------------------------------------------
! Module
! -------------------------------------------------------------------

<Module>       ::= <Attributes> <Modifiers> Module ID <NL> <Module Items> End Module <NL>

<Module Items> ::= <Module Item> <Module Items>
                 | 
                 
<Module Item>  ::= <Declare>
                 | <Method>                 
                 | <Property>   
                 | <Var Member> 
                 | <Enumeration>
                 | <Option Decl>

! -------------------------------------------------------------------
! Interface
! -------------------------------------------------------------------

<Interface> ::= <Attributes> <Modifiers> Interface ID <NL> <Interface Items> End Interface <NL>


<Interface Items> ::= <Interface Item> <Interface Items>
                    | 
               
<Interface Item>  ::= <Implements>
                    | <Event Member>
                    | <Enum Member>                   
                    | <Method Member>                   
                    | <Property Member>

<Enum Member>     ::= <Attributes> <Modifiers> Enum ID <NL>

<Method Member>   ::= <Attributes> <Modifiers> Sub <Sub ID> <Param List> <Handles Or Implements> <NL>
                    | <Attributes> <Modifiers> Function ID  <Param List> <Type> <Handles Or Implements> <NL> 

<Property Member> ::= <Attributes> <Modifiers> Property ID  <Param List> <Type> <Handles Or Implements> <NL> 
               
               
! -------------------------------------------------------------------
! Parameters
! -------------------------------------------------------------------

<Param List Opt> ::= <Param List>
                   |

<Param List>     ::= '(' <Param Items> ')'
                   | '(' ')'
 
<Param Items>    ::= <Param Item> ',' <Param Items>
                   | <Param Item>

<Param Item>     ::= <Param Passing> ID <Type> 


<Param Passing>  ::= ByVal
                   | ByRef
                   | Optional 
                   | ParamArray
                   |

! -------------------------------------------------------------------
! Arguments 
! -------------------------------------------------------------------

<Argument List Opt> ::= <Argument List>
                      |
                       
<Argument List>  ::= '(' <Argument Items> ')'
              
<Argument Items> ::= <Argument> ',' <Argument Items>
                   | <Argument> 

<Argument>       ::= <Expression>
                   | Id ':=' <Expression>
                   |                          !NULL
                   
                  
! -------------------------------------------------------------------
! Declares (External Procedures)   
! -------------------------------------------------------------------

<Declare> ::= <Attributes> <Modifiers> Declare <Charset> Sub      ID Lib StringLiteral <Alias> <Param List Opt> <NL>
            | <Attributes> <Modifiers> Declare <Charset> Function ID Lib StringLiteral <Alias> <Param List Opt> <Type> <NL>

<Charset> ::= Ansi | Unicode | Auto |  !Null

<Alias> ::= Alias StringLiteral
          |


! -------------------------------------------------------------------
! Methods
! -------------------------------------------------------------------

<Method> ::= <Attributes> <Modifiers> Sub <Sub ID> <Param List>        <Handles Or Implements> <NL> <Statements> End Sub <NL>
           | <Attributes> <Modifiers> Function ID  <Param List> <Type> <Handles Or Implements> <NL> <Statements> End Function <NL>
                
<Sub ID>     ::= ID
               | New     !Class creation

<Handles Or Implements> ::= <Implements> 
                          | <Handles>
                          | 

<Handles>      ::= Handles <ID List>

! -------------------------------------------------------------------
! Properties
! -------------------------------------------------------------------
                 
<Property>   ::= <Attributes> <Modifiers> Property ID <Param List> <Type> <NL> <Property Items> End Property <NL>

<Property Items> ::= <Property Item> <Property Items>          
                   |

<Property Item> ::= Get <NL> <Statements> End Get <NL>
                  | Set <Param List> <NL> <Statements> End Set <NL>


! ------------------------------------------------------------------- 
! Enumerations
! ------------------------------------------------------------------- 

<Enumeration>   ::= <Attributes> <Modifiers> Enum ID <NL> <Enum List> End Enum <NL>

<Enum List>     ::= <Enum Item> <Enum List>
                  | 

<Enum Item>     ::= Id '=' <Expression> <NL>
                  | Id <NL>

! -------------------------------------------------------------------
! Variable Declaration
! -------------------------------------------------------------------

<Var Decl> ::= <Var Decl Item> ',' <Var Decl>
             | <Var Decl Item>
                  
<Var Decl Item>  ::= <Var Decl ID> As <Identifier> <Argument List Opt>             
                   | <Var Decl ID> As <Identifier> '=' <Expression>         !Initialize                                        
                   | <Var Decl ID> As New <Identifier> <Argument List Opt>
                   | <Var Decl ID>
                   | <Var Decl ID> '=' <Expression>                          !Initialize 

<Var Decl ID> ::= ID <Argument List Opt> 
                
! ------------------------------------------------------------------- 
! Normal Statements
! -------------------------------------------------------------------

<Statements>  ::= <Statement> <Statements>
                | 

<Statement>   ::= <Loop Stm>
                | <For Stm>
                | <If Stm>                 
                | <Select Stm> 
                | <SyncLock Stm>
                | <Try Stm>               
                | <With Stm>
                | <Option Decl>                   
                | <Local Decl>    
                | <Non-Block Stm> <NL>       !Note the <NL>. A non-block statement can be a full statement
                | LABEL           <NL>  
                                
                              
<Non-Block Stm> ::= Call <Variable>
                  | ReDim <Var Decl>  
                  | ReDim Preserve <Var Decl>
                  | Erase ID 
     
                  | Throw <Value>                                    
                  | RaiseEvent <Identifier>  <Argument List Opt>
                  | AddHandler <Expression> ',' <Expression>
                  | RemoveHandler  <Expression> ',' <Expression>
    
                  | Exit Do 
                  | Exit For                  
                  | Exit Function            
                  | Exit Property                   
                  | Exit Select      
                  | Exit Sub    
                  | Exit Try
                  | Exit While
                  | GoTo ID                   !Argh - they still have this
                  | Return <Value>           

                  | Error <Value>                      !Raise an error by number
                  | On Error GoTo IntLiteral           ! 0  This is obsolete.   
                  | On Error GoTo '-' IntLiteral       !-1  This is obsolete.
                  | On Error GoTo Id      
                  | On Error Resume Next 
                  | Resume ID 
                  | Resume Next 
                  
                  | <Variable> <Assign Op> <Expression> 
                  | <Variable>       
                  | <Method Call>         

<Assign Op>   ::= '=' | '^=' | '*=' | '/=' | '\=' | '+=' | '-=' | '&=' | '<<=' | '>>='


! ------------------------------------------------------------------- 
! Local declarations
! -------------------------------------------------------------------

<Local Decl>  ::= Dim    <Var Decl>  <NL>
                | Const  <Var Decl>  <NL>
                | Static <Var Decl>  <NL> 

! ------------------------------------------------------------------- 
! Do Statement
! -------------------------------------------------------------------

<Loop Stm>   ::= Do <Test Type> <Expression> <NL> <Statements> Loop <NL>
               | Do <NL> <Statements> Loop <Test Type> <Expression> <NL>                
               | While <Expression> <NL> <Statements> End While <NL>

<Test Type>  ::= While
               | Until                 

! -------------------------------------------------------------------
! For Statement
! -------------------------------------------------------------------

<For Stm>   ::= For <Identifier>  '=' <Expression> To <Expression> <Step Opt> <NL> <Statements> Next <NL>    
              | For Each <Variable> In <Variable> <NL> <Statements> Next <NL>

<Step Opt>  ::= Step <Expression>
              |


! -------------------------------------------------------------------
! If Statement
! -------------------------------------------------------------------

<If Stm>    ::= If <Expression> <Then Opt> <NL> <Statements> <If Blocks> End If <NL> 
              | If <Expression> Then <Non-Block Stm> <NL>
              | If <Expression> Then <Non-Block Stm> Else <Non-Block Stm> <NL>

<Then Opt>  ::= Then         !!The reserved word 'Then' is optional for Block-If statements
              |

<If Blocks> ::= ElseIf <Expression> <Then Opt> <NL> <Statements> <If Blocks>
              | Else <NL> <Statements>
              |

! -------------------------------------------------------------------
! Select Statement
! -------------------------------------------------------------------

<Select Stm>    ::= Select <Case Opt> <Expression> <NL> <Select Blocks> End Select <NL>

<Case Opt>      ::= Case                         !!The "Case" after Select is optional in VB.NEt
                  |


<Select Blocks> ::= Case <Case Clauses> <NL> <Statements>  <Select Blocks>
                  | Case Else <NL> <Statements>  
                  |                 

<Case Clauses>  ::= <Case Clause> ',' <Case Clauses>
                  | <Case Clause> 

<Case Clause>   ::= <Is Opt> <Compare Op> <Expression>
                  | <Expression> 
                  | <Expression> To <Expression>

<Is Opt> ::= Is 
           | !Null

! -------------------------------------------------------------------
! SyncLock Statement
! -------------------------------------------------------------------

<SyncLock Stm> ::= SyncLock <NL> <Statements> End SyncLock <NL>             

! -------------------------------------------------------------------
! Try Statement
! -------------------------------------------------------------------

<Try Stm>      ::= Try <NL> <Statements> <Catch Blocks> End Try <NL>  

<Catch Blocks> ::= <Catch Block> <Catch Blocks>
                 | <Catch Block>

<Catch Block>  ::= Catch <Identifier>  As ID <NL> <Statements> 
                 | Catch <NL> <Statements>

! -------------------------------------------------------------------
! With Statement
! -------------------------------------------------------------------

<With Stm> ::= With <Value> <NL> <Statements> End With <NL>
                  
! -------------------------------------------------------------------
! Expressions
! -------------------------------------------------------------------

<Expression>  ::= <And Exp> Or     <Expression> 
                | <And Exp> OrElse <Expression> 
                | <And Exp> XOr    <Expression> 
                | <And Exp> 

<And Exp>     ::= <Not Exp> And     <And Exp> 
                | <Not Exp> AndAlso <And Exp> 
                | <Not Exp> 
 
<Not Exp>     ::= NOT <Compare Exp>
                | <Compare Exp>

<Compare Exp> ::= <Shift Exp> <Compare Op> <Compare Exp>       !e.g.  x < y
                | TypeOf <Add Exp> Is <Object>
                | <Shift Exp> Is <Object>
                | <Shift Exp> Like <Value>
                | <Shift Exp>

<Shift Exp>   ::= <Concat Exp> '<<' <Shift Exp>  
                | <Concat Exp> '>>' <Shift Exp>  
                | <Concat Exp> 

<Concat Exp>  ::= <Add Exp> '&' <Concat Exp>
                | <Add Exp>

<Add Exp>     ::= <Modulus Exp> '+' <Add Exp> 
                | <Modulus Exp> '-' <Add Exp> 
                | <Modulus Exp>  

<Modulus Exp> ::= <Int Div Exp> Mod <Modulus Exp> 
                | <Int Div Exp>

<Int Div Exp> ::= <Mult Exp> '\' <Int Div Exp>                 
                | <Mult Exp>

<Mult Exp>    ::= <Negate Exp> '*' <Mult Exp> 
                | <Negate Exp> '/' <Mult Exp> 
                | <Negate Exp> 

<Negate Exp>  ::= '-' <Power Exp> 
                | <Power Exp> 

<Power Exp>   ::= <Power Exp> '^' <Value> 
                | <Value> 

<Value>       ::= '(' <Expression> ')'                
                | New <Identifier> <Argument List Opt>
                | IntLiteral 
                | HexLiteral
                | OctLiteral
                | StringLiteral 
                | CharLiteral
                | RealLiteral
                | DateLiteral 
                | True
                | False
                | Me 
                | MyClass 
                | MyBase
                | Nothing
                | <Variable>
                | AddressOf <Identifier>

<Object>      ::= <Identifier>        !Object identifiers 
                | Me 
                | MyClass 
                | MyBase
                | Nothing

<Variable>    ::= <Identifier> <Argument List Opt> <Method Calls> 
                                
<Method Calls> ::= <Method Call> <Method Calls>
                 | 

<Method Call>  ::= MemberID <Argument List Opt>                    


<Identifier>   ::= ID | QualifiedID       !Any type of identifier