تحياتي ، أيها الأصدقاء الأعزاء.
نواصل سلسلة المقالات التي تغطي أنشطة (العاصفة) لمنظمتنا غير الربحية.
كما هو موعود ، ننتقل من (تسجيل) بسيط إلى أكثر تعقيدًا: البرمجة التخطيطية.
ربطة عنق
حدث ذلك أن الشركة الأم (تقنية مالية كبيرة) بحاجة إلى الاندماج مع منظمة كبيرة أخرى باستخدام أجهزة الكمبيوتر المركزية و COBOL.
يبدو - ما هي الصعوبة ، وماذا يمكن أن تؤثر؟
والحقيقة هي أنه كوننا عبدا في هذا التكامل ، كان علينا دعم واجهات تبادل البيانات من الخارج. وهي ملفات البيانات الثنائية "ملفات بيانات كوبول".
كما اتضح (ولم تكن لدينا خبرة مع COBOL من قبل) ، فإن ملفات البيانات الموجودة بها تحتوي على بنية غير خطية . يسمى:
- يمكن تفسير كتلة واحدة ونفس البيانات على أنها "مجموعات" مختلفة (تنسيق البيانات في مصطلحات COBOL) ، وهو نوع من تعدد الأشكال للبيانات: التوجيه
redefines
. علاوة على ذلك ، مع جميع المجموعات المتداخلة ومجالاتها. - يمكن تكرار كتلة N مرات: التوجيه
occurs
- تذهب الكتل بالتسلسل ، ولكن يتم احتساب بدايتها من نهاية الكتلة السابقة - وفقًا لذلك ، لا يمكنك قراءة كتلة منفصلة دون قراءة الكتل السابقة.
كل هذا كان معقدًا بسبب حقيقة أن مواصفات الملف تمثل كود مصدر COBOL القابل للتنفيذ: "دفتر نسخ" (في قسم قسم البيانات) ، إلى جانب جميع خيارات بناء الجملة الممكنة لوصف تنسيق البيانات ، على سبيل المثال:
PIC X(06)V99
أو
PIC 9(06).9999999
أو
PIC 9(07)V9(07) COMP-3
أضف إلى هذا:
- تنسيق ثنائي صعب لتخزين أرقام IBM Computational 3
- ترميزات مختلفة (EBCDIC ، ASCII) - حتى بالنسبة لنوع واحد من الملفات (على Test و Prod)
- فواصل أسطر مختلفة (CR ، LF ، CRLF ، LFCR ، Newline ، ضمني بعد N بايت)
- دفاتر نسخ ضخمة من 400 مدخل مع مجموعة من الحقول
- Copbooks لها هيكل مع رأس ، سجل ، مقطورة ومجموعاتها
وهنا يصبح الأمر معًا مشكلة حقيقية: كيف ندعمها؟
بدأنا بالبحث عن الحلول الموجودة. وكانت النتيجة كارثية: من الحلول المجانية كانت فقط JRecord من 90s.
, — , - . , data picture
comp-3
.
, 2 :
, . — — :
, ? — 1 .
- , :
COBOL — Data Section Division
. , COBOL.
, -, COBOL ( Java) — MIT:
https://github.com/uwol/proleap-cobol-parser
, :
Antlr, meta-API Visitor. -.
visit e , Groovy , (data picture clause
):
@Override
@CompileDynamic
Boolean visitDataPictureClause(CobolParser.DataPictureClauseContext ctx) {
PictureClause entry = (PictureClause) program.getASGElementRegistry().getASGElement(ctx)
def (length, comp3length, scale) = calculateLengths(entry.pictureString)
write """ setDataPicture("""
write """ depth: ${currentFrame.depth},"""
write """ pictureString: "${entry.pictureString}","""
write """ length: ${length},"""
write """ comp3length: ${comp3length},"""
write """ scale: ${scale},"""
Boolean result = super.visitDataPictureClause(ctx)
write """ )"""
return result
}
, COBOL Groovy.
, copybook
.
Java , .
Closure Groovy — Closure COBOL.
, COBOL
(copybook):
000010 IDENTIFICATION DIVISION. XXXXXXXX
PROGRAM-ID. UnstringSample. XXXXXXXX
ENVIRONMENT DIVISION. XXXXXXXX
CONFIGURATION SECTION. XXXXXXXX
SPECIAL-NAMES. DECIMAL-POINT IS COMMA. XXXXXXXX
INPUT-OUTPUT SECTION. XXXXXXXX
DATA DIVISION. XXXXXXXX
WORKING-STORAGE SECTION. XXXXXXXX
01 ABCDE-RECORD. XXXXXXXX
XXXXXX 02 ABCDE-REC. XXXXXXXX
03 ABCDE-COMMON. XXXXXXXX
05 ABCDE-DETAILS. XXXXXXXX
10 ABCDE-RECORD-ABC. XXXXXXXX
15 ABCDE-PRI-ABC. XXXXXXXX
20 ABCDE-ABC-AAAAAAAA PIC X(02). XXXXXXXX
20 ABCDE-ABC-ACCT-ABCS. XXXXXXXX
25 ABCDE-ABC-ABC-1 PIC X(02). XXXXXXXX
25 ABCDE-ABC-ABC-2 PIC X(03). XXXXXXXX
25 ABCDE-ABC-ABC-3 PIC X(03). XXXXXXXX
25 ABCDE-ABC-ABC-4 PIC X(04). XXXXXXXX
:
io.infinite.cobol.CobolCompiler|import groovy.transform.CompileStatic
import io.infinite.cobol.CobolRuntime
import io.infinite.cobol.CobolApi
import io.infinite.other.CopybookStructureEnum
@CompileStatic
class CobolClosureRuntime extends CobolRuntime {
@Override
void run(Long totalSize, InputStream inputStream, String charsetName, List<Byte> lineBreakBytes, CobolApi cobolApi, CopybookStructureEnum copybookStructure) {
super.setup(totalSize, inputStream, charsetName, lineBreakBytes, cobolApi, copybookStructure)
readFile() {
createRecord("ABCDE-RECORD") {
createGroup(2, "ABCDE-REC") {
createGroup(3, "ABCDE-COMMON") {
createGroup(4, "ABCDE-DETAILS") {
createGroup(5, "ABCDE-RECORD-ABC") {
createGroup(6, "ABCDE-PRI-ABC") {
createGroup(7, "ABCDE-ABC-AAAAAAAA") {
setDataPicture(
depth: 7,
pictureString: "X(02)",
length: 2,
comp3length: 2,
scale: 0,
)
}//<(end of group: ABCDE-ABC-AAAAAAAA)
createGroup(7, "ABCDE-ABC-ACCT-ABCS") {
createGroup(8, "ABCDE-ABC-ABC-1") {
setDataPicture(
depth: 8,
pictureString: "X(02)",
length: 2,
comp3length: 2,
scale: 0,
)
}//<(end of group: ABCDE-ABC-ABC-1)
createGroup(8, "ABCDE-ABC-ABC-2") {
setDataPicture(
depth: 8,
pictureString: "X(03)",
length: 3,
comp3length: 2,
scale: 0,
)
}//<(end of group: ABCDE-ABC-ABC-2)
createGroup(8, "ABCDE-ABC-ABC-3") {
setDataPicture(
depth: 8,
pictureString: "X(03)",
length: 3,
comp3length: 2,
scale: 0,
)
}//<(end of group: ABCDE-ABC-ABC-3)
createGroup(8, "ABCDE-ABC-ABC-4") {
setDataPicture(
depth: 8,
pictureString: "X(04)",
length: 4,
comp3length: 3,
scale: 0,
)
}//<<<<(end of group: ABCDE-ABC-ABC-4)
}//<<<<(end of group: ABCDE-ABC-ACCT-ABCS)
}//<<<<(end of group: ABCDE-PRI-ABC)
}//<<<<(end of group: ABCDE-RECORD-ABC)
}//<<<<(end of group: ABCDE-DETAILS)
}//<<<<(end of group: ABCDE-COMMON)
}//<<<<(end of group: ABCDE-REC)
}//<<<<(end of group: ABCDE-RECORD)
}//<<<<<
}
}
, Production .
— , . — copybook
— .
.
$.
:
- Open Source COBOL Java (Groovy)
- COBOL (proleap.io)
- COMP-3
- Data Section Division
redefines
occurs
- API, XML ( )
- (EBCDIC, ASCII )
1)
2) — , . .
3) , " ". 2020 .
https://i-t.io , . -, .
.
!
:
https://github.com/INFINITE-TECHNOLOGY/COBOL