Digit =             '0'| '1'| '2'| '3'| '4'| '5'| '6'| '7'| '8'| '9'.

Letter =            '_'| 'A'| 'B'| 'C'| 'D'| 'E'| 'F'| 'G'| 'H'|
                    'I'| 'J'| 'K'| 'L'| 'M'| 'N'| 'O'| 'P'| 'Q'|
                    'R'| 'S'| 'T'| 'U'| 'V'| 'W'| 'X'| 'Y'| 'Z'|
                    'a'| 'b'| 'c'| 'd'| 'e'| 'f'| 'g'| 'h'|
                    'i'| 'j'| 'k'| 'l'| 'm'| 'n'| 'o'| 'p'| 'q'|
                    'r'| 's'| 't'| 'u'| 'v'| 'w'| 'x'| 'y'| 'z'.

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

Ident =             Letter { Letter | Digit }.

QualIdent =         [Ident '.'] Ident.

IdentList =         Ident { ',' Ident }.

HexDigit =          Digit | 'A'| 'B'| 'C'| 'D'| 'E'| 'F'|
                            'a'| 'b'| 'c'| 'd'| 'e'| 'f'.

Decimal =           Digit { Digit | '_' }.

IntConst =          Decimal | ('$' HexDigit { HexDigit | '_' }).

Sign =              [ '+' | '-'].

ScaleFactor =       ('E' | 'e') Sign Decimal.

RealConstant =      Decimal (('.' Decimal [ScaleFactor]) |
                            (['.' Decimal] ScaleFactor)) .

SignedRealConst =   Sign RealConstant.

SignedIntConst =    Sign IntConst.

CharConst =         '"' ASCII_8 '"'| "'" ASCII_8 "'"| '#'IntConst.

StringConst =       { '"' { ASCII_8 } '"' | 
                      "'" { ASCII_8 } "'" |
                      CharConst           }
                    | '""' | "''".

Comment =           ('{'  { ASCII_8 }  '}') | ('(*' { ASCII_8 } '*)').

Program =           ProgramHeading
                      UsesClause
                    Block '.'.

Block =                [ Declarations ]
                    'begin'
                       Statement { ';'
                       Statement }
                    'end'.

Declarations =      { { LabelDeclaration } |
                      { ConstDeclaration } |
                      { TypeDeclaration }  |
                      { VarDeclaration }   |
                      { PFDeclaration } }  .

ProgramHeading =    'program' Ident [ '(' IdentList ')' ] ';'.

Label =             Ident | IntConst.

LabelDeclaration =  'label' Label { ',' Label } ';'.

ConstDeclaration =  'const' Ident '=' Constant ';' {
                            Ident '=' Constant ';' }.

Constant =          SignedRealConst | SignedIntConst | CharConst |
                    StringConst | ConstExpression.

ConstExpression =   Expression.

TypeDeclaration =   'type' Ident '=' Type ';' {
                           Ident '=' Type ';' }.

Type =              TypeIdent| SimpleType| PointerType| StructuredType.

TypeIdent =         Ident.

VarDeclaration =    'var' IdentList ':' Type ';' {
                          IdentList ':' Type ';' }.

PFDeclaration =     { ProcDeclaration | FuncDeclaration }.

SimpleType =        OrdinalType | RealType.

OrdinalType =       Enumerated | SubRange | StandardType.

StandardType =      'integer'  | 'shortint'  | 'longint' |
                    'cardinal' | 'shortcard' | 'natural' |
                    'char'     | 'boolean'   |
                    'byte'     | 'word'      | 'longword'|.

RealType =          'real'.

Enumerated =        '(' IdentList ')'.

SubRange =          Constant '..' Constant.

StructuredType =    ['packed'] (ArrayType  |
                                StringType |
                                RecordType |
                                SetType    |
                                FileType   ).

ArrayType =         'array' '[' IndexType{',' IndexType} ']' 'of' Type.

IndexType =         OrdinalType.

StringType =        'string' [ '[' Constant ']' ].

RecordType =        'record' FieldList 'end'.

FieldList =         (FixedPart [';']) | (VariantPart [';']) |
                    (FixedPart ';' VariantPart [';']).

FixedPart =         IdentList ':' Type { ';'
                    IdentList ':' Type }.

VariantPart =       'case' TagField 'of'
                       CnstList ':' '(' [FieldList] ')' { ';'
                       CnstList ':' '(' [FieldList] ')' }.

