;;;; mother modular generic compiler project
; (c)2001,2002/GPL Oskar Schirmer <oskar@scara.com>
; see file COPYING for GPL license details

; extended affix grammar description for pascal
; according to K. Jensen, N. Wirth, "Pascal User Manual and Report",
;   ISBN 0-387-90144-2, ISBN 3-540-90144-2

(extended-affix-grammar
  '(
    (program ((()(("PASCAL"))))
      ( ((()
          ()
        ) program-heading))
      ( ((()
          ()
        ) block))
      (period))
    (program-heading ((()()))
      (program)
      (word)
      ( ((()
          ()
        ) prog-head-files-empty)
        ((()
          ()
        ) prog-head-files))
      (semicolon))
    (prog-head-files-empty ((()())))
    (prog-head-files ((()()))
      (lparen)
      ( ((()
          ()
        ) prog-head-files-decl))
      (rparen))
    (prog-head-files-decl ((()()))
      (word)
      ( ((()
          ()
        ) prog-head-files-empty)
        ((()
          ()
        ) prog-head-files-more)))
    (prog-head-files-more ((()()))
      (comma)
      ( ((()
          ()
        ) prog-head-files-decl)))

    (block ((()()))
      ( ((()
          ()
        ) label-decl-empty)
        ((()
          ()
        ) label-declaration-part))
      ( ((()
          ()
        ) constant-def-empty)
        ((()
          ()
        ) constant-definition-part))
      ( ((()
          ()
        ) type-def-empty)
        ((()
          ()
        ) type-definition-part))
      ( ((()
          ()
        ) variable-decl-empty)
        ((()
          ()
        ) variable-declaration-part))
      ( ((()
          ()
        ) proc-func-decl-empty)
        ((()
          ()
        ) procedure-and-function-declaration-part))
      ( ((()
          ()
        ) compound-statement)))

    (label-declaration-part ((()()))
      (label)
      ( ((()
          ()
        ) label-decl))
      (semicolon))
    (label-decl-empty ((()())))
    (label-decl ((()()))
      (integer)
      ( ((()
          ()
        ) label-decl-empty)
        ((()
          ()
        ) label-decl-more)))
    (label-decl-more ((()()))
      (comma)
      ( ((()
          ()
        ) label-decl)))

    (constant-definition-part ((()()))
      (const)
      ( ((()
          ()
        ) constant-def)))
    (constant-def-empty ((()())))
    (constant-def ((()()))
      (word)
      (compare "=")
      ( ((()
          ()
        ) constant-sign-empty)
        ((()
          ()
        ) constant-sign))
      ( ((()
          ()
        ) constant))
      (semicolon)
      ( ((()
          ()
        ) constant-def-empty)
        ((()
          ()
        ) constant-def)))
    (constant-sign-empty ((()())))
    (constant-sign ((()()))
      (add))
    (constant ((()()))
      ( ((()
          ()
        ) constant-integer)
        ((()
          ()
        ) constant-real)
        ((()
          ()
        ) constant-identifier)
        ((()
          ()
        ) constant-string)))
    (constant-integer ((()()))
      (integer))
    (constant-real ((()()))
      (number))
    (constant-identifier ((()()))
      (word))
    (constant-string ((()()))
      (string))

    (type-definition-part ((()()))
      (type)
      ( ((()
          ()
        ) type-def)))
    (type-def-empty ((()())))
    (type-def ((()()))
      (word)
      (compare "=")
      ( ((()
          ()
        ) type))
      (semicolon)
      ( ((()
          ()
        ) type-def-empty)
        ((()
          ()
        ) type-def)))

    (type ((()()))
      ( ((()
          ()
        ) simple-type)
        ((()
          ()
        ) unpacked-structured-type)
        ((()
          ()
        ) packed-structured-type)
        ((()
          ()
        ) pointer-type)))
    (simple-type ((()()))
      ( ((()
          ()
        ) scalar-type)
        ((()
          ()
        ) subrange-type-or-identifier)))

    (scalar-type ((()()))
      (lparen)
      ( ((()
          ()
        ) scalar-type-def))
      (rparen))
    (scalar-type-def ((()()))
      (word)
      ( ((()
          ()
        ) scalar-type-empty)
        ((()
          ()
        ) scalar-type-more)))
    (scalar-type-empty ((()())))
    (scalar-type-more ((()()))
      (comma)
      ( ((()
          ()
        ) scalar-type-def)))

    (subrange-type-or-identifier ((()()))
      ( ((()
          ()
        ) constant))
      ( ((()
          ()
        ) subrange-type)
        ((()
          ()
        ) type-identifier)))
    (subrange-type ((()()))
      (twodots)
      ( ((()
          ()
        ) constant)))
    (type-identifier ((()())))

    (unpacked-structured-type ((()()))
      ( ((()
          ()
        ) array-type)
        ((()
          ()
        ) record-type)
        ((()
          ()
        ) set-type)
        ((()
          ()
        ) file-type)))

    (packed-structured-type ((()()))
      (packed)
      ( ((()
          ()
        ) array-type)
        ((()
          ()
        ) record-type)
        ((()
          ()
        ) set-type)
        ((()
          ()
        ) file-type)))

    (array-type ((()()))
      (array)
      (lbracket)
      ( ((()
          ()
        ) array-type-index))
      (rbracket)
      (of)
      ( ((()
          ()
        ) type)))
    (array-type-index ((()()))
      ( ((()
          ()
        ) scalar-type)
        ((()
          ()
        ) subrange-type-or-identifier))
      ( ((()
          ()
        ) array-type-index-empty)
        ((()
          ()
        ) array-type-index-more)))
    (array-type-index-empty ((()())))
    (array-type-index-more ((()()))
      (comma)
      ( ((()
          ()
        ) array-type-index)))

    (record-type ((()()))
      (record)
      ( ((()
          ()
        ) field-list))
      (end))
    (field-list ((()()))
      ( ((()
          ()
        ) fixed-part-and-more)
        ((()
          ()
        ) variant-part)))
    (fixed-part-and-more ((()()))
      ( ((()
          ()
        ) record-section-empty)
        ((()
          ()
        ) record-section))
      ( ((()
          ()
        ) field-list-empty)
        ((()
          ()
        ) field-list-more)))
    (field-list-empty ((()())))
    (field-list-more ((()()))
      (comma)
      ( ((()
          ()
        ) field-list)))
    (record-section-empty ((()())))
    (record-section ((()()))
      ( ((()
          ()
        ) record-section-ident))
      (colon)
      ( ((()
          ()
        ) type)))
    (record-section-ident ((()()))
      (word)
      ( ((()
          ()
        ) record-section-ident-empty)
        ((()
          ()
        ) record-section-ident-more)))
    (record-section-ident-empty ((()())))
    (record-section-ident-more ((()()))
      (comma)
      ( ((()
          ()
        ) record-section-ident)))
    (variant-part ((()()))
      (case)
      (word)
      ( ((()
          ()
        ) tag-field-empty)
        ((()
          ()
        ) tag-field-present))
      (of)
      ( ((()
          ()
        ) variants-empty)
        ((()
          ()
        ) variants)))
    (tag-field-empty ((()())))
    (tag-field-present ((()()))
      (colon)
      (word))
    (variants ((()()))
      ( ((()
          ()
        ) case-label-list))
      (colon)
      (lparen)
      ( ((()
          ()
        ) field-list))
      (rparen)
      ( ((()
          ()
        ) variants-empty)
        ((()
          ()
        ) variants-more)))
    (variants-empty ((()())))
    (variants-more ((()()))
      (semicolon)
      ( ((()
          ()
        ) variants)))
    (case-label-list ((()()))
      ( ((()
          ()
        ) constant))
      ( ((()
          ()
        ) case-label-list-empty)
        ((()
          ()
        ) case-label-list-more)))
    (case-label-list-empty ((()())))
    (case-label-list-more ((()()))
      (comma)
      ( ((()
          ()
        ) case-label-list)))

    (set-type ((()()))
      (set)
      (of)
      ( ((()
          ()
        ) simple-type)))

    (file-type ((()()))
      (file)
      (of)
      ( ((()
          ()
        ) type)))

    (pointer-type ((()()))
      (pointer)
      (word))

    (variable-declaration-part ((()()))
      (var)
      ( ((()
          ()
        ) variable-decl)))
    (variable-decl-empty ((()())))
    (variable-decl ((()()))
      ( ((()
          ()
        ) variable-ident-list))
      (colon)
      ( ((()
          ()
        ) type))
      (semicolon)
      ( ((()
          ()
        ) variable-decl-empty)
        ((()
          ()
        ) variable-decl)))
    (variable-ident-list ((()()))
      (word)
      ( ((()
          ()
        ) variable-ident-list-empty)
        ((()
          ()
        ) variable-ident-list-more)))
    (variable-ident-list-empty ((()())))
    (variable-ident-list-more ((()()))
      (comma)
      ( ((()
          ()
        ) variable-ident-list)))

    (procedure-and-function-declaration-part ((()()))
      ( ((()
          ()
        ) procedure-heading)
        ((()
          ()
        ) function-heading))
      ( ((()
          ()
        ) block)
        ((()
          ()
        ) forward-declaration))
      (semicolon)
      ( ((()
          ()
        ) proc-func-decl-empty)
        ((()
          ()
        ) procedure-and-function-declaration-part)))
    (proc-func-decl-empty ((()())))
    (procedure-heading ((()()))
      (procedure)
      (word)
      ( ((()
          ()
        ) formal-param-empty)
        ((()
          ()
        ) formal-parameters))
      (semicolon))
    (function-heading ((()()))
      (function)
      (word)
      ( ((()
          ()
        ) formal-param-empty)
        ((()
          ()
        ) formal-parameters))
      (colon)
      (word)
      (semicolon))

    (formal-parameters ((()()))
      (lparen)
      ( ((()
          ()
        ) formal-param))
      (rparen))
    (formal-param ((()()))
      ( ((()
          ()
        ) formal-parameter-section))
      ( ((()
          ()
        ) formal-param-empty)
        ((()
          ()
        ) formal-param-more)))
    (formal-param-empty ((()())))
    (formal-param-more ((()()))
      (colon)
      ( ((()
          ()
        ) formal-param)))

    (formal-parameter-section ((()()))
      ( ((()
          ()
        ) parameter-group)
        ((()
          ()
        ) formal-param-var)
        ((()
          ()
        ) formal-param-function)
        ((()
          ()
        ) formal-param-procedure)))
    (formal-param-var ((()()))
      (var)
      ( ((()
          ()
        ) parameter-group)))
    (formal-param-function ((()()))
      (function)
      ( ((()
          ()
        ) parameter-group)))
    (formal-param-procedure ((()()))
      (procedure)
      ( ((()
          ()
        ) param-group-ident-list)))
    (parameter-group ((()()))
      ( ((()
          ()
        ) param-group-ident-list))
      (colon)
      (word))
    (param-group-ident-list ((()()))
      (word)
      ( ((()
          ()
        ) param-group-ident-list-empty)
        ((()
          ()
        ) param-group-ident-list-more)))
    (param-group-ident-list-empty ((()())))
    (param-group-ident-list-more ((()()))
      (comma)
      ( ((()
          ()
        ) param-group-ident-list)))

    (forward-declaration ((()()))
      (forward))

    (statement ((()()))
      ( ((()
          ()
        ) statement-label))
      ( ((()
          ()
        ) if-statement)
        ((()
          ()
        ) other-statement)))
    (other-statement ((()()))
      ( ((()
          ()
        ) empty-statement)
        ((()
          ()
        ) assignment-or-procedure-statement)
        ((()
          ()
        ) goto-statement)
        ((()
          ()
        ) compound-statement)
        ((()
          ()
        ) case-statement)
        ((()
          ()
        ) while-statement)
        ((()
          ()
        ) repeat-statement)
        ((()
          ()
        ) for-statement)
        ((()
          ()
        ) with-statement)))

    (statement-label ((()()))
      ( ((()
          ()
        ) statement-label-empty)
        ((()
          ()
        ) statement-label-present)))
    (statement-label-empty ((()())))
    (statement-label-present ((()()))
      (integer)
      (colon))

    (empty-statement ((()())))

    (assignment-or-procedure-statement ((()()))
      ( ((()
          ()
        ) variable))
      ( ((()
          ()
        ) assignment-statement)
        ((()
          ()
        ) procedure-statement-without-parameters)
        ((()
          ()
        ) procedure-statement)))
    (assignment-statement ((()()))
      (be)
      ( ((()
          ()
        ) expression)))
    (procedure-statement-without-parameters ((()())))
    (procedure-statement ((()()))
      (lparen)
      ( ((()
          ()
        ) actual-param-list))
      (rparen))
    (actual-param-list ((()()))
      ( ((()
          ()
        ) expression))
      ( ((()
          ()
        ) actual-param-field-width-empty)
        ((()
          ()
        ) actual-param-field-width))
      ( ((()
          ()
        ) actual-param-list-empty)
        ((()
          ()
        ) actual-param-list-more)))
    (actual-param-list-empty ((()())))
    (actual-param-list-more ((()()))
      (comma)
      ( ((()
          ()
        ) actual-param-list)))
    (actual-param-field-width-empty ((()())))
    (actual-param-field-width ((()()))
      (colon)
      ( ((()
          ()
        ) expression))
      ( ((()
          ()
        ) actual-param-field-width-empty)
        ((()
          ()
        ) actual-param-field-width-real)))
    (actual-param-field-width-real ((()()))
      (colon)
      ( ((()
          ()
        ) expression)))

    (goto-statement ((()()))
      (goto)
      (integer))

    (compound-statement ((()()))
      (begin)
      ( ((()
          ()
        ) statement-list))
      (end))
    (statement-list ((()()))
      ( ((()
          ()
        ) statement))
      ( ((()
          ()
        ) statement-list-empty)
        ((()
          ()
        ) statement-list-more)))
    (statement-list-empty ((()())))
    (statement-list-more ((()()))
      (semicolon)
      ( ((()
          ()
        ) statement-list)))

    (if-statement ((()()))
      ( ((()
          ()
        ) if-then-part))
      ( ((()
          ()
        ) else-part)))
    (if-then-part ((()()))
      (if)
      ( ((()
          ()
        ) expression))
      (then)
      ( ((()
          ()
        ) if-branch)))
    (else-part ((()()))
      (else)
      ( ((()
          ()
        ) if-branch))
      ( ((()
          ()
        ) else-part-empty)
        ((()
          ()
        ) else-part)))
    (else-part-empty ((()())))
    (if-branch ((()()))
      ( ((()
          ()
        ) statement-label))
      ( ((()
          ()
        ) other-statement)
        ((()
          ()
        ) if-then-part)))

    (case-statement ((()()))
      (case)
      ( ((()
          ()
        ) expression))
      (of)
      ( ((()
          ()
        ) case-list))
      (end))
    (case-list ((()()))
      ( ((()
          ()
        ) case-list-element-empty)
        ((()
          ()
        ) case-list-element))
      ( ((()
          ()
        ) case-list-empty)
        ((()
          ()
        ) case-list-more)))
    (case-list-empty ((()())))
    (case-list-more ((()()))
      (semicolon)
      ( ((()
          ()
        ) case-list)))
    (case-list-element-empty ((()())))
    (case-list-element ((()()))
      ( ((()
          ()
        ) case-label-list))
      (colon)
      ( ((()
          ()
        ) statement)))
    (case-label-list ((()()))
      ( ((()
          ()
        ) constant))
      ( ((()
          ()
        ) case-label-list-empty)
        ((()
          ()
        ) case-label-list-more)))
    (case-label-list-empty ((()())))
    (case-label-list-more ((()()))
      (comma)
      ( ((()
          ()
        ) case-label-list)))

    (while-statement ((()()))
      (while)
      ( ((()
          ()
        ) expression))
      (do)
      ( ((()
          ()
        ) statement)))

    (repeat-statement ((()()))
      (repeat)
      ( ((()
          ()
        ) statement))
      (until)
      ( ((()
          ()
        ) expression)))

    (for-statement ((()()))
      (for)
      (word)
      (be)
      ( ((()
          ()
        ) expression))
      ( ((()
          ()
        ) for-to)
        ((()
          ()
        ) for-downto))
      ( ((()
          ()
        ) expression))
      (do)
      ( ((()
          ()
        ) statement)))
    (for-to ((()()))
      (to))
    (for-downto ((()()))
      (downto))

    (with-statement ((()()))
      (with)
      ( ((()
          ()
        ) record-variable-list))
      (do)
      ( ((()
          ()
        ) statement)))
    (record-variable-list ((()()))
      ( ((()
          ()
        ) variable))
      ( ((()
          ()
        ) record-variable-list-empty)
        ((()
          ()
        ) record-variable-list-more)))
    (record-variable-list-empty ((()())))
    (record-variable-list-more ((()()))
      (comma)
      ( ((()
          ()
        ) record-variable-list)))

    (variable ((()()))
      (word)
      ( ((()
          ()
        ) variable-more)))
    (variable-more ((()()))
      ( ((()
          ()
        ) variable-entire)
        ((()
          ()
        ) variable-index)
        ((()
          ()
        ) variable-field)
        ((()
          ()
        ) variable-reference)))
    (variable-entire ((()())))
    (variable-index ((()()))
      (lbracket)
      ( ((()
          ()
        ) array-index-list))
      (rbracket)
      ( ((()
          ()
        ) variable-more)))
    (array-index-list ((()()))
      ( ((()
          ()
        ) expression))
      ( ((()
          ()
        ) array-index-list-empty)
        ((()
          ()
        ) array-index-list-more)))
    (array-index-list-empty ((()())))
    (array-index-list-more ((()()))
      (comma)
      ( ((()
          ()
        ) array-index-list)))
    (variable-field ((()()))
      (period)
      (word)
      ( ((()
          ()
        ) variable-more)))
    (variable-reference ((()()))
      (pointer)
      ( ((()
          ()
        ) variable-more)))

    (expression ((()()))
      ( ((()
          ()
        ) simple-expression))
      ( ((()
          ()
        ) expression-empty)
        ((()
          ()
        ) expression-more)))
    (expression-empty ((()())))
    (expression-more ((()()))
      ( ((()
          ()
        ) rel-op-compare)
        ((()
          ()
        ) rel-op-in))
      ( ((()
          ()
        ) simple-expression)))
    (rel-op-compare ((()()))
      (compare))
    (rel-op-in ((()()))
      (in))

    (simple-expression ((()()))
      ( ((()
          ()
        ) simple-expr-optsign-empty)
        ((()
          ()
        ) simple-expr-optsign))
      ( ((()
          ()
        ) term))
      ( ((()
          ()
        ) simple-expr-empty)
        ((()
          ()
        ) simple-expr-more)))
    (simple-expr-optsign-empty ((()())))
    (simple-expr-optsign ((()()))
      (add))
    (simple-expr-empty ((()())))
    (simple-expr-more ((()()))
      ( ((()
          ()
        ) add-op-add)
        ((()
          ()
        ) add-op-or))
      ( ((()
          ()
        ) term))
      ( ((()
          ()
        ) simple-expr-empty)
        ((()
          ()
        ) simple-expr-more)))
    (add-op-add ((()()))
      (add))
    (add-op-or ((()()))
      (or))

    (term ((()()))
      ( ((()
          ()
        ) factor))
      ( ((()
          ()
        ) term-empty)
        ((()
          ()
        ) term-more)))
    (term-empty ((()())))
    (term-more ((()()))
      ( ((()
          ()
        ) mul-op-mul)
        ((()
          ()
        ) mul-op-div)
        ((()
          ()
        ) mul-op-mod)
        ((()
          ()
        ) mul-op-and))
      ( ((()
          ()
        ) factor))
      ( ((()
          ()
        ) term-empty)
        ((()
          ()
        ) term-more)))
    (mul-op-mul ((()()))
      (mul))
    (mul-op-div ((()()))
      (div))
    (mul-op-mod ((()()))
      (mod))
    (mul-op-and ((()()))
      (and))

    (factor ((()()))
      ( ((()
          ()
        ) factor-variable-or-function-designator)
        ((()
          ()
        ) factor-unsigned-integer)
        ((()
          ()
        ) factor-unsigned-real)
        ((()
          ()
        ) factor-string)
        ((()
          ()
        ) factor-nil)
        ((()
          ()
        ) factor-expression)
        ((()
          ()
        ) factor-set)
        ((()
          ()
        ) factor-not-factor)))
    (factor-variable-or-function-designator ((()()))
      (word)
      ( ((()
          ()
        ) variable-more)
        ((()
          ()
        ) function-designator)))
    (factor-unsigned-integer ((()()))
      (integer))
    (factor-unsigned-real ((()()))
      (number))
    (factor-string ((()()))
      (string))
    (factor-nil ((()()))
      (nil))
    (factor-expression ((()()))
      (lparen)
      ( ((()
          ()
        ) expression))
      (rparen))
    (factor-set ((()()))
      (lbracket)
      ( ((()
          ()
        ) element-list-empty)
        ((()
          ()
        ) element-list))
      (rbracket))
    (factor-not-factor ((()()))
      (not)
      ( ((()
          ()
        ) factor)))

    (function-designator ((()()))
      (lparen)
      ( ((()
          ()
        ) actual-param-list))
      (rparen))

    (element-list ((()()))
      ( ((()
          ()
        ) element))
      ( ((()
          ()
        ) element-list-empty)
        ((()
          ()
        ) element-list-more)))
    (element-list-empty ((()())))
    (element-list-more ((()()))
      (comma)
      ( ((()
          ()
        ) element-list)))
    (element ((()()))
      ( ((()
          ()
        ) expression))
      ( ((()
          ()
        ) element-single)
        ((()
          ()
        ) element-range)))
    (element-single ((()())))
    (element-range ((()()))
      (twodots)
      ( ((()
          ()
        ) expression)))
  )
)
