2021-08-21 14:44:37 +02:00
|
|
|
;;; vs-cobol-ii.lisp --- sample grammar for VS-Cobol II
|
|
|
|
|
|
|
|
;;; Copyright (C) 2003 by Walter C. Pelissero
|
|
|
|
|
|
|
|
;;; Author: Walter C. Pelissero <walter@pelissero.de>
|
|
|
|
;;; Project: NPG a Naive Parser Generator
|
|
|
|
;;; $Id: F-1D03709AEB30BA7644C1CFA2DF60FE8C.lisp,v 1.2 2004/03/09 10:33:07 wcp Exp $
|
|
|
|
|
|
|
|
;;; This library is free software; you can redistribute it and/or
|
|
|
|
;;; modify it under the terms of the GNU Lesser General Public License
|
|
|
|
;;; as published by the Free Software Foundation; either version 2.1
|
|
|
|
;;; of the License, or (at your option) any later version.
|
|
|
|
;;; This library is distributed in the hope that it will be useful,
|
|
|
|
;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
;;; Lesser General Public License for more details.
|
|
|
|
;;; You should have received a copy of the GNU Lesser General Public
|
|
|
|
;;; License along with this library; if not, write to the Free
|
|
|
|
;;; Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
|
|
|
;;; 02111-1307 USA
|
|
|
|
|
|
|
|
;;; Commentary:
|
|
|
|
;;;
|
|
|
|
;;; A fairly incomplete VS-Cobol II grammar fro NPG. It's probably
|
|
|
|
;;; not very accurate either.
|
|
|
|
|
|
|
|
#+cmu (ext:file-comment "$Id: F-1D03709AEB30BA7644C1CFA2DF60FE8C.lisp,v 1.2 2004/03/09 10:33:07 wcp Exp $")
|
|
|
|
|
|
|
|
(in-package :grammar)
|
|
|
|
|
|
|
|
(defun make-keyword (string)
|
|
|
|
"Create a keyword from STRING."
|
|
|
|
(intern (string-upcase string) :keyword))
|
|
|
|
|
|
|
|
(defun flatten-list (list)
|
|
|
|
"Remove one depth level in LIST."
|
|
|
|
(mapcan #'identity list))
|
|
|
|
|
|
|
|
(deflazy define-grammar
|
|
|
|
(let ((*package* #.*package*)
|
2022-01-19 14:39:58 +01:00
|
|
|
(*compile-print* (and parser::*debug* t)))
|
2021-08-21 14:44:37 +02:00
|
|
|
(reset-grammar)
|
|
|
|
(format t "creating Cobol grammar...~%")
|
|
|
|
(populate-grammar)
|
|
|
|
(let ((grammar (parser:generate-grammar)))
|
|
|
|
(reset-grammar)
|
|
|
|
(parser:print-grammar-figures grammar)
|
|
|
|
grammar)))
|
|
|
|
|
|
|
|
(defun populate-grammar ()
|
|
|
|
;;;
|
|
|
|
;;; Hereafter PP means Partial Program
|
|
|
|
;;;
|
|
|
|
|
|
|
|
#+nil
|
|
|
|
(defrule pp--declarations
|
|
|
|
:= identification-division environment-division? data-division? "PROCEDURE" "DIVISION" using-phrase? "." :rest)
|
|
|
|
|
|
|
|
;;; We need to split the parsing of the declarations from the rest
|
|
|
|
;;; because the declarations may change the lexical rules (ie decimal
|
|
|
|
;;; point)
|
|
|
|
|
|
|
|
(defrule pp--declarations
|
|
|
|
:= identification-division environment-division? data-division-head-or-procedure-division-head :rest)
|
|
|
|
|
|
|
|
(defrule data-division-head-or-procedure-division-head
|
|
|
|
:= data-division-head
|
|
|
|
:reduce :data-division
|
|
|
|
:= procedure-division-head
|
|
|
|
:reduce (list :procedure-division $1))
|
|
|
|
|
|
|
|
(defrule pp--data-division
|
|
|
|
:= data-division-content procedure-division-head :rest)
|
|
|
|
|
|
|
|
(defrule pp--sentence
|
|
|
|
:= sentence :rest
|
|
|
|
:= :eof)
|
|
|
|
|
|
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
|
|
;;; The real grammar
|
|
|
|
;;;
|
|
|
|
|
|
|
|
(defrule cobol-source-program
|
|
|
|
:= identification-division environment-division? data-division procedure-division end-program?)
|
|
|
|
|
|
|
|
(defrule identification-division
|
|
|
|
:= identification "DIVISION" "." program-id-cobol-source-program identification-division-content
|
|
|
|
:reduce program-id-cobol-source-program)
|
|
|
|
|
|
|
|
(defrule priority-number
|
|
|
|
:= integer)
|
|
|
|
|
|
|
|
(defrule level-number
|
|
|
|
:= integer)
|
|
|
|
|
|
|
|
(defrule to-id-or-lit
|
|
|
|
:= "TO" id-or-lit)
|
|
|
|
|
|
|
|
(defrule inspect-by-argument
|
|
|
|
:= variable-identifier
|
|
|
|
:= string
|
|
|
|
:= figurative-constant-simple)
|
|
|
|
|
|
|
|
(defrule figurative-constant-simple
|
|
|
|
:= "ZERO"
|
|
|
|
:reduce :zero
|
|
|
|
:= "ZEROS"
|
|
|
|
:reduce :zero
|
|
|
|
:= "ZEROES"
|
|
|
|
:reduce :zero
|
|
|
|
:= "SPACE"
|
|
|
|
:reduce :space
|
|
|
|
:= "SPACES"
|
|
|
|
:reduce :space
|
|
|
|
:= "HIGH-VALUE"
|
|
|
|
:reduce :high
|
|
|
|
:= "HIGH-VALUES"
|
|
|
|
:reduce :high
|
|
|
|
:= "LOW-VALUE"
|
|
|
|
:reduce :low
|
|
|
|
:= "LOW-VALUES"
|
|
|
|
:reduce :low
|
|
|
|
:= "QUOTE"
|
|
|
|
:reduce :quote
|
|
|
|
:= "QUOTES"
|
|
|
|
:reduce :quote
|
|
|
|
:= "NULL"
|
|
|
|
:reduce :null
|
|
|
|
:= "NULLS"
|
|
|
|
:reduce :null)
|
|
|
|
|
|
|
|
(defrule write-exceptions
|
|
|
|
:= at-end-of-page-statement-list? not-at-end-of-page-statement-list? invalid-key-statement-list? not-invalid-key-statement-list?)
|
|
|
|
|
|
|
|
(defrule set-statement-phrase
|
|
|
|
:= variable-identifier+ set-oper set-src)
|
|
|
|
|
|
|
|
(defrule set-src
|
|
|
|
:= variable-identifier
|
|
|
|
:= literal
|
|
|
|
:= "TRUE"
|
|
|
|
:= "ON"
|
|
|
|
:= "OFF")
|
|
|
|
|
|
|
|
(defrule set-oper
|
|
|
|
:= "TO"
|
|
|
|
:reduce :to
|
|
|
|
:= "UP" "BY"
|
|
|
|
:reduce :up
|
|
|
|
:= "DOWN" "BY"
|
|
|
|
:reduce :down)
|
|
|
|
|
|
|
|
(defrule fce-phrase
|
|
|
|
:= reserve-clause
|
|
|
|
:= fce-organization
|
|
|
|
:= fce-access-mode
|
|
|
|
:= record-key-clause
|
|
|
|
:= password-clause
|
|
|
|
:= alternate-record-key-clause
|
|
|
|
:= file-status-clause
|
|
|
|
:= padding-character-clause
|
|
|
|
:= record-delimiter-clause)
|
|
|
|
|
|
|
|
(defrule fce-organization
|
|
|
|
:= organization-is? alt-indexed-relative-sequential
|
|
|
|
:reduce (list :organization (make-keyword alt-indexed-relative-sequential)))
|
|
|
|
|
|
|
|
(defrule fce-access-mode
|
|
|
|
:= "ACCESS" "MODE"? "IS"? alt-sequential-random-dynamic relative-key-clause?
|
|
|
|
:reduce (list :access-mode (make-keyword alt-sequential-random-dynamic)))
|
|
|
|
|
|
|
|
(defrule alt-indexed-relative-sequential
|
|
|
|
:= "INDEXED"
|
|
|
|
:= "RELATIVE"
|
|
|
|
:= "SEQUENTIAL")
|
|
|
|
|
|
|
|
(defrule is-not
|
|
|
|
:= "IS"? "NOT"?)
|
|
|
|
|
|
|
|
(defrule all-procedures
|
|
|
|
:= "ALL" "PROCEDURES")
|
|
|
|
|
|
|
|
(defrule next-sentence
|
|
|
|
:= "NEXT" "SENTENCE")
|
|
|
|
|
|
|
|
(defrule no-rewind
|
|
|
|
:= "NO" "REWIND")
|
|
|
|
|
|
|
|
(defrule for-removal
|
|
|
|
:= "FOR"? "REMOVAL")
|
|
|
|
|
|
|
|
(defrule values
|
|
|
|
:= "VALUE"
|
|
|
|
:= "VALUES")
|
|
|
|
|
|
|
|
(defrule records
|
|
|
|
:= "RECORD"
|
|
|
|
:= "RECORDS")
|
|
|
|
|
|
|
|
(defrule end-program
|
|
|
|
:= "END" "PROGRAM" program-name ".")
|
|
|
|
|
|
|
|
(defrule environment-division
|
|
|
|
:= "ENVIRONMENT" "DIVISION" "." environment-division-content)
|
|
|
|
|
|
|
|
(defrule data-division-head
|
|
|
|
:= "DATA" "DIVISION" ".")
|
|
|
|
|
|
|
|
(defrule data-division
|
|
|
|
:= data-division-head data-division-content
|
|
|
|
:reduce data-division-content)
|
|
|
|
|
|
|
|
(defrule identification
|
|
|
|
:= "IDENTIFICATION"
|
|
|
|
:= "ID")
|
|
|
|
|
|
|
|
(defrule identification-division-content
|
|
|
|
:= identification-division-phrase*)
|
|
|
|
|
|
|
|
(defrule author
|
|
|
|
:= "AUTHOR" ".")
|
|
|
|
|
|
|
|
(defrule installation
|
|
|
|
:= "INSTALLATION" ".")
|
|
|
|
|
|
|
|
(defrule date-written
|
|
|
|
:= "DATE-WRITTEN" ".")
|
|
|
|
|
|
|
|
(defrule date-compiled
|
|
|
|
:= "DATE-COMPILED" ".")
|
|
|
|
|
|
|
|
(defrule security
|
|
|
|
:= "SECURITY" ".")
|
|
|
|
|
|
|
|
(defrule remarks
|
|
|
|
:= "REMARKS" ".")
|
|
|
|
|
|
|
|
(defrule identification-division-phrase
|
|
|
|
:= author
|
|
|
|
:= installation
|
|
|
|
:= date-written
|
|
|
|
:= date-compiled
|
|
|
|
:= security
|
|
|
|
:= remarks)
|
|
|
|
|
|
|
|
(defrule program-id-cobol-source-program
|
|
|
|
:= "PROGRAM-ID" "."? program-name initial-program? "."
|
|
|
|
:reduce program-name)
|
|
|
|
|
|
|
|
(defrule initial-program
|
|
|
|
:= "IS"? "INITIAL" "PROGRAM"?)
|
|
|
|
|
|
|
|
(defrule environment-division-content
|
|
|
|
:= configuration-section? input-output-section?)
|
|
|
|
|
|
|
|
(defrule input-output-section
|
|
|
|
:= "INPUT-OUTPUT" "SECTION" "." file-control-paragraph? i-o-control-paragraph?
|
|
|
|
:reduce file-control-paragraph)
|
|
|
|
|
|
|
|
(defrule file-control-paragraph
|
|
|
|
:= "FILE-CONTROL" "." file-control-entry*)
|
|
|
|
|
|
|
|
(defrule file-control-entry
|
|
|
|
:= select-clause assign-clause fce-phrase* "."
|
|
|
|
:reduce (append select-clause
|
2022-01-19 14:39:58 +01:00
|
|
|
assign-clause
|
|
|
|
(flatten-list fce-phrase)))
|
2021-08-21 14:44:37 +02:00
|
|
|
|
|
|
|
(defrule organization-is
|
|
|
|
:= "ORGANIZATION" "IS"?)
|
|
|
|
|
|
|
|
(defrule alt-sequential-random-dynamic
|
|
|
|
:= "SEQUENTIAL"
|
|
|
|
:= "RANDOM"
|
|
|
|
:= "DYNAMIC")
|
|
|
|
|
|
|
|
(defrule select-clause
|
|
|
|
:= "SELECT" "OPTIONAL"? file-name
|
|
|
|
:reduce (list file-name :optional (and $2 t)))
|
|
|
|
|
|
|
|
(defrule assign-clause
|
|
|
|
:= "ASSIGN" "TO"? alt-assignment-name-literal+
|
|
|
|
:reduce (list :assign alt-assignment-name-literal))
|
|
|
|
|
|
|
|
(defrule alt-assignment-name-literal
|
|
|
|
:= assignment-name
|
|
|
|
:= literal)
|
|
|
|
|
|
|
|
(defrule reserve-clause
|
|
|
|
:= "RESERVE" integer areas?)
|
|
|
|
|
|
|
|
(defrule areas
|
|
|
|
:= "AREA"
|
|
|
|
:= "AREAS")
|
|
|
|
|
|
|
|
(defrule padding-character-clause
|
|
|
|
:= "PADDING" "CHARACTER"? "IS"? alt-qualified-data-name-literal)
|
|
|
|
|
|
|
|
(defrule record-delimiter-clause
|
|
|
|
:= "RECORD" "DELIMITER" "IS"? record-delimiter-name)
|
|
|
|
|
|
|
|
(defrule record-delimiter-name
|
|
|
|
:= "STANDARD-1"
|
|
|
|
:= assignment-name)
|
|
|
|
|
|
|
|
(defrule password-clause
|
|
|
|
:= "PASSWORD" "IS"? data-name)
|
|
|
|
|
|
|
|
(defrule file-status-clause
|
|
|
|
:= "FILE"? "STATUS" "IS"? qualified-data-name qualified-data-name?
|
|
|
|
:reduce (list :file-status qualified-data-name))
|
|
|
|
|
|
|
|
(defrule relative-key-clause
|
|
|
|
:= "RELATIVE" "KEY"? "IS"? qualified-data-name
|
|
|
|
:reduce (list :relative-key qualified-data-name))
|
|
|
|
|
|
|
|
(defrule record-key-clause
|
|
|
|
:= "RECORD" "KEY"? "IS"? qualified-data-name
|
|
|
|
:reduce (list :key qualified-data-name))
|
|
|
|
|
|
|
|
(defrule alternate-record-key-clause
|
|
|
|
:= "ALTERNATE" "RECORD"? "KEY"? "IS"? qualified-data-name password-clause? with-duplicates?
|
|
|
|
:reduce (list :alternate-key qualified-data-name with-duplicates))
|
|
|
|
|
|
|
|
(defrule with-duplicates
|
|
|
|
:= "WITH"? "DUPLICATES")
|
|
|
|
|
|
|
|
(defrule i-o-control-paragraph
|
|
|
|
:= "I-O-CONTROL" "." i-o-sam? i-o-sort-merge?)
|
|
|
|
|
|
|
|
(defrule i-o-sam
|
|
|
|
:= qsam-or-sam-or-vsam-i-o-control-entries+ ".")
|
|
|
|
|
|
|
|
(defrule i-o-sort-merge
|
|
|
|
:= sort-merge-i-o-control-entries ".")
|
|
|
|
|
|
|
|
(defrule qsam-or-sam-or-vsam-i-o-control-entries
|
|
|
|
:= qsam-or-sam-or-vsam-i-o-control-entries-1
|
|
|
|
:= qsam-or-sam-or-vsam-i-o-control-entries-2
|
|
|
|
:= qsam-or-sam-or-vsam-i-o-control-entries-3
|
|
|
|
:= qsam-or-sam-or-vsam-i-o-control-entries-4)
|
|
|
|
|
|
|
|
(defrule qsam-or-sam-or-vsam-i-o-control-entries-1
|
|
|
|
:= "RERUN" "ON" alt-assignment-name-file-name "EVERY"? every-phrase "OF"? file-name)
|
|
|
|
|
|
|
|
(defrule every-phrase-1
|
|
|
|
:= integer "RECORDS")
|
|
|
|
|
|
|
|
(defrule every-phrase-2
|
|
|
|
:= "END" "OF"? alt-reel-unit)
|
|
|
|
|
|
|
|
(defrule every-phrase
|
|
|
|
:= every-phrase-1
|
|
|
|
:= every-phrase-2)
|
|
|
|
|
|
|
|
(defrule alt-assignment-name-file-name
|
|
|
|
:= assignment-name
|
|
|
|
:= file-name)
|
|
|
|
|
|
|
|
(defrule qsam-or-sam-or-vsam-i-o-control-entries-2
|
|
|
|
:= "SAME" "RECORD"? "AREA"? "FOR"? file-name file-name+)
|
|
|
|
|
|
|
|
(defrule qsam-or-sam-or-vsam-i-o-control-entries-3
|
|
|
|
:= "MULTIPLE" "FILE" "TAPE"? "CONTAINS"? file-name-position+)
|
|
|
|
|
|
|
|
(defrule position
|
|
|
|
:= "POSITION" integer)
|
|
|
|
|
|
|
|
(defrule file-name-position
|
|
|
|
:= file-name position?)
|
|
|
|
|
|
|
|
(defrule qsam-or-sam-or-vsam-i-o-control-entries-4
|
|
|
|
:= "APPLY" "WRITE-ONLY" "ON"? file-name+)
|
|
|
|
|
|
|
|
(defrule sort-merge-i-o-control-entries
|
|
|
|
:= rerun-on? same-area+)
|
|
|
|
|
|
|
|
(defrule rerun-on
|
|
|
|
:= "RERUN" "ON" assignment-name)
|
|
|
|
|
|
|
|
(defrule record-sort
|
|
|
|
:= "RECORD"
|
|
|
|
:= "SORT"
|
|
|
|
:= "SORT-MERGE")
|
|
|
|
|
|
|
|
(defrule same-area
|
|
|
|
:= "SAME" record-sort "AREA"? "FOR"? file-name file-name+)
|
|
|
|
|
|
|
|
(defrule configuration-section
|
|
|
|
:= "CONFIGURATION" "SECTION" "." configuration-section-paragraph*
|
|
|
|
:reduce (flatten-list configuration-section-paragraph))
|
|
|
|
|
|
|
|
(defrule configuration-section-paragraph
|
|
|
|
:= source-computer-paragraph
|
|
|
|
:= object-computer-paragraph
|
|
|
|
:= special-names-paragraph)
|
|
|
|
|
|
|
|
(defrule source-computer-paragraph
|
|
|
|
:= "SOURCE-COMPUTER" "." source-computer-name
|
|
|
|
:reduce (list :source-computer source-computer-name))
|
|
|
|
|
|
|
|
(defrule with-debugging-mode
|
|
|
|
:= "WITH"? "DEBUGGING" "MODE")
|
|
|
|
|
|
|
|
(defrule source-computer-name
|
|
|
|
:= computer-name with-debugging-mode? "."
|
|
|
|
:reduce computer-name)
|
|
|
|
|
|
|
|
(defrule object-computer-paragraph
|
|
|
|
:= "OBJECT-COMPUTER" "." object-computer-name
|
|
|
|
:reduce (list :object-computer object-computer-name))
|
|
|
|
|
|
|
|
(defrule memory-size-type
|
|
|
|
:= "WORDS"
|
|
|
|
:= "CHARACTERS"
|
|
|
|
:= "MODULES")
|
|
|
|
|
|
|
|
(defrule memory-size
|
|
|
|
:= "MEMORY" "SIZE"? integer memory-size-type)
|
|
|
|
|
|
|
|
(defrule object-computer-name
|
|
|
|
:= computer-name memory-size? object-computer-paragraph-sequence-phrase "."
|
|
|
|
:reduce computer-name)
|
|
|
|
|
|
|
|
(defrule object-computer-paragraph-sequence-phrase
|
|
|
|
:= program-collating-sequence? segment-limit?)
|
|
|
|
|
|
|
|
(defrule program-collating-sequence
|
|
|
|
:= "PROGRAM"? "COLLATING"? "SEQUENCE" "IS"? alphabet-name)
|
|
|
|
|
|
|
|
(defrule segment-limit
|
|
|
|
:= "SEGMENT-LIMIT" "IS"? priority-number)
|
|
|
|
|
|
|
|
(defrule special-names-paragraph
|
|
|
|
:= "SPECIAL-NAMES" "." special-names-paragraph-phrase* special-names-paragraph-clause* "."
|
|
|
|
:reduce (flatten-list special-names-paragraph-clause))
|
|
|
|
|
|
|
|
(defrule is-mnemonic-name
|
|
|
|
:= "IS"? mnemonic-name special-names-paragraph-status-phrase?)
|
|
|
|
|
|
|
|
(defrule special-names-paragraph-phrase-tail
|
|
|
|
:= is-mnemonic-name
|
|
|
|
:= special-names-paragraph-status-phrase)
|
|
|
|
|
|
|
|
(defrule special-names-paragraph-phrase
|
|
|
|
:= environment-name special-names-paragraph-phrase-tail)
|
|
|
|
|
|
|
|
(defrule special-names-paragraph-status-phrase
|
|
|
|
:= special-names-paragraph-status-phrase-1
|
|
|
|
:= special-names-paragraph-status-phrase-2)
|
|
|
|
|
|
|
|
(defrule special-names-paragraph-status-phrase-1
|
|
|
|
:= "ON" "STATUS"? "IS"? condition off-status?)
|
|
|
|
|
|
|
|
(defrule off-status
|
|
|
|
:= "OFF" "STATUS"? "IS"? condition)
|
|
|
|
|
|
|
|
(defrule special-names-paragraph-status-phrase-2
|
|
|
|
:= "OFF" "STATUS"? "IS"? condition on-status?)
|
|
|
|
|
|
|
|
(defrule on-status
|
|
|
|
:= "ON" "STATUS"? "IS"? condition)
|
|
|
|
|
|
|
|
(defrule special-names-paragraph-clause
|
|
|
|
;; := alphabet-clause
|
|
|
|
;; := symbolic-characters-clause
|
|
|
|
:= currency-sign-clause
|
|
|
|
:= decimal-point-clause)
|
|
|
|
|
|
|
|
(defrule alphabet-clause
|
|
|
|
:= "ALPHABET" alphabet-name "IS"? alphabet-type)
|
|
|
|
|
|
|
|
(defrule alphabet-type-also
|
|
|
|
:= "ALSO" literal)
|
|
|
|
|
|
|
|
(defrule alphabet-type-alsos
|
|
|
|
:= alphabet-type-also+)
|
|
|
|
|
|
|
|
(defrule alphabet-type-also-through
|
|
|
|
:= through-literal
|
|
|
|
:= alphabet-type-alsos)
|
|
|
|
|
|
|
|
(defrule alphabet-type-other
|
|
|
|
:= literal alphabet-type-also-through?)
|
|
|
|
|
|
|
|
(defrule alphabet-type-others
|
|
|
|
:= alphabet-type-other+)
|
|
|
|
|
|
|
|
(defrule alphabet-type
|
|
|
|
:= "STANDARD-1"
|
|
|
|
:= "STANDARD-2"
|
|
|
|
:= "NATIVE"
|
|
|
|
:= "EBCDIC"
|
|
|
|
:= alphabet-type-others)
|
|
|
|
|
|
|
|
(defrule symbolic-characters-clause
|
|
|
|
:= "SYMBOLIC" "CHARACTERS"? symbolic-character-mapping+ in-alphabet-name?)
|
|
|
|
|
|
|
|
(defrule are
|
|
|
|
:= "ARE"
|
|
|
|
:= "IS")
|
|
|
|
|
|
|
|
(defrule symbolic-character-mapping
|
|
|
|
:= symbolic-character+ are? integer+)
|
|
|
|
|
|
|
|
(defrule in-alphabet-name
|
|
|
|
:= "IN" alphabet-name)
|
|
|
|
|
|
|
|
(defrule currency-sign-clause
|
|
|
|
:= "CURRENCY" "SIGN"? "IS"? literal
|
|
|
|
:reduce (list :currency-sign literal))
|
|
|
|
|
|
|
|
(defrule decimal-point-clause
|
|
|
|
:= "DECIMAL-POINT" "IS"? "COMMA"
|
|
|
|
:reduce (list :decimal-point #\,))
|
|
|
|
|
|
|
|
(defrule data-division-content
|
|
|
|
:= file-section? working-storage-section? linkage-section?)
|
|
|
|
|
|
|
|
(defrule file-section-entry
|
|
|
|
:= file-and-sort-description-entry data-description-entry+
|
|
|
|
:reduce (cons file-and-sort-description-entry data-description-entry))
|
|
|
|
|
|
|
|
(defrule file-section-head
|
|
|
|
:= "FILE" "SECTION" ".")
|
|
|
|
|
|
|
|
(defrule file-section
|
|
|
|
:= file-section-head file-section-entry*
|
|
|
|
:reduce $2)
|
|
|
|
|
|
|
|
(defrule working-storage-section-head
|
|
|
|
:= "WORKING-STORAGE" "SECTION" ".")
|
|
|
|
|
|
|
|
(defrule working-storage-section
|
|
|
|
:= working-storage-section-head data-description-entry*
|
|
|
|
:reduce $2)
|
|
|
|
|
|
|
|
(defrule linkage-section-head
|
|
|
|
:= "LINKAGE" "SECTION" ".")
|
|
|
|
|
|
|
|
(defrule linkage-section
|
|
|
|
:= linkage-section-head data-description-entry*
|
|
|
|
:reduce $2)
|
|
|
|
|
|
|
|
(defrule file-and-sort-description-entry
|
|
|
|
:= alt-fd-sd file-name file-and-sort-description-entry-clause* "."
|
|
|
|
:reduce (list (make-keyword alt-fd-sd) file-name file-and-sort-description-entry-clause))
|
|
|
|
|
|
|
|
(defrule alt-fd-sd
|
|
|
|
:= "FD"
|
|
|
|
:= "SD")
|
|
|
|
|
|
|
|
(defrule file-and-sort-description-entry-clause
|
|
|
|
:= external-clause
|
|
|
|
:= global-clause
|
|
|
|
:= block-contains-clause
|
|
|
|
:= record-clause
|
|
|
|
:= label-records-clause
|
|
|
|
:= value-of-clause
|
|
|
|
:= data-records-clause
|
|
|
|
:= linage-clause
|
|
|
|
:= recording-mode-clause
|
|
|
|
:= code-set-clause)
|
|
|
|
|
|
|
|
(defrule integer-to
|
|
|
|
:= integer "TO")
|
|
|
|
|
|
|
|
(defrule block-contains-clause
|
|
|
|
:= "BLOCK" "CONTAINS"? integer-to? integer alt-characters-records?)
|
|
|
|
|
|
|
|
(defrule alt-characters-records
|
|
|
|
:= "CHARACTERS"
|
|
|
|
:= "RECORDS"
|
|
|
|
:= "RECORD")
|
|
|
|
|
|
|
|
(defrule record-clause
|
|
|
|
:= "RECORD" record-clause-tail)
|
|
|
|
|
|
|
|
(defrule depending-on
|
|
|
|
:= "DEPENDING" "ON"? data-name)
|
|
|
|
|
|
|
|
(defrule record-clause-tail-1
|
|
|
|
:= "CONTAINS"? integer "CHARACTERS"?)
|
|
|
|
|
|
|
|
(defrule record-clause-tail-2
|
|
|
|
:= "CONTAINS"? integer "TO" integer "CHARACTERS"?)
|
|
|
|
|
|
|
|
(defrule record-clause-tail-3
|
|
|
|
:= record-varying-phrase depending-on?)
|
|
|
|
|
|
|
|
(defrule record-clause-tail
|
|
|
|
:= record-clause-tail-2
|
|
|
|
:= record-clause-tail-1
|
|
|
|
:= record-clause-tail-3)
|
|
|
|
|
|
|
|
(defrule record-varying-phrase
|
|
|
|
:= "IS"? "VARYING" "IN"? "SIZE"? from-integer? to-integer? "CHARACTERS"?)
|
|
|
|
|
|
|
|
(defrule from-integer
|
|
|
|
:= "FROM"? integer)
|
|
|
|
|
|
|
|
(defrule to-integer
|
|
|
|
:= "TO" integer)
|
|
|
|
|
|
|
|
(defrule label-records-clause
|
|
|
|
:= "LABEL" records-are label-records-clause-tail
|
|
|
|
:reduce (list :label-record label-records-clause-tail))
|
|
|
|
|
|
|
|
(defrule data-names
|
|
|
|
:= data-name+)
|
|
|
|
|
|
|
|
(defrule label-records-clause-tail
|
|
|
|
:= "STANDARD" :reduce :standard
|
|
|
|
:= "OMITTED" :reduce :omitted
|
|
|
|
:= data-names)
|
|
|
|
|
|
|
|
(defrule value-of-clause
|
|
|
|
:= "VALUE" "OF" value-of-clause-tail+)
|
|
|
|
|
|
|
|
(defrule alt-qualified-data-name-literal
|
|
|
|
:= qualified-data-name
|
|
|
|
:= literal)
|
|
|
|
|
|
|
|
(defrule value-of-clause-tail
|
|
|
|
:= variable-identifier "IS"? alt-qualified-data-name-literal)
|
|
|
|
|
|
|
|
(defrule data-records-clause
|
|
|
|
:= "DATA" records-are data-name+)
|
|
|
|
|
|
|
|
(defrule records-are
|
|
|
|
:= records are?)
|
|
|
|
|
|
|
|
(defrule linage-clause
|
|
|
|
:= "LINAGE" "IS"? alt-data-name-integer "LINES"? linage-footing-phrase)
|
|
|
|
|
|
|
|
(defrule linage-footing-phrase
|
|
|
|
:= footing? lines-top? lines-bottom?)
|
|
|
|
|
|
|
|
(defrule alt-data-name-integer
|
|
|
|
:= data-name
|
|
|
|
:= integer)
|
|
|
|
|
|
|
|
(defrule footing
|
|
|
|
:= "WITH"? "FOOTING" "AT"? alt-data-name-integer)
|
|
|
|
|
|
|
|
(defrule lines-top
|
|
|
|
:= "LINES"? "AT"? "TOP" alt-data-name-integer)
|
|
|
|
|
|
|
|
(defrule lines-bottom
|
|
|
|
:= "LINES"? "AT"? "BOTTOM" alt-data-name-integer)
|
|
|
|
|
|
|
|
(defrule recording-mode-clause
|
|
|
|
:= "RECORDING" "MODE"? "IS"? variable-identifier)
|
|
|
|
|
|
|
|
(defrule code-set-clause
|
|
|
|
:= "CODE-SET" "IS"? alphabet-name)
|
|
|
|
|
|
|
|
(defrule data-description-entry
|
|
|
|
:= level-number alt-data-name-filler? data-description-entry-clause* "."
|
|
|
|
:reduce (append (list level-number alt-data-name-filler)
|
2022-01-19 14:39:58 +01:00
|
|
|
(flatten-list data-description-entry-clause)))
|
2021-08-21 14:44:37 +02:00
|
|
|
|
|
|
|
(defrule alt-data-name-filler
|
|
|
|
:= data-name
|
|
|
|
:= "FILLER"
|
|
|
|
:reduce (list))
|
|
|
|
|
|
|
|
(defrule data-description-entry-clause
|
|
|
|
:= picture-clause
|
|
|
|
:= redefines-clause
|
|
|
|
:= blank-when-zero-clause
|
|
|
|
:= external-clause
|
|
|
|
:= global-clause
|
|
|
|
:= justified-clause
|
|
|
|
:= occurs-clause
|
|
|
|
:= sign-clause
|
|
|
|
:= synchronized-clause
|
|
|
|
:= usage-clause
|
|
|
|
:= renames-clause
|
|
|
|
:= value-clause)
|
|
|
|
|
|
|
|
(defrule value-clause
|
|
|
|
:= "VALUE" "IS"? literal
|
|
|
|
:reduce (list :value literal))
|
|
|
|
|
|
|
|
(defrule redefines-clause
|
|
|
|
:= "REDEFINES" data-name
|
|
|
|
:reduce `(:redefines ,data-name))
|
|
|
|
|
|
|
|
(defrule blank-when-zero-clause
|
|
|
|
:= "BLANK" "WHEN"? zeroes
|
|
|
|
:reduce '(:blank-when-zero t))
|
|
|
|
|
|
|
|
(defrule zeroes
|
|
|
|
:= "ZERO"
|
|
|
|
:= "ZEROS"
|
|
|
|
:= "ZEROES")
|
|
|
|
|
|
|
|
(defrule external-clause
|
|
|
|
:= "IS"? "EXTERNAL"
|
|
|
|
:reduce '(:external t))
|
|
|
|
|
|
|
|
(defrule global-clause
|
|
|
|
:= "IS"? "GLOBAL"
|
|
|
|
:reduce '(:global t))
|
|
|
|
|
|
|
|
(defrule justified-clause
|
|
|
|
:= justified "RIGHT"?
|
|
|
|
:reduce `(:justified ,(if $2 :right :left)))
|
|
|
|
|
|
|
|
(defrule justified
|
|
|
|
:= "JUSTIFIED"
|
|
|
|
:= "JUST")
|
|
|
|
|
|
|
|
(defrule occurs-clause
|
|
|
|
:= "OCCURS" integer "TIMES"? occurs-clause-key* indexed-by?
|
|
|
|
;; to be completed -wcp16/7/03.
|
|
|
|
:reduce `(:times ,integer)
|
|
|
|
:= "OCCURS" integer "TO" integer "TIMES"? "DEPENDING" "ON"? qualified-data-name occurs-clause-key* indexed-by?
|
|
|
|
;; to be completed -wcp16/7/03.
|
|
|
|
:reduce `(:times (,integer ,integer2 ,qualified-data-name)))
|
|
|
|
|
|
|
|
(defrule occurs-clause-key
|
|
|
|
:= alt-ascending-descending "KEY"? "IS"? qualified-data-name+)
|
|
|
|
|
|
|
|
(defrule indexed-by
|
|
|
|
:= "INDEXED" "BY"? index-name+)
|
|
|
|
|
|
|
|
(defrule picture-clause
|
|
|
|
:= picture "IS"? picture-string
|
|
|
|
:reduce `(:picture ,picture-string))
|
|
|
|
|
|
|
|
(defrule picture
|
|
|
|
:= "PICTURE"
|
|
|
|
:= "PIC")
|
|
|
|
|
|
|
|
(defrule sign-clause
|
|
|
|
:= sign-is? alt-leading-trailing separate-character?
|
|
|
|
:reduce `(:separate-sign ,separate-character :sign-position ,alt-leading-trailing))
|
|
|
|
|
|
|
|
(defrule sign-is
|
|
|
|
:= "SIGN" "IS"?)
|
|
|
|
|
|
|
|
(defrule separate-character
|
|
|
|
:= "SEPARATE" "CHARACTER"?
|
|
|
|
:reduce t)
|
|
|
|
|
|
|
|
(defrule alt-leading-trailing
|
|
|
|
:= "LEADING"
|
|
|
|
:reduce :leading
|
|
|
|
:= "TRAILING"
|
|
|
|
:reduce :trailing)
|
|
|
|
|
|
|
|
(defrule synchronized-clause
|
|
|
|
:= synchronized alt-left-right?
|
|
|
|
:reduce `(:synchronized ,(if alt-left-right
|
2022-01-19 14:39:58 +01:00
|
|
|
alt-left-right
|
|
|
|
t)))
|
2021-08-21 14:44:37 +02:00
|
|
|
|
|
|
|
(defrule alt-left-right
|
|
|
|
:= "LEFT"
|
|
|
|
:reduce :left
|
|
|
|
:= "RIGHT"
|
|
|
|
:reduce :right)
|
|
|
|
|
|
|
|
(defrule synchronized
|
|
|
|
:= "SYNCHRONIZED"
|
|
|
|
:= "SYNC")
|
|
|
|
|
|
|
|
(defrule usage-clause
|
|
|
|
:= usage-is? usage
|
|
|
|
:reduce (list :encoding usage))
|
|
|
|
|
|
|
|
(defrule usage-is
|
|
|
|
:= "USAGE" "IS"?)
|
|
|
|
|
|
|
|
(defrule usage
|
|
|
|
:= "BINARY"
|
|
|
|
:reduce :binary
|
|
|
|
:= "COMP"
|
|
|
|
:reduce :comp
|
|
|
|
:= "COMP-1"
|
|
|
|
:reduce :comp1
|
|
|
|
:= "COMP-2"
|
|
|
|
:reduce :comp2
|
|
|
|
:= "COMP-3"
|
|
|
|
:reduce :comp3
|
|
|
|
:= "COMP-4"
|
|
|
|
:reduce :comp4
|
|
|
|
:= "COMPUTATIONAL"
|
|
|
|
:reduce :comp
|
|
|
|
:= "COMPUTATIONAL-1"
|
|
|
|
:reduce :comp1
|
|
|
|
:= "COMPUTATIONAL-2"
|
|
|
|
:reduce :comp2
|
|
|
|
:= "COMPUTATIONAL-3"
|
|
|
|
:reduce :comp3
|
|
|
|
:= "COMPUTATIONAL-4"
|
|
|
|
:reduce :comp4
|
|
|
|
:= "DISPLAY"
|
|
|
|
:reduce :display
|
|
|
|
:= "DISPLAY-1"
|
|
|
|
:reduce :display1
|
|
|
|
:= "INDEX"
|
|
|
|
:reduce :index
|
|
|
|
:= "PACKED-DECIMAL"
|
|
|
|
:reduce :packed-decimal
|
|
|
|
:= "POINTER"
|
|
|
|
:reduce :pointer)
|
|
|
|
|
|
|
|
(defrule renames-clause
|
|
|
|
:= "RENAMES" qualified-data-name through-qualified-data-name?
|
|
|
|
:reduce `(:renames ,qualified-data-name ,through-qualified-data-name))
|
|
|
|
|
|
|
|
(defrule through-qualified-data-name
|
|
|
|
:= through qualified-data-name
|
|
|
|
:reduce qualified-data-name)
|
|
|
|
|
|
|
|
(defrule condition-value-clause
|
|
|
|
:= values-are literal-through-literal+)
|
|
|
|
|
|
|
|
(defrule through-literal
|
|
|
|
:= through literal)
|
|
|
|
|
|
|
|
(defrule literal-through-literal
|
|
|
|
:= literal through-literal?)
|
|
|
|
|
|
|
|
(defrule values-are
|
|
|
|
:= values are?)
|
|
|
|
|
|
|
|
(defrule procedure-division-head
|
|
|
|
:= "PROCEDURE" "DIVISION" using-phrase? ".")
|
|
|
|
|
|
|
|
(defrule procedure-division
|
|
|
|
:= procedure-division-head sentence+)
|
|
|
|
|
|
|
|
(defrule using-phrase
|
|
|
|
:= "USING" data-name+)
|
|
|
|
|
|
|
|
|
|
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
|
|
|
|
|
|
|
|
|
|
(defrule declaratives
|
|
|
|
:= "DECLARATIVES" "." declaratives-content+ "END" "DECLARATIVES" ".")
|
|
|
|
|
|
|
|
(defrule declaratives-content
|
|
|
|
:= cobol-identifier "SECTION" "." use-statement "." sentence*)
|
|
|
|
|
|
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
|
|
|
|
|
|
|
|
|
|
(defrule paragraph-header
|
|
|
|
:= cobol-identifier "SECTION"?
|
|
|
|
:reduce (list (if $2 :section :label) $1))
|
|
|
|
|
|
|
|
(defrule sentence
|
|
|
|
:= declaratives
|
|
|
|
:= statement* "."
|
|
|
|
:reduce $1
|
|
|
|
:= paragraph-header "."
|
|
|
|
:reduce $1)
|
|
|
|
|
|
|
|
(defrule statement
|
|
|
|
:= move-statement
|
|
|
|
:= if-statement
|
|
|
|
:= perform-statement
|
|
|
|
:= go-to-statement
|
|
|
|
:= accept-statement
|
|
|
|
:= add-statement
|
|
|
|
:= alter-statement
|
|
|
|
:= call-statement
|
|
|
|
:= cancel-statement
|
|
|
|
:= close-statement
|
|
|
|
:= compute-statement
|
|
|
|
:= continue-statement
|
|
|
|
:= delete-statement
|
|
|
|
:= display-statement
|
|
|
|
:= divide-statement
|
|
|
|
:= entry-statement
|
|
|
|
:= evaluate-statement
|
|
|
|
:= exit-program-statement
|
|
|
|
:= exit-statement
|
|
|
|
:= goback-statement
|
|
|
|
:= initialize-statement
|
|
|
|
:= inspect-statement
|
|
|
|
:= merge-statement
|
|
|
|
:= multiply-statement
|
|
|
|
:= open-statement
|
|
|
|
:= read-statement
|
|
|
|
:= release-statement
|
|
|
|
:= return-statement
|
|
|
|
:= rewrite-statement
|
|
|
|
:= search-statement
|
|
|
|
:= set-statement
|
|
|
|
:= sort-statement
|
|
|
|
:= start-statement
|
|
|
|
:= stop-statement
|
|
|
|
:= string-statement
|
|
|
|
:= subtract-statement
|
|
|
|
:= unstring-statement
|
|
|
|
:= write-statement
|
|
|
|
:= paragraph-header)
|
|
|
|
|
|
|
|
(defrule accept-statement
|
|
|
|
:= "ACCEPT" variable-identifier "FROM" date
|
|
|
|
:= "ACCEPT" variable-identifier "AT" screen-coordinates
|
|
|
|
:reduce (apply #'list 'accept-at variable-identifier screen-coordinates)
|
|
|
|
:= "ACCEPT" variable-identifier from-environment-name?)
|
|
|
|
|
|
|
|
(defrule from-environment-name
|
|
|
|
:= "FROM" cobol-identifier)
|
|
|
|
|
|
|
|
|
|
|
|
(defrule date
|
|
|
|
:= "DATE"
|
|
|
|
:= "DAY"
|
|
|
|
:= "DAY-OF-WEEK"
|
|
|
|
:= "TIME")
|
|
|
|
|
|
|
|
(defrule add-statement
|
|
|
|
:= "ADD" id-or-lit+ to-id-or-lit? "GIVING" cobword-rounded+ on-size-error-statement-list? not-on-size-error-statement-list? "END-ADD"?
|
|
|
|
:= "ADD" id-or-lit+ "TO" cobword-rounded+ on-size-error-statement-list? not-on-size-error-statement-list? "END-ADD"?
|
|
|
|
:= "ADD" corresponding variable-identifier "TO" variable-identifier "ROUNDED"? on-size-error-statement-list? not-on-size-error-statement-list? "END-ADD"?)
|
|
|
|
|
|
|
|
(defrule statement-list
|
|
|
|
:= statement+)
|
|
|
|
|
|
|
|
(defrule alter-statement
|
|
|
|
:= "ALTER" procedure-to-procedure+)
|
|
|
|
|
|
|
|
(defrule proceed-to
|
|
|
|
:= "PROCEED" "TO")
|
|
|
|
|
|
|
|
(defrule procedure-to-procedure
|
|
|
|
:= procedure-name "TO" proceed-to? procedure-name)
|
|
|
|
|
|
|
|
(defrule call-statement
|
|
|
|
:= "CALL" id-or-lit using-parameters? call-rest-phrase "END-CALL"?
|
|
|
|
:reduce (list 'call id-or-lit (cons 'list using-parameters)))
|
|
|
|
|
|
|
|
(defrule by-reference
|
|
|
|
:= "BY"? "REFERENCE")
|
|
|
|
|
|
|
|
(defrule content-parameter-value
|
|
|
|
:= cobol-identifier
|
|
|
|
:= literal)
|
|
|
|
|
|
|
|
(defrule reference-parameter
|
|
|
|
:= by-reference? variable-identifier)
|
|
|
|
|
|
|
|
(defrule content-parameter
|
|
|
|
:= "BY"? "CONTENT" content-parameter-value+)
|
|
|
|
|
|
|
|
(defrule parameter
|
|
|
|
:= reference-parameter
|
|
|
|
:= content-parameter
|
|
|
|
:= literal)
|
|
|
|
|
|
|
|
(defrule using-parameters
|
|
|
|
:= "USING" parameter+)
|
|
|
|
|
|
|
|
(defrule call-rest-phrase
|
|
|
|
:= on-exception-statement-list? not-on-exception-statement-list? on-overflow-statement-list?)
|
|
|
|
|
|
|
|
(defrule on-exception-statement-list
|
|
|
|
:= "ON"? "EXCEPTION" statement-list)
|
|
|
|
|
|
|
|
(defrule not-on-exception-statement-list
|
|
|
|
:= "NOT" "ON"? "EXCEPTION" statement-list)
|
|
|
|
|
|
|
|
(defrule cancel-statement
|
|
|
|
:= "CANCEL" id-or-lit+)
|
|
|
|
|
|
|
|
(defrule close-statement
|
|
|
|
:= "CLOSE" close-statement-file-name+
|
|
|
|
:reduce (list 'close close-statement-file-name))
|
|
|
|
|
|
|
|
(defrule alt-removal-no-rewind
|
|
|
|
:= for-removal
|
|
|
|
:= with-no-rewind)
|
|
|
|
|
|
|
|
(defrule alt-reel-unit
|
|
|
|
:= "REEL"
|
|
|
|
:= "UNIT")
|
|
|
|
|
|
|
|
(defrule alt-no-rewind-lock
|
|
|
|
:= no-rewind
|
|
|
|
:= "LOCK")
|
|
|
|
|
|
|
|
(defrule close-statement-options-1
|
|
|
|
:= alt-reel-unit alt-removal-no-rewind?)
|
|
|
|
|
|
|
|
(defrule close-statement-options-2
|
|
|
|
:= "WITH"? alt-no-rewind-lock)
|
|
|
|
|
|
|
|
(defrule close-statement-options
|
|
|
|
:= close-statement-options-1
|
|
|
|
:= close-statement-options-2)
|
|
|
|
|
|
|
|
(defrule close-statement-file-name
|
|
|
|
:= file-name close-statement-options?)
|
|
|
|
|
|
|
|
(defrule compute-statement
|
|
|
|
:= "COMPUTE" cobword-rounded+ equal arithmetic-expression on-size-error-statement-list? not-on-size-error-statement-list? "END-COMPUTE"?
|
|
|
|
:reduce (list 'compute cobword-rounded arithmetic-expression :on-size-error on-size-error-statement-list
|
2022-01-19 14:39:58 +01:00
|
|
|
:not-on-size-error not-on-size-error-statement-list))
|
2021-08-21 14:44:37 +02:00
|
|
|
|
|
|
|
(defrule equal
|
|
|
|
:= "="
|
|
|
|
:= "EQUAL")
|
|
|
|
|
|
|
|
(defrule continue-statement
|
|
|
|
:= "CONTINUE")
|
|
|
|
|
|
|
|
(defrule delete-statement
|
|
|
|
:= "DELETE" file-name "RECORD"? invalid-key-statement-list? not-invalid-key-statement-list? "END-DELETE"?
|
|
|
|
:reduce (list 'delete file-name :invalid invalid-key-statement-list :not-invalid not-invalid-key-statement-list))
|
|
|
|
|
|
|
|
(defrule display-statement
|
|
|
|
:= "DISPLAY" id-or-lit+ upon-environment-name? with-no-advancing?
|
|
|
|
:reduce (list 'display (cons 'list id-or-lit) :upon upon-environment-name :advance (not with-no-advancing))
|
|
|
|
:= "DISPLAY" id-or-lit "AT" screen-coordinates
|
|
|
|
:reduce (apply #'list 'display-at id-or-lit screen-coordinates))
|
|
|
|
|
|
|
|
(defrule screen-coordinates
|
|
|
|
:= integer
|
|
|
|
:reduce (multiple-value-list (truncate integer 100)))
|
|
|
|
|
|
|
|
(defrule upon-environment-name
|
|
|
|
:= "UPON" cobol-identifier)
|
|
|
|
|
|
|
|
(defrule with-no-advancing
|
|
|
|
:= "WITH"? "NO" "ADVANCING")
|
|
|
|
|
|
|
|
(defrule divide-statement
|
|
|
|
:= "DIVIDE" id-or-lit "INTO" id-or-lit "GIVING" variable-identifier "ROUNDED"? "REMAINDER" variable-identifier on-size-error-statement-list? not-on-size-error-statement-list? "END-DIVIDE"?
|
|
|
|
:= "DIVIDE" id-or-lit "BY" id-or-lit "GIVING" variable-identifier "ROUNDED"? "REMAINDER" variable-identifier on-size-error-statement-list? not-on-size-error-statement-list? "END-DIVIDE"?
|
|
|
|
:= "DIVIDE" id-or-lit "INTO" id-or-lit "GIVING" cobword-rounded+ on-size-error-statement-list? not-on-size-error-statement-list? "END-DIVIDE"?
|
|
|
|
:= "DIVIDE" id-or-lit "BY" id-or-lit "GIVING" cobword-rounded+ on-size-error-statement-list? not-on-size-error-statement-list? "END-DIVIDE"?
|
|
|
|
:= "DIVIDE" id-or-lit "INTO" cobword-rounded+ on-size-error-statement-list? not-on-size-error-statement-list? "END-DIVIDE"?)
|
|
|
|
|
|
|
|
(defrule entry-statement
|
|
|
|
:= "ENTRY" literal using-phrase?)
|
|
|
|
|
|
|
|
(defrule evaluate-statement
|
|
|
|
:= "EVALUATE" evaluate-condition also-phrase* when-phrases+ when-other-phrase? "END-EVALUATE"?)
|
|
|
|
|
|
|
|
(defrule evaluate-condition
|
|
|
|
:= condition
|
|
|
|
:= "TRUE"
|
|
|
|
:= "FALSE")
|
|
|
|
|
|
|
|
(defrule also-phrase
|
|
|
|
:= "ALSO" evaluate-condition)
|
|
|
|
|
|
|
|
(defrule when-phrase-also-phrase
|
|
|
|
:= "ALSO" evaluate-phrase)
|
|
|
|
|
|
|
|
(defrule when-phrase
|
|
|
|
:= "WHEN" evaluate-phrase when-phrase-also-phrase*)
|
|
|
|
|
|
|
|
(defrule when-phrases
|
|
|
|
:= when-phrase+ statement-list)
|
|
|
|
|
|
|
|
(defrule when-other-phrase
|
|
|
|
:= "WHEN" "OTHER" statement-list)
|
|
|
|
|
|
|
|
(defrule evaluate-phrase
|
|
|
|
:= "ANY"
|
|
|
|
:= condition
|
|
|
|
:= "TRUE"
|
|
|
|
:= "FALSE"
|
|
|
|
:= evaluate-phrase-1)
|
|
|
|
|
|
|
|
(defrule evaluate-phrase-1
|
|
|
|
:= "NOT"? arithmetic-expression through-arithmetic-expression?)
|
|
|
|
|
|
|
|
(defrule through-arithmetic-expression
|
|
|
|
:= through arithmetic-expression)
|
|
|
|
|
|
|
|
(defrule exit-statement
|
|
|
|
:= "EXIT"
|
|
|
|
:reduce '(exit-paragraph))
|
|
|
|
|
|
|
|
(defrule exit-program-statement
|
|
|
|
:= "EXIT" "PROGRAM"
|
|
|
|
:reduce '(exit-program))
|
|
|
|
|
|
|
|
(defrule goback-statement
|
|
|
|
:= "GOBACK"
|
|
|
|
:reduce '(go-back))
|
|
|
|
|
|
|
|
(defrule go-to-statement
|
|
|
|
:= "GO" "TO"? procedure-name+ "DEPENDING" "ON"? variable-identifier
|
|
|
|
:reduce (list 'goto-depending variable-identifier procedure-name)
|
|
|
|
:= "GO" "TO"? procedure-name
|
|
|
|
:reduce (list 'goto procedure-name))
|
|
|
|
|
|
|
|
(defrule if-phrase
|
|
|
|
:= "IF" condition "THEN"? alt-statement-list-next-sentence "ELSE" alt-statement-list-next-sentence
|
|
|
|
:reduce (list 'if condition
|
2022-01-19 14:39:58 +01:00
|
|
|
(if (cdr alt-statement-list-next-sentence)
|
|
|
|
(cons 'progn alt-statement-list-next-sentence)
|
|
|
|
(car alt-statement-list-next-sentence))
|
|
|
|
(if (cdr alt-statement-list-next-sentence2)
|
|
|
|
(cons 'progn alt-statement-list-next-sentence2)
|
|
|
|
(car alt-statement-list-next-sentence2)))
|
2021-08-21 14:44:37 +02:00
|
|
|
:= "IF" condition "THEN"? alt-statement-list-next-sentence
|
|
|
|
:reduce (append (list 'when condition) alt-statement-list-next-sentence))
|
|
|
|
|
|
|
|
(defrule if-statement
|
|
|
|
:= if-phrase "END-IF"?
|
|
|
|
:reduce $1)
|
|
|
|
|
|
|
|
(defrule initialize-statement
|
|
|
|
:= "INITIALIZE" variable-identifier+ initialize-replacing-phrase?)
|
|
|
|
|
|
|
|
(defrule initialize-replacing-type
|
|
|
|
:= "ALPHABETIC"
|
|
|
|
:= "ALPHANUMERIC"
|
|
|
|
:= "NUMERIC"
|
|
|
|
:= "ALPHANUMERIC-EDITED"
|
|
|
|
:= "NUMERIC-EDITED"
|
|
|
|
:= "DBCS"
|
|
|
|
:= "EGCS")
|
|
|
|
|
|
|
|
(defrule initialize-replacing-argument
|
|
|
|
:= initialize-replacing-type "DATA"? "BY" id-or-lit)
|
|
|
|
|
|
|
|
(defrule initialize-replacing-phrase
|
|
|
|
:= "REPLACING" initialize-replacing-argument+)
|
|
|
|
|
|
|
|
(defrule inspect-statement
|
|
|
|
:= inspect-statement-1
|
|
|
|
:= inspect-statement-2
|
|
|
|
:= inspect-statement-3
|
|
|
|
:= inspect-statement-4)
|
|
|
|
|
|
|
|
(defrule inspect-statement-1
|
|
|
|
:= "INSPECT" variable-identifier "TALLYING" tallying-argument+)
|
|
|
|
|
|
|
|
(defrule inspect-statement-2
|
|
|
|
:= "INSPECT" variable-identifier "CONVERTING" id-or-lit "TO" id-or-lit before-after-phrase*)
|
|
|
|
|
|
|
|
(defrule inspect-statement-3
|
|
|
|
:= "INSPECT" variable-identifier "TALLYING" tallying-argument+ "REPLACING" inspect-replacing-phrase+)
|
|
|
|
|
|
|
|
(defrule tallying-for-id-or-lit
|
|
|
|
:= id-or-lit before-after-phrase*)
|
|
|
|
|
|
|
|
(defrule alt-all-leading
|
|
|
|
:= "ALL"
|
|
|
|
:= "LEADING")
|
|
|
|
|
|
|
|
(defrule tallying-for-argument-1
|
|
|
|
:= "CHARACTERS" before-after-phrase*)
|
|
|
|
|
|
|
|
(defrule tallying-for-argument-2
|
|
|
|
:= alt-all-leading tallying-for-id-or-lit+)
|
|
|
|
|
|
|
|
(defrule tallying-for-argument
|
|
|
|
:= tallying-for-argument-1
|
|
|
|
:= tallying-for-argument-2)
|
|
|
|
|
|
|
|
(defrule tallying-argument
|
|
|
|
:= variable-identifier "FOR" tallying-for-argument+)
|
|
|
|
|
|
|
|
(defrule inspect-statement-4
|
|
|
|
:= "INSPECT" variable-identifier "REPLACING" inspect-replacing-phrase+)
|
|
|
|
|
|
|
|
(defrule inspect-replacing-argument
|
|
|
|
:= inspect-by-argument "BY" inspect-by-argument before-after-phrase*)
|
|
|
|
|
|
|
|
(defrule alt-all-leading-first
|
|
|
|
:= "ALL"
|
|
|
|
:= "LEADING"
|
|
|
|
:= "FIRST")
|
|
|
|
|
|
|
|
(defrule inspect-replacing-phrase-1
|
|
|
|
:= "CHARACTERS" "BY" id-or-lit before-after-phrase*)
|
|
|
|
|
|
|
|
(defrule inspect-replacing-phrase-2
|
|
|
|
:= alt-all-leading-first inspect-replacing-argument+)
|
|
|
|
|
|
|
|
(defrule inspect-replacing-phrase
|
|
|
|
:= inspect-replacing-phrase-1
|
|
|
|
:= inspect-replacing-phrase-2)
|
|
|
|
|
|
|
|
(defrule before-after-phrase
|
|
|
|
:= alt-before-after "INITIAL"? id-or-lit)
|
|
|
|
|
|
|
|
(defrule merge-statement
|
|
|
|
:= "MERGE" file-name on-key-phrase+ collating-sequence? "USING" file-name file-name+ merge-statement-tail)
|
|
|
|
|
|
|
|
(defrule on-key-phrase
|
|
|
|
:= "ON"? alt-ascending-descending "KEY"? qualified-data-name+)
|
|
|
|
|
|
|
|
(defrule merge-statement-tail
|
|
|
|
:= output-procedure
|
|
|
|
:= giving-file-names)
|
|
|
|
|
|
|
|
(defrule move-statement
|
|
|
|
:= "MOVE" id-or-lit "TO" variable-identifier+
|
|
|
|
:reduce (apply #'list 'move id-or-lit variable-identifier)
|
|
|
|
:= "MOVE" corresponding variable-identifier "TO" variable-identifier+
|
|
|
|
:reduce (apply #'list 'move-corresponding variable-identifier variable-identifier2))
|
|
|
|
|
|
|
|
(defrule multiply-statement
|
|
|
|
:= "MULTIPLY" id-or-lit "BY" cobword-rounded+ on-size-error-statement-list? not-on-size-error-statement-list? "END-MULTIPLY"?
|
|
|
|
:reduce (list 'multiply id-or-lit cobword-rounded :on-size-error on-size-error-statement-list
|
2022-01-19 14:39:58 +01:00
|
|
|
:not-on-size-error not-on-size-error-statement-list)
|
2021-08-21 14:44:37 +02:00
|
|
|
:= "MULTIPLY" id-or-lit "BY" id-or-lit "GIVING" cobword-rounded+ on-size-error-statement-list? not-on-size-error-statement-list? "END-MULTIPLY"?
|
|
|
|
:reduce (list 'multiply id-or-lit id-or-lit2 :giving cobword-rounded
|
2022-01-19 14:39:58 +01:00
|
|
|
:on-size-error on-size-error-statement-list
|
|
|
|
:not-on-size-error not-on-size-error-statement-list))
|
2021-08-21 14:44:37 +02:00
|
|
|
|
|
|
|
(defrule open-statement
|
|
|
|
:= "OPEN" open-statement-phrase+
|
|
|
|
:reduce (list 'open open-statement-phrase))
|
|
|
|
|
|
|
|
(defrule alt-reversed-with-no-rewind
|
|
|
|
:= "REVERSED"
|
|
|
|
:= with-no-rewind)
|
|
|
|
|
|
|
|
(defrule open-statement-input-file-name
|
|
|
|
:= file-name alt-reversed-with-no-rewind?)
|
|
|
|
|
|
|
|
(defrule with-no-rewind
|
|
|
|
:= "WITH"? "NO" "REWIND")
|
|
|
|
|
|
|
|
(defrule open-statement-output-file-name
|
|
|
|
:= file-name with-no-rewind?)
|
|
|
|
|
|
|
|
(defrule open-statement-input
|
|
|
|
:= "INPUT" open-statement-input-file-name+)
|
|
|
|
|
|
|
|
(defrule open-statement-output
|
|
|
|
:= "OUTPUT" open-statement-output-file-name+)
|
|
|
|
|
|
|
|
(defrule open-statement-i-o
|
|
|
|
:= "I-O" file-name+)
|
|
|
|
|
|
|
|
(defrule open-statement-extend
|
|
|
|
:= "EXTEND" file-name+)
|
|
|
|
|
|
|
|
(defrule open-statement-phrase
|
|
|
|
:= open-statement-input
|
|
|
|
:= open-statement-output
|
|
|
|
:= open-statement-i-o
|
|
|
|
:= open-statement-extend)
|
|
|
|
|
|
|
|
(defrule perform-statement
|
|
|
|
:= "PERFORM" procedure-name through-procedure-name? perform-until-phrase
|
|
|
|
:reduce `(perform-until ,procedure-name ,through-procedure-name ,perform-until-phrase)
|
|
|
|
:= "PERFORM" procedure-name through-procedure-name? perform-varying-phrase perform-after-phrase*
|
|
|
|
:reduce `(perform-varying ,perform-varying-phrase ,procedure-name ,through-procedure-name ,perform-after-phrase)
|
|
|
|
:= "PERFORM" procedure-name through-procedure-name? cobword-int "TIMES"
|
|
|
|
:reduce `(perform-times ,cobword-int ,procedure-name ,through-procedure-name)
|
|
|
|
:= "PERFORM" procedure-name through-procedure-name?
|
|
|
|
:reduce (append (list 'perform procedure-name) through-procedure-name))
|
|
|
|
|
|
|
|
(defrule perform-varying-phrase
|
|
|
|
:= with-test? "VARYING" variable-identifier "FROM" id-or-lit "BY" id-or-lit "UNTIL" condition)
|
|
|
|
|
|
|
|
(defrule perform-after-phrase
|
|
|
|
:= "AFTER" variable-identifier "FROM" id-or-lit "BY" id-or-lit "UNTIL" condition)
|
|
|
|
|
|
|
|
(defrule perform-until-phrase
|
|
|
|
:= with-test? "UNTIL" condition)
|
|
|
|
|
|
|
|
(defrule with-test
|
|
|
|
:= "WITH"? "TEST" alt-before-after
|
|
|
|
:reduce alt-before-after)
|
|
|
|
|
|
|
|
(defrule read-statement
|
|
|
|
:= "READ" file-name "NEXT"? "RECORD"? into-identifier? key-is-qualified-data-name? invalid-key-statement-list? not-invalid-key-statement-list? at-end-statement-list? not-at-end-statement-list? "END-READ"?)
|
|
|
|
|
|
|
|
(defrule key-is-qualified-data-name
|
|
|
|
:= "KEY" "IS"? qualified-data-name)
|
|
|
|
|
|
|
|
(defrule release-statement
|
|
|
|
:= "RELEASE" record-name from-identifier?)
|
|
|
|
|
|
|
|
(defrule return-statement
|
|
|
|
:= "RETURN" file-name "RECORD"? into-identifier? "AT"? "END" statement-list not-at-end-statement-list? "END-RETURN"?)
|
|
|
|
|
|
|
|
(defrule into-identifier
|
|
|
|
:= "INTO" variable-identifier)
|
|
|
|
|
|
|
|
(defrule not-at-end-statement-list
|
|
|
|
:= "NOT" "AT"? "END" statement-list)
|
|
|
|
|
|
|
|
(defrule rewrite-statement
|
|
|
|
:= "REWRITE" record-name from-identifier? invalid-key-statement-list? not-invalid-key-statement-list? "END-REWRITE"?)
|
|
|
|
|
|
|
|
(defrule search-statement
|
|
|
|
:= search-statement-1
|
|
|
|
:= search-statement-2)
|
|
|
|
|
|
|
|
(defrule search-statement-1
|
|
|
|
:= "SEARCH" cobol-identifier varying-identifier? at-end-statement-list? when-condition-stats+ "END-SEARCH"?)
|
|
|
|
|
|
|
|
(defrule varying-identifier
|
|
|
|
:= "VARYING" variable-identifier)
|
|
|
|
|
|
|
|
(defrule when-condition-stats
|
|
|
|
:= "WHEN" condition alt-statement-list-next-sentence)
|
|
|
|
|
|
|
|
(defrule search-statement-2
|
|
|
|
:= "SEARCH" "ALL" variable-identifier at-end-statement-list? "WHEN" search-statement-condition search-statement-condition-tail* alt-statement-list-next-sentence "END-SEARCH"?)
|
|
|
|
|
|
|
|
(defrule at-end-statement-list
|
|
|
|
:= "AT"? "END" statement-list)
|
|
|
|
|
|
|
|
(defrule search-statement-equal-expression
|
|
|
|
:= variable-identifier "IS"? equal-to arithmetic-expression
|
|
|
|
:reduce (list '= variable-identifier arithmetic-expression))
|
|
|
|
|
|
|
|
(defrule search-statement-condition
|
|
|
|
:= search-statement-equal-expression
|
|
|
|
:= condition-name-reference)
|
|
|
|
|
|
|
|
(defrule search-statement-condition-tail
|
|
|
|
:= "AND" search-statement-condition)
|
|
|
|
|
|
|
|
(defrule alt-statement-list-next-sentence
|
|
|
|
:= statement+
|
|
|
|
:= next-sentence
|
|
|
|
:reduce :next-sentence)
|
|
|
|
|
|
|
|
(defrule set-statement
|
|
|
|
:= "SET" set-statement-phrase+)
|
|
|
|
|
|
|
|
(defrule sort-statement
|
|
|
|
:= "SORT" file-name on-key-is-phrase+ with-duplicates-in-order? collating-sequence? sort-statement-in sort-statement-out)
|
|
|
|
|
|
|
|
(defrule key-is
|
|
|
|
:= "KEY" "IS"?)
|
|
|
|
|
|
|
|
(defrule alt-ascending-descending
|
|
|
|
:= "ASCENDING"
|
|
|
|
:= "DESCENDING")
|
|
|
|
|
|
|
|
(defrule on-key-is-phrase
|
|
|
|
:= "ON"? alt-ascending-descending key-is? qualified-data-name+)
|
|
|
|
|
|
|
|
(defrule with-duplicates-in-order
|
|
|
|
:= "WITH"? "DUPLICATES" "IN"? "ORDER"?)
|
|
|
|
|
|
|
|
(defrule collating-sequence
|
|
|
|
:= "COLLATING"? "SEQUENCE" "IS"? alphabet-name)
|
|
|
|
|
|
|
|
(defrule through
|
|
|
|
:= "THROUGH"
|
|
|
|
:= "THRU")
|
|
|
|
|
|
|
|
(defrule through-procedure-name
|
|
|
|
:= through procedure-name
|
|
|
|
:reduce procedure-name)
|
|
|
|
|
|
|
|
(defrule using-file-names
|
|
|
|
:= "USING" file-name+)
|
|
|
|
|
|
|
|
(defrule input-procedure
|
|
|
|
:= "INPUT" "PROCEDURE" "IS"? procedure-name through-procedure-name?)
|
|
|
|
|
|
|
|
(defrule giving-file-names
|
|
|
|
:= "GIVING" file-name+)
|
|
|
|
|
|
|
|
(defrule output-procedure
|
|
|
|
:= "OUTPUT" "PROCEDURE" "IS"? procedure-name through-procedure-name?)
|
|
|
|
|
|
|
|
(defrule sort-statement-in
|
|
|
|
:= using-file-names
|
|
|
|
:= input-procedure)
|
|
|
|
|
|
|
|
(defrule sort-statement-out
|
|
|
|
:= giving-file-names
|
|
|
|
:= output-procedure)
|
|
|
|
|
|
|
|
(defrule start-statement
|
|
|
|
:= "START" file-name key-is-rel-op-qualified-data-name? invalid-key-statement-list? not-invalid-key-statement-list? "END-START"?)
|
|
|
|
|
|
|
|
(defrule rel-op
|
|
|
|
:= equal-to
|
|
|
|
:reduce '=
|
|
|
|
:= greater-than
|
|
|
|
:reduce '>
|
|
|
|
:= greater-equal
|
|
|
|
:reduce '>=)
|
|
|
|
|
|
|
|
(defrule key-is-rel-op-qualified-data-name
|
|
|
|
:= "KEY" "IS"? rel-op qualified-data-name
|
|
|
|
:reduce (list rel-op qualified-data-name))
|
|
|
|
|
|
|
|
(defrule stop-statement
|
|
|
|
:= "STOP" alt-run-literal
|
|
|
|
:reduce '(stop))
|
|
|
|
|
|
|
|
(defrule alt-run-literal
|
|
|
|
:= "RUN"
|
|
|
|
:= literal)
|
|
|
|
|
|
|
|
(defrule string-statement
|
|
|
|
:= "STRING" delimited-by-phrase+ "INTO" variable-identifier with-pointer-identifier? on-overflow-statement-list? not-on-overflow-statement-list? "END-STRING"?
|
|
|
|
:reduce (list 'string-concat delimited-by-phrase variable-identifier :with-pointer with-pointer-identifier :on-overflow on-overflow-statement-list :not-on-overflow not-on-overflow-statement-list))
|
|
|
|
|
|
|
|
(defrule id-or-lit-size
|
|
|
|
:= literal
|
|
|
|
:= variable-identifier
|
|
|
|
:= "SIZE")
|
|
|
|
|
|
|
|
(defrule delimited-by-phrase
|
|
|
|
:= id-or-lit+ "DELIMITED" "BY"? id-or-lit-size
|
|
|
|
:reduce (list id-or-lit id-or-lit-size))
|
|
|
|
|
|
|
|
(defrule subtract-statement
|
|
|
|
:= "SUBTRACT" id-or-lit+ "FROM" id-or-lit "GIVING" cobword-rounded+ on-size-error-statement-list? not-on-size-error-statement-list? "END-SUBTRACT"?
|
|
|
|
:reduce (list 'subtract-giving id-or-lit id-or-lit2 cobword-rounded
|
2022-01-19 14:39:58 +01:00
|
|
|
:on-size-error on-size-error-statement-list
|
|
|
|
:not-on-size-error not-on-size-error-statement-list)
|
2021-08-21 14:44:37 +02:00
|
|
|
:= "SUBTRACT" id-or-lit+ "FROM" cobword-rounded+ on-size-error-statement-list? not-on-size-error-statement-list? "END-SUBTRACT"?
|
|
|
|
:reduce (list 'subtract id-or-lit cobword-rounded
|
2022-01-19 14:39:58 +01:00
|
|
|
:on-size-error on-size-error-statement-list
|
|
|
|
:not-on-size-error not-on-size-error-statement-list)
|
2021-08-21 14:44:37 +02:00
|
|
|
:= "SUBTRACT" corresponding variable-identifier "FROM" variable-identifier "ROUNDED"? on-size-error-statement-list? not-on-size-error-statement-list? "END-SUBTRACT"?
|
|
|
|
:reduce (list 'subtract-corr variable-identifier variable-identifier
|
2022-01-19 14:39:58 +01:00
|
|
|
:rounded (and $5 t)
|
|
|
|
:on-size-error on-size-error-statement-list
|
|
|
|
:not-on-size-error not-on-size-error-statement-list))
|
2021-08-21 14:44:37 +02:00
|
|
|
|
|
|
|
(defrule cobword-rounded
|
|
|
|
:= variable-identifier "ROUNDED"?
|
|
|
|
:reduce (list variable-identifier (and $2 t)))
|
|
|
|
|
|
|
|
(defrule on-size-error-statement-list
|
|
|
|
:= "ON"? "SIZE" "ERROR" statement-list
|
|
|
|
:reduce statement-list)
|
|
|
|
|
|
|
|
(defrule not-on-size-error-statement-list
|
|
|
|
:= "NOT" "ON"? "SIZE" "ERROR" statement-list
|
|
|
|
:reduce statement-list)
|
|
|
|
|
|
|
|
(defrule corresponding
|
|
|
|
:= "CORRESPONDING"
|
|
|
|
:= "CORR")
|
|
|
|
|
|
|
|
(defrule unstring-statement
|
|
|
|
:= "UNSTRING" variable-identifier delimited-by-all-phrase? "INTO" unstring-statement-dst+ with-pointer-identifier? tallying-in-identifier? on-overflow-statement-list? not-on-overflow-statement-list? "END-UNSTRING"?
|
|
|
|
:reduce (list 'unstring variable-identifier unstring-statement-dst
|
2022-01-19 14:39:58 +01:00
|
|
|
:delimited-by-all delimited-by-all-phrase
|
|
|
|
:with-pointer with-pointer-identifier
|
|
|
|
:tallying tallying-in-identifier
|
|
|
|
:on-overflow on-overflow-statement-list
|
|
|
|
:not-on-overflow not-on-overflow-statement-list))
|
2021-08-21 14:44:37 +02:00
|
|
|
|
|
|
|
(defrule id-or-lit
|
|
|
|
:= literal
|
|
|
|
:= variable-identifier)
|
|
|
|
|
|
|
|
(defrule or-all-id-or-lit
|
|
|
|
:= "OR" "ALL"? id-or-lit)
|
|
|
|
|
|
|
|
(defrule delimited-by-all-phrase
|
|
|
|
:= "DELIMITED" "BY"? "ALL"? id-or-lit or-all-id-or-lit*)
|
|
|
|
|
|
|
|
(defrule delimiter-in-identifier
|
|
|
|
:= "DELIMITER" "IN"? variable-identifier)
|
|
|
|
|
|
|
|
(defrule count-in-identifier
|
|
|
|
:= "COUNT" "IN"? variable-identifier)
|
|
|
|
|
|
|
|
(defrule unstring-statement-dst
|
|
|
|
:= variable-identifier delimiter-in-identifier? count-in-identifier?)
|
|
|
|
|
|
|
|
(defrule with-pointer-identifier
|
|
|
|
:= "WITH"? "POINTER" variable-identifier)
|
|
|
|
|
|
|
|
(defrule tallying-in-identifier
|
|
|
|
:= "TALLYING" "IN"? variable-identifier)
|
|
|
|
|
|
|
|
(defrule on-overflow-statement-list
|
|
|
|
:= "ON"? "OVERFLOW" statement-list)
|
|
|
|
|
|
|
|
(defrule not-on-overflow-statement-list
|
|
|
|
:= "NOT" "ON"? "OVERFLOW" statement-list)
|
|
|
|
|
|
|
|
(defrule write-statement
|
|
|
|
:= "WRITE" record-name from-identifier? advancing-phrase? write-exceptions "END-WRITE"?)
|
|
|
|
|
|
|
|
(defrule lines
|
|
|
|
:= "LINE"
|
|
|
|
:= "LINES")
|
|
|
|
|
|
|
|
(defrule cobword-int
|
|
|
|
:= cobol-identifier
|
|
|
|
:= integer)
|
|
|
|
|
|
|
|
(defrule nr-lines-phrase
|
|
|
|
:= cobword-int lines?)
|
|
|
|
|
|
|
|
(defrule page-phrase
|
|
|
|
:= nr-lines-phrase
|
|
|
|
:= "PAGE")
|
|
|
|
|
|
|
|
(defrule alt-before-after
|
|
|
|
:= "BEFORE"
|
|
|
|
:= "AFTER")
|
|
|
|
|
|
|
|
(defrule advancing-phrase
|
|
|
|
:= alt-before-after "ADVANCING"? page-phrase)
|
|
|
|
|
|
|
|
(defrule from-identifier
|
|
|
|
:= "FROM" variable-identifier)
|
|
|
|
|
|
|
|
(defrule invalid-key-statement-list
|
|
|
|
:= "INVALID" "KEY"? statement-list
|
|
|
|
:reduce statement-list)
|
|
|
|
|
|
|
|
(defrule not-invalid-key-statement-list
|
|
|
|
:= "NOT" "INVALID" "KEY"? statement-list
|
|
|
|
:reduce statement-list)
|
|
|
|
|
|
|
|
(defrule end-of-page
|
|
|
|
:= "END-OF-PAGE"
|
|
|
|
:= "EOP")
|
|
|
|
|
|
|
|
(defrule at-end-of-page-statement-list
|
|
|
|
:= "AT"? end-of-page statement-list
|
|
|
|
:reduce statement-list)
|
|
|
|
|
|
|
|
(defrule not-at-end-of-page-statement-list
|
|
|
|
:= "NOT" "AT"? end-of-page statement-list
|
|
|
|
:reduce statement-list)
|
|
|
|
|
|
|
|
;; This is left in the grammar but is not used. COPYs are handled by
|
|
|
|
;; the lexical scanner.
|
|
|
|
(defrule copy-statement
|
|
|
|
:= "COPY" alt-text-name-literal in-library? "SUPPRESS"? copy-statement-replacing-phrase?)
|
|
|
|
|
|
|
|
(defrule in
|
|
|
|
:= "OF"
|
|
|
|
:= "IN")
|
|
|
|
|
|
|
|
(defrule alt-library-name-literal
|
|
|
|
:= library-name
|
|
|
|
:= literal)
|
|
|
|
|
|
|
|
(defrule in-library
|
|
|
|
:= in alt-library-name-literal)
|
|
|
|
|
|
|
|
(defrule copy-statement-by-phrase
|
|
|
|
:= copy-operand "BY" copy-operand)
|
|
|
|
|
|
|
|
(defrule copy-statement-replacing-phrase
|
|
|
|
:= "REPLACING" copy-statement-by-phrase+)
|
|
|
|
|
|
|
|
(defrule alt-text-name-literal
|
|
|
|
:= text-name
|
|
|
|
:= literal)
|
|
|
|
|
|
|
|
(defrule copy-operand
|
|
|
|
:= cobol-identifier
|
|
|
|
:= literal)
|
|
|
|
|
|
|
|
(defrule use-statement
|
|
|
|
:= use-statement-1
|
|
|
|
:= use-statement-2
|
|
|
|
:= use-statement-3)
|
|
|
|
|
|
|
|
(defrule use-statement-1
|
|
|
|
:= "USE" "GLOBAL"? "AFTER" "STANDARD"? alt-exception-error "PROCEDURE" "ON"? alt-file-names-i-o)
|
|
|
|
|
|
|
|
(defrule alt-exception-error
|
|
|
|
:= "EXCEPTION"
|
|
|
|
:= "ERROR")
|
|
|
|
|
|
|
|
(defrule use-statement-2
|
|
|
|
:= "USE" "GLOBAL"? "AFTER" "STANDARD"? alt-beginning-ending? alt-file-reel-unit? "LABEL" "PROCEDURE" "ON"? alt-file-names-i-o)
|
|
|
|
|
|
|
|
(defrule alt-beginning-ending
|
|
|
|
:= "BEGINNING"
|
|
|
|
:= "ENDING")
|
|
|
|
|
|
|
|
(defrule alt-file-reel-unit
|
|
|
|
:= "FILE"
|
|
|
|
:= "REEL"
|
|
|
|
:= "UNIT")
|
|
|
|
|
|
|
|
(defrule file-names
|
|
|
|
:= file-name+)
|
|
|
|
|
|
|
|
(defrule alt-file-names-i-o
|
|
|
|
:= file-names
|
|
|
|
:= "INPUT"
|
|
|
|
:= "OUTPUT"
|
|
|
|
:= "I-O"
|
|
|
|
:= "EXTEND")
|
|
|
|
|
|
|
|
(defrule use-statement-3
|
|
|
|
:= "USE" "FOR"? "DEBUGGING" "ON"? alt-procedures-all-procedures)
|
|
|
|
|
|
|
|
(defrule procedure-names
|
|
|
|
:= procedure-name+)
|
|
|
|
|
|
|
|
(defrule alt-procedures-all-procedures
|
|
|
|
:= procedure-names
|
|
|
|
:= all-procedures)
|
|
|
|
|
|
|
|
(defrule condition
|
|
|
|
:= combinable-condition
|
|
|
|
:= combinable-condition "AND" condition
|
|
|
|
:reduce `(and ,combinable-condition ,condition)
|
|
|
|
:= combinable-condition "OR" condition
|
|
|
|
:reduce `(or ,combinable-condition ,condition)
|
|
|
|
:= combinable-condition "AND" id-or-lit
|
|
|
|
:reduce `(and ,combinable-condition (,(car combinable-condition) ,(cadr combinable-condition) ,id-or-lit))
|
|
|
|
:= combinable-condition "OR" id-or-lit
|
|
|
|
:reduce `(or ,combinable-condition (,(car combinable-condition) ,(cadr combinable-condition) ,id-or-lit)))
|
|
|
|
|
|
|
|
(defrule combinable-condition
|
|
|
|
:= "NOT"? simple-condition
|
|
|
|
:reduce (if $1
|
2022-01-19 14:39:58 +01:00
|
|
|
(list 'not simple-condition)
|
|
|
|
simple-condition))
|
2021-08-21 14:44:37 +02:00
|
|
|
|
|
|
|
(defrule simple-condition
|
|
|
|
:= class-condition
|
|
|
|
:= relation-condition
|
|
|
|
:= sign-condition
|
|
|
|
:= "(" condition ")"
|
|
|
|
;; not sure if it's necessary -wcp15/7/03.
|
|
|
|
;; := arithmetic-expression
|
|
|
|
)
|
|
|
|
|
|
|
|
(defrule class-condition
|
|
|
|
:= variable-identifier "IS"? "NOT"? class-type
|
|
|
|
:reduce (if $3
|
2022-01-19 14:39:58 +01:00
|
|
|
(list 'not (list 'type-of variable-identifier (make-keyword class-type)))
|
|
|
|
(list 'type-of variable-identifier (make-keyword class-type))))
|
2021-08-21 14:44:37 +02:00
|
|
|
|
|
|
|
(defrule class-type
|
|
|
|
:= "NUMERIC"
|
|
|
|
:= "ALPHABETIC"
|
|
|
|
:= "ALPHABETIC-LOWER"
|
|
|
|
:= "ALPHABETIC-UPPER"
|
|
|
|
:= "DBCS")
|
|
|
|
|
|
|
|
(defun unfold-subrelations (main-relation subs)
|
|
|
|
(destructuring-bind (main-operator main-variable other-variable) main-relation
|
|
|
|
(declare (ignore other-variable))
|
|
|
|
(labels ((unfold (subs)
|
2022-01-19 14:39:58 +01:00
|
|
|
(if (null subs)
|
|
|
|
main-relation
|
|
|
|
(destructuring-bind (connection operator variable) (car subs)
|
|
|
|
(list connection
|
|
|
|
(list (or operator main-operator) main-variable variable)
|
|
|
|
(unfold (cdr subs)))))))
|
2021-08-21 14:44:37 +02:00
|
|
|
(unfold subs))))
|
|
|
|
|
|
|
|
(defrule relation-condition
|
|
|
|
;; This is too complex
|
|
|
|
;; := arithmetic-expression relational-operator simple-condition
|
|
|
|
:= id-or-lit relational-operator id-or-lit subordinate-relation*
|
|
|
|
:reduce (unfold-subrelations (list relational-operator id-or-lit id-or-lit2) subordinate-relation))
|
|
|
|
|
|
|
|
(defrule or-and
|
|
|
|
:= "OR" :reduce 'or
|
|
|
|
:= "AND" :reduce 'and)
|
|
|
|
|
|
|
|
(defrule subordinate-relation
|
|
|
|
:= or-and relational-operator? id-or-lit
|
|
|
|
:reduce (list or-and relational-operator id-or-lit))
|
|
|
|
|
|
|
|
(defrule relational-operator
|
|
|
|
:= "IS"? relational-operator-type
|
|
|
|
:reduce relational-operator-type)
|
|
|
|
|
|
|
|
(defrule less-than
|
|
|
|
:= "LESS" "THAN"?
|
|
|
|
:= "<")
|
|
|
|
|
|
|
|
(defrule greater-equal
|
|
|
|
:= "GREATER" "THAN"? "OR" "EQUAL" "TO"?
|
|
|
|
:= ">="
|
|
|
|
:= ">" "="
|
|
|
|
:= "NOT" "<"
|
|
|
|
:= "NOT" "LESS" "THAN"?)
|
|
|
|
|
|
|
|
(defrule less-equal
|
|
|
|
:= "LESS" "THAN"? "OR" "EQUAL" "TO"?
|
|
|
|
:= "<="
|
|
|
|
:= "<" "="
|
|
|
|
:= "NOT" ">"
|
|
|
|
:= "NOT" "GREATER" "THAN"?)
|
|
|
|
|
|
|
|
(defrule greater-than
|
|
|
|
:= "GREATER" "THAN"?
|
|
|
|
:= ">")
|
|
|
|
|
|
|
|
(defrule equal-to
|
|
|
|
:= "EQUAL" "TO"?
|
|
|
|
:= "=")
|
|
|
|
|
|
|
|
(defrule relational-operator-type
|
|
|
|
:= greater-equal
|
|
|
|
:reduce 'cob>=
|
|
|
|
:= less-equal
|
|
|
|
:reduce 'cob<=
|
|
|
|
:= greater-than
|
|
|
|
:reduce 'cob>
|
|
|
|
:= less-than
|
|
|
|
:reduce 'cob<
|
|
|
|
:= equal-to
|
|
|
|
:reduce 'cob=
|
|
|
|
:= "NOT" equal-to
|
|
|
|
:reduce 'cob-not=)
|
|
|
|
|
|
|
|
(defrule sign-condition
|
|
|
|
:= arithmetic-expression "IS"? "NOT"? sign-type
|
|
|
|
:reduce (if $3
|
2022-01-19 14:39:58 +01:00
|
|
|
`(not (,sign-type ,arithmetic-expression))
|
|
|
|
`(,sign-type ,arithmetic-expression)))
|
2021-08-21 14:44:37 +02:00
|
|
|
|
|
|
|
(defrule sign-type
|
|
|
|
:= "POSITIVE" :reduce '>
|
|
|
|
:= "NEGATIVE" :reduce '<
|
|
|
|
:= "ZERO" :reduce '=
|
|
|
|
:= "ZEROES" :reduce '=
|
|
|
|
:= "ZEROS" :reduce '=)
|
|
|
|
|
|
|
|
(defrule procedure-name
|
|
|
|
:= paragraph-or-section-name in-section-name
|
|
|
|
:reduce (list paragraph-or-section-name in-section-name)
|
|
|
|
:= paragraph-or-section-name
|
|
|
|
:reduce paragraph-or-section-name)
|
|
|
|
|
|
|
|
(defrule in-section-name
|
|
|
|
:= in cobol-identifier
|
|
|
|
:reduce cobol-identifier)
|
|
|
|
|
|
|
|
(defrule variable-identifier
|
|
|
|
:= qualified-data-name subscript-parentheses* ;; reference-modification?
|
|
|
|
:reduce (if subscript-parentheses
|
2022-01-19 14:39:58 +01:00
|
|
|
(list :aref qualified-data-name subscript-parentheses)
|
|
|
|
qualified-data-name))
|
2021-08-21 14:44:37 +02:00
|
|
|
|
|
|
|
(defrule reference-modification
|
|
|
|
:= "(" leftmost-character-position ":" length? ")"
|
|
|
|
:reduce (if length
|
2022-01-19 14:39:58 +01:00
|
|
|
(list :range leftmost-character-position length)
|
|
|
|
leftmost-character-position))
|
2021-08-21 14:44:37 +02:00
|
|
|
|
|
|
|
(defrule condition-name-reference
|
|
|
|
:= condition-name in-data-or-file-or-mnemonic-name* subscript-parentheses*)
|
|
|
|
|
|
|
|
(defrule in-data-or-file-or-mnemonic-name
|
|
|
|
:= in data-or-file-or-mnemonic-name)
|
|
|
|
|
|
|
|
(defrule subscript-parentheses
|
|
|
|
:= "(" subscript ")")
|
|
|
|
|
|
|
|
(defrule subscript
|
|
|
|
:= subscript-expression+)
|
|
|
|
|
|
|
|
(defrule plus-minus-integer
|
|
|
|
:= plus-or-minus integer)
|
|
|
|
|
|
|
|
(defrule subscript-expression-ambiguous
|
|
|
|
:= qualified-data-name plus-minus-integer?)
|
|
|
|
|
|
|
|
(defrule subscript-expression
|
|
|
|
:= literal
|
|
|
|
:= subscript-expression-ambiguous)
|
|
|
|
|
|
|
|
(defrule qualified-data-name
|
|
|
|
:= data-name in-data-or-file-name*
|
|
|
|
:reduce (if in-data-or-file-name
|
2022-01-19 14:39:58 +01:00
|
|
|
(list data-name in-data-or-file-name) ; incomplete -wcp15/7/03.
|
|
|
|
data-name)
|
2021-08-21 14:44:37 +02:00
|
|
|
:= "ADDRESS" "OF" data-name
|
|
|
|
:reduce (list 'address-of data-name)
|
|
|
|
:= "LENGTH" "OF" cobol-identifier
|
|
|
|
:reduce (list 'length-of cobol-identifier))
|
|
|
|
|
|
|
|
(defrule in-data-or-file-name
|
|
|
|
:= in data-or-file-name)
|
|
|
|
|
|
|
|
(defrule leftmost-character-position
|
|
|
|
:= arithmetic-expression)
|
|
|
|
|
|
|
|
(defrule length
|
|
|
|
:= arithmetic-expression)
|
|
|
|
|
|
|
|
(defrule arithmetic-expression
|
|
|
|
:= times-div
|
|
|
|
:= times-div "+" arithmetic-expression
|
|
|
|
:reduce `(+ ,times-div ,arithmetic-expression)
|
|
|
|
:= times-div "-" arithmetic-expression
|
|
|
|
:reduce `(- ,times-div ,arithmetic-expression))
|
|
|
|
|
|
|
|
(defrule times-div
|
|
|
|
:= power
|
|
|
|
:= power "*" times-div
|
|
|
|
:reduce `(* ,power ,times-div)
|
|
|
|
:= power "/" times-div
|
|
|
|
:reduce `(/ ,power ,times-div))
|
|
|
|
|
|
|
|
(defrule power
|
|
|
|
:= plus-or-minus? basis
|
|
|
|
:= plus-or-minus? basis "**" power
|
|
|
|
:reduce (if plus-or-minus
|
2022-01-19 14:39:58 +01:00
|
|
|
`(plus-or-minus (expt basis basis2))
|
|
|
|
`(expt basis basis2)))
|
2021-08-21 14:44:37 +02:00
|
|
|
|
|
|
|
(defrule plus-or-minus
|
|
|
|
:= "+"
|
|
|
|
:reduce '+
|
|
|
|
:= "-"
|
|
|
|
:reduce '-)
|
|
|
|
|
|
|
|
;; (defrule power-tail
|
|
|
|
;; := "**" basis)
|
|
|
|
|
|
|
|
(defrule basis
|
|
|
|
:= literal
|
|
|
|
:= variable-identifier
|
|
|
|
:= "(" arithmetic-expression ")")
|
|
|
|
|
|
|
|
(defrule alphabet-name
|
|
|
|
:= cobol-identifier)
|
|
|
|
|
|
|
|
(defrule condition-name
|
|
|
|
:= cobol-identifier)
|
|
|
|
|
|
|
|
(defrule data-name
|
|
|
|
:= cobol-identifier)
|
|
|
|
|
|
|
|
(defrule cobol-identifier
|
|
|
|
:= identifier
|
|
|
|
:reduce (intern (string-upcase identifier)))
|
|
|
|
|
|
|
|
(defrule file-name
|
|
|
|
:= cobol-identifier)
|
|
|
|
|
|
|
|
(defrule data-or-file-name
|
|
|
|
:= cobol-identifier)
|
|
|
|
|
|
|
|
(defrule index-name
|
|
|
|
:= cobol-identifier)
|
|
|
|
|
|
|
|
(defrule mnemonic-name
|
|
|
|
:= cobol-identifier)
|
|
|
|
|
|
|
|
(defrule data-or-file-or-mnemonic-name
|
|
|
|
:= cobol-identifier)
|
|
|
|
|
|
|
|
(defrule record-name
|
|
|
|
:= qualified-data-name)
|
|
|
|
|
|
|
|
(defrule symbolic-character
|
|
|
|
:= cobol-identifier)
|
|
|
|
|
|
|
|
(defrule library-name
|
|
|
|
:= cobol-identifier)
|
|
|
|
|
|
|
|
(defrule program-name
|
|
|
|
:= cobol-identifier
|
|
|
|
:= string)
|
|
|
|
|
|
|
|
(defrule text-name
|
|
|
|
:= cobol-identifier)
|
|
|
|
|
|
|
|
(defrule paragraph-or-section-name
|
|
|
|
:= cobol-identifier
|
|
|
|
:= integer)
|
|
|
|
|
|
|
|
(defrule computer-name
|
|
|
|
:= identifier)
|
|
|
|
|
|
|
|
(defrule environment-name
|
|
|
|
:= cobol-identifier)
|
|
|
|
|
|
|
|
(defrule assignment-name
|
|
|
|
:= cobol-identifier)
|
|
|
|
|
|
|
|
(defrule figurative-constant
|
|
|
|
:= figurative-constant-simple
|
|
|
|
:= figurative-constant-all)
|
|
|
|
|
|
|
|
(defrule figurative-constant-all
|
|
|
|
:= "ALL" literal)
|
|
|
|
|
|
|
|
(defrule literal
|
|
|
|
:= string
|
|
|
|
:= float
|
|
|
|
:= integer
|
|
|
|
:= figurative-constant)
|
|
|
|
|
|
|
|
) ; defun populate-grammar
|