TagField =          [Ident ':'] OrdinalTypeIdent.

OrdinalTypeIdent =  Ident.

SetType =           'set' 'of' OrdinalType.

FileType =          'file' [ 'of' Type ].

PointerType =       '^' TypeIdent.

Expression =        (SimpleExpression [relationOp SimpleExpression]) |
                    ExpTypeCast.

SimpleExpression =  ['+' | '-'] Term {AdditiveOp Term}.

Term =              Factor {MultiplicativeOp Factor}.

Factor =            Constant              |
                    VariableRef           |
                    SetConstructor        |
                    FunctionCall          |
                    'not' Factor          |
                    ( '(' Expression ')' ).

SetConstructor =    '[' [SetElement {',' SetElement}] ']'.

SetElement =        Expression [ '..' Expression ].

FunctionCall =      QualIdent [ ActualParamList ].

relationOp =        '='| '<>'| '<' | '<=' | '>'| '>='| 'in'.

AdditiveOp =        '+'| '-' | 'or'| 'xor'| '|'.

MultiplicativeOp =  '*'| '/' | 'div'| 'mod'| 'and'| '&'.

ExpTypeCast =       TypeIdent '(' Expression ')'.

VarTypeCast =       TypeIdent '(' VariableRef ')'.

Statement =         [Label ':'] ( SimpleStatement | StructStatement ).

SimpleStatement =   EmptyStatement | Assignment |
                    ProcedureCall  | GotoStatement.

EmptyStatement =    .

Assignment =        (VariableRef | FuncIdent) ':=' Expression.

VariableRef =       VarTypeCast |
                    (QualIdent {'.' Ident | '^' |
                     '[' Expression {',' Expression} ']'}).

FuncIdent =         Ident.

ProcedureCall =     QualIdent [ ActualParamList ].

GotoStatement =     'goto' Label.

StructStatement =   CompoundStatement |
                    IfStatement       |
                    CaseStatement     |
                    RepetativeStat    |
                    WithStatement     .

CompoundStatement = 'begin' Statement { ';' Statement } 'end'.

IfStatement =       'if' Expression
                      'then' Statement [
                      'else' Statement ].

CaseStatement =     'case' Selector 'of'
                       CnstList ':' Statement {';'
                       CnstList ':' Statement } [';'] [
                    'else' ':' Statement { ';'
                       Statement } [';'] ]
                    'end'.

Selector =          Expression.

CnstList =          Constant {',' Constant }.

RepetativeStat =    ForStatement   |
                    WhileStatement |
                    RepeatStatement.

WhileStatement =    'while' Expression 'do' Statement.

RepeatStatement =   'repeat' Statement {';'
                       Statement }
                    'until' Expression.

ForStatement =      'for' Ident ':=' Expression ('to' |
                                              'downto') Expression 'do'
                       Statement.

WithStatement =     'with' VariableRef{',' VariableRef} 'do' Statement.

ProcDeclaration =   ProcHeading ';' (Block | Directive) ';'.

ProcHeading =       ['segment'] 'procedure' Ident[FormalPList].

Directive =         'forward' | 'external' | 
                    ('code' IntConst {',' IntConst}).

FuncDeclaration =   FuncHeading ';' (Block | Directive) ';'.

FuncHeading =       ['segment'] 
                    'function' Ident[FormalPList]':'TypeIdent.

FormalPList =       '(' [ Parameter { ',' Parameter } ] ')'.

Parameter =         (['var'|'const'] IdentList ':' TypeIdent)|
                    ('var' | 'const') IdentList.

ActualParamList =   ['(' [Expression {',' Expression} ] ')'].

Unit =              'unit'Ident['('IntConst')']';' 'interface'
                       InterfacePart (
                    'implementation'
                       ImplmntPart |
                    'end') '.'.

InterfaceUnit =     'interface' 'unit'Ident['('IntConst')']';'
                       InterfacePart
                    'end' '.'.

ImplmntUnit =       'implementation' 'unit' Ident ';'
                       ImplmntPart '.'.

InterfacePart =     [ UsesClause ]   {
                    ConstDeclaration |
                    TypeDeclaration  |
                    VarDeclaration   |
                    PFDeclaration    }.

ImplmntPart =       [ UsesClause ]
                    Block.

UsesClause =        { 'uses' IdentList';' }.

Compilation =       Program| Unit| InterfaceUnit| ImplmntUnit.