COBOL: Import new upstream candidate parser

This fixes support for COBOL symbols after the recent breakage of regex
parsers, as well as introducing additional features and bug fixes.

Also import some of the tests.

https://github.com/universal-ctags/ctags/pull/2076

Part of #2119.
This commit is contained in:
Colomban Wendling 2019-04-20 10:54:27 +02:00
parent acebc2d6db
commit 585b16b0da
15 changed files with 645 additions and 45 deletions

View File

@ -8,42 +8,516 @@
* files.
*/
/* Some references:
* - https://www.cs.vu.nl/grammarware/browsable/cobol/
* - https://www.cs.vu.nl/grammarware/browsable/vs-cobol-ii/
* - https://open-cobol.sourceforge.io/guides/grammar.pdf
* - http://mapage.noos.fr/~bpinon/a_cobol_parser.htm
* - https://en.wikipedia.org/wiki/COBOL
*/
/*
* INCLUDE FILES
*/
#include "general.h" /* must always come first */
#include "debug.h"
#include "entry.h"
#include "keyword.h"
#include "nestlevel.h"
#include "parse.h"
#include "read.h"
#include "routines.h"
static tagRegexTable cobolTagRegexTable[] = {
{"^[ \t]*[0-9]+[ \t]+([A-Z0-9][A-Z0-9-]*)[ \t]+("
"BLANK|OCCURS|IS|JUST|PIC|REDEFINES|RENAMES|SIGN|SYNC|USAGE|VALUE"
")", "\\1",
"d,data,data items", "i", NULL},
{"^[ \t]*[FSR]D[ \t]+([A-Z0-9][A-Z0-9-]*)\\.", "\\1",
"f,file,file descriptions (FD, SD, RD)", "i", NULL},
{"^[ \t]*[0-9]+[ \t]+([A-Z0-9][A-Z0-9-]*)\\.", "\\1",
"g,group,group items", "i", NULL},
{"^[ \t]*([A-Z0-9][A-Z0-9-]*)\\.", "\\1",
"p,paragraph,paragraphs", "i", NULL},
{"^[ \t]*PROGRAM-ID\\.[ \t]+([A-Z0-9][A-Z0-9-]*)\\.", "\\1",
"P,program,program ids", "i", NULL},
{"^[ \t]*([A-Z0-9][A-Z0-9-]*)[ \t]+SECTION\\.", "\\1",
"s,section,sections", "i", NULL},
typedef enum {
K_FILE,
K_GROUP,
K_PROGRAM,
K_SECTION,
K_DIVISION,
K_PARAGRAPH,
K_DATA,
K_SOURCEFILE,
} cobolKind;
typedef enum {
COBOL_SOURCEFILE_COPIED,
} cobolSourcefileRole;
static roleDefinition CobolSourcefileRoles [] = {
{ true, "copied", "copied in source file" },
};
/*
* FUNCTION DEFINITIONS
*/
static kindDefinition CobolKinds[] = {
{ true, 'f', "fd", "file descriptions (FD, SD, RD)" },
{ true, 'g', "group", "group items" },
{ true, 'P', "program", "program ids" },
{ true, 's', "section", "sections" },
{ true, 'D', "division", "divisions" },
{ true, 'p', "paragraph", "paragraphs" },
{ true, 'd', "data", "data items" },
{ true, 'S', "sourcefile", "source code file",
.referenceOnly = true, ATTACH_ROLES(CobolSourcefileRoles)},
};
static langType Lang_cobol;
enum {
KEYWORD_FD,
KEYWORD_SD,
KEYWORD_RD,
KEYWORD_SECTION,
KEYWORD_DIVISION,
KEYWORD_CONTINUE,
KEYWORD_END_EXEC,
KEYWORD_FILLER,
KEYWORD_BLANK,
KEYWORD_OCCURS,
KEYWORD_IS,
KEYWORD_JUST,
KEYWORD_PIC,
KEYWORD_REDEFINES,
KEYWORD_RENAMES,
KEYWORD_SIGN,
KEYWORD_SYNC,
KEYWORD_USAGE,
KEYWORD_VALUE,
KEYWORD_PROGRAM_ID,
KEYWORD_EXIT,
KEYWORD_COPY,
};
static const keywordTable cobolKeywordTable[] = {
#define DEFINE_KEYWORD(n) { #n, KEYWORD_##n }
DEFINE_KEYWORD (FD),
DEFINE_KEYWORD (SD),
DEFINE_KEYWORD (RD),
DEFINE_KEYWORD (SECTION),
DEFINE_KEYWORD (DIVISION),
DEFINE_KEYWORD (CONTINUE),
{ "END-EXEC", KEYWORD_END_EXEC },
DEFINE_KEYWORD (EXIT),
DEFINE_KEYWORD (FILLER),
DEFINE_KEYWORD (BLANK),
DEFINE_KEYWORD (OCCURS),
DEFINE_KEYWORD (IS),
DEFINE_KEYWORD (JUST),
DEFINE_KEYWORD (PIC),
{ "PICTURE", KEYWORD_PIC },
DEFINE_KEYWORD (REDEFINES),
DEFINE_KEYWORD (RENAMES),
DEFINE_KEYWORD (SIGN),
DEFINE_KEYWORD (SYNC),
DEFINE_KEYWORD (USAGE),
DEFINE_KEYWORD (VALUE),
{ "VALUES", KEYWORD_VALUE },
{ "PROGRAM-ID", KEYWORD_PROGRAM_ID },
DEFINE_KEYWORD (COPY),
};
#define INDICATOR_COLUMN 7
#define PROGRAM_NAME_AREA_COLUMN 73
#define isIdentifierChar(c) (isalnum(c) || (c) == '-')
#define isQuote(c) ((c) == '\'' || (c) == '"')
typedef enum {
/* Fixed: program starts at column 8, ends at column 72 */
FORMAT_FIXED = 0x1,
/* Free: program starts at column 1, no specific end */
FORMAT_FREE = 0x2,
/* Variable: program starts at column 8, no specific end */
FORMAT_VARIABLE = FORMAT_FIXED | FORMAT_FREE
} CobolFormat;
static struct {
vString *line;
unsigned long int lineNumber;
MIOPos filePosition;
const char *nextLine;
CobolFormat format;
} CblInputState;
static void cblppInit (const CobolFormat format)
{
CblInputState.line = vStringNew ();
CblInputState.lineNumber = 0;
CblInputState.nextLine = NULL;
CblInputState.format = format;
}
static void cblppDeinit (void)
{
vStringDelete (CblInputState.line);
}
static const char *cblppGetColumn (const char *line,
const unsigned int column)
{
unsigned int col = 0;
for (; *line; line++)
{
col += (*line == '\t') ? 8 : 1;
if (col >= column)
return line;
}
return NULL;
}
static void cblppAppendLine (vString *buffer,
const char *line)
{
if (CblInputState.format & FORMAT_FIXED)
{
const char *indicator = cblppGetColumn (line, INDICATOR_COLUMN);
if (indicator && *indicator && *indicator != '*' && *indicator != '/')
{
const char *lineStart = indicator + 1;
const char *lineEnd = cblppGetColumn (line, PROGRAM_NAME_AREA_COLUMN);
if (*indicator == '-')
{
vStringStripTrailing (buffer);
while (isspace (*lineStart))
lineStart++;
}
if (CblInputState.format == FORMAT_FIXED)
vStringNCatS (buffer, lineStart, lineEnd - lineStart);
else
vStringCatS (buffer, lineStart);
}
}
else if (line[0] != '*' && line[0] != '/')
vStringCatS (buffer, line);
}
/* TODO: skip *> comments */
static const char *cblppGetLine (void)
{
const char *line;
if (CblInputState.nextLine)
{
line = CblInputState.nextLine;
CblInputState.nextLine = NULL;
}
else
line = (const char *) readLineFromInputFile ();
CblInputState.lineNumber = getInputLineNumber ();
CblInputState.filePosition = getInputFilePosition ();
if (!line)
return NULL;
vStringClear (CblInputState.line);
cblppAppendLine (CblInputState.line, line);
/* check for continuation lines */
if (CblInputState.format & FORMAT_FIXED)
{
while (true)
{
const char *indicator;
line = (const char *) readLineFromInputFile ();
if (! line)
break;
indicator = cblppGetColumn (line, INDICATOR_COLUMN);
if (indicator && *indicator == '-')
cblppAppendLine (CblInputState.line, line);
else
break;
}
CblInputState.nextLine = line;
}
return vStringValue (CblInputState.line);
}
static void initCOBOLRefTagEntry (tagEntryInfo *e, const char *name,
const cobolKind kind, const int role)
{
initRefTagEntry (e, name, kind, role);
e->lineNumber = CblInputState.lineNumber;
e->filePosition = CblInputState.filePosition;
}
static void initCOBOLTagEntry (tagEntryInfo *e, const char *name, const cobolKind kind)
{
initCOBOLRefTagEntry (e, name, kind, ROLE_INDEX_DEFINITION);
}
static int makeCOBOLRefTag (const char *name, const cobolKind kind, const int role)
{
if (CobolKinds[kind].enabled)
{
tagEntryInfo e;
initCOBOLRefTagEntry (&e, name, kind, role);
return makeTagEntry (&e);
}
return CORK_NIL;
}
static int makeCOBOLTag (const char *name, const cobolKind kind)
{
return makeCOBOLRefTag (name, kind, ROLE_INDEX_DEFINITION);
}
#define CBL_NL(nl) (*((unsigned int *) (nestingLevelGetUserData (nl))))
static NestingLevel *popNestingLevelsToLevelNumber (NestingLevels *levels, const unsigned int levelNumber)
{
NestingLevel *nl;
while (true)
{
nl = nestingLevelsGetCurrent (levels);
if (! nl || CBL_NL (nl) < levelNumber)
break;
nestingLevelsPop (levels);
}
return nl;
}
static bool isNumeric (const char *nptr, unsigned long int *num)
{
char *endptr;
unsigned long int v;
v = strtoul (nptr, &endptr, 10);
if (nptr != endptr && *endptr == 0)
{
if (num)
*num = v;
return true;
}
return false;
}
static void findCOBOLTags (const CobolFormat format)
{
NestingLevels *levels;
const char *line;
cblppInit (format);
levels = nestingLevelsNew (sizeof (unsigned int));
while ((line = cblppGetLine ()) != NULL)
{
char word[64];
int keyword;
unsigned long int levelNumber;
#define READ_WHILE(word, cond) \
do { \
unsigned int i; \
for (i = 0; i < (ARRAY_SIZE (word) - 1) && *line && (cond); line++) \
word[i++] = *line; \
word[i] = 0; \
} while (0)
#define READ_LITERAL(word) \
do { \
const char READ_LITERAL__q = isQuote (*line) ? *line++ : 0; \
READ_WHILE (word, (READ_LITERAL__q && READ_LITERAL__q != *line) || \
isIdentifierChar (*line)); \
if (READ_LITERAL__q && READ_LITERAL__q == *line) \
line++; \
keyword = lookupCaseKeyword (word, Lang_cobol); \
} while (0)
#define READ_WORD(word, keyword) \
do { \
READ_WHILE (word, isIdentifierChar (*line)); \
keyword = lookupCaseKeyword (word, Lang_cobol); \
} while (0)
#define READ_KEYWORD(keyword) \
do { \
char READ_KEYWORD__word[64]; \
READ_WORD (READ_KEYWORD__word, keyword); \
} while (0)
#define SKIP_SPACES() do { while (isspace (*line)) line++; } while (0)
SKIP_SPACES ();
READ_WORD (word, keyword);
SKIP_SPACES ();
switch (keyword)
{
case KEYWORD_FD:
case KEYWORD_SD:
case KEYWORD_RD:
READ_WORD (word, keyword);
SKIP_SPACES ();
if (*word && *line == '.')
makeCOBOLTag (word, K_FILE);
break;
case KEYWORD_PROGRAM_ID:
if (*line == '.')
{
line++;
SKIP_SPACES ();
}
READ_LITERAL (word);
if (*word)
makeCOBOLTag (word, K_PROGRAM);
break;
case KEYWORD_COPY:
READ_WORD (word, keyword); // FIXME: also allow LITERAL
if (*word)
makeCOBOLRefTag (word, K_SOURCEFILE, COBOL_SOURCEFILE_COPIED);
break;
case KEYWORD_CONTINUE:
case KEYWORD_END_EXEC:
case KEYWORD_EXIT:
case KEYWORD_FILLER:
/* nothing, just ignore those in following cases */;
break;
default:
if (isNumeric (word, &levelNumber))
{
READ_WORD (word, keyword);
SKIP_SPACES ();
if (*word && keyword != KEYWORD_FILLER)
{
int kind = KIND_GHOST_INDEX;
if (*line == '.')
kind = K_GROUP;
else
{
int keyword2;
READ_KEYWORD (keyword2);
switch (keyword2)
{
case KEYWORD_BLANK:
case KEYWORD_OCCURS:
case KEYWORD_IS:
case KEYWORD_JUST:
case KEYWORD_PIC:
case KEYWORD_REDEFINES:
case KEYWORD_RENAMES:
case KEYWORD_SIGN:
case KEYWORD_SYNC:
case KEYWORD_USAGE:
case KEYWORD_VALUE:
kind = K_DATA;
}
}
if (kind != KIND_GHOST_INDEX)
{
NestingLevel *nl;
tagEntryInfo entry;
int r;
unsigned int nestingLevelNumber;
/* for nesting purposes, level 77 is identical to 1,
* and 66 to 2 */
switch (levelNumber)
{
default: nestingLevelNumber = levelNumber; break;
case 77: nestingLevelNumber = 1; break;
case 66: nestingLevelNumber = 2; break;
}
nl = popNestingLevelsToLevelNumber (levels, nestingLevelNumber);
initCOBOLTagEntry (&entry, word, kind);
if (nl && CBL_NL (nl) < nestingLevelNumber)
entry.extensionFields.scopeIndex = nl->corkIndex;
r = makeTagEntry (&entry);
if (levelNumber < 50 /* exclude special levels */)
{
nl = nestingLevelsPush (levels, r);
CBL_NL (nl) = levelNumber;
}
}
}
}
else if (*word && *line == '.')
makeCOBOLTag (word, K_PARAGRAPH);
else
{
int keyword2;
READ_KEYWORD (keyword2);
SKIP_SPACES ();
if (keyword2 == KEYWORD_DIVISION && *line == '.')
makeCOBOLTag (word, K_DIVISION);
else if (keyword2 == KEYWORD_SECTION && *line == '.')
makeCOBOLTag (word, K_SECTION);
}
}
}
nestingLevelsFree (levels);
cblppDeinit ();
}
static void findCOBOLFixedTags (void)
{
findCOBOLTags (FORMAT_FIXED);
}
static void findCOBOLFreeTags (void)
{
findCOBOLTags (FORMAT_FREE);
}
static void findCOBOLVariableTags (void)
{
findCOBOLTags (FORMAT_VARIABLE);
}
static void initializeCobolParser (langType language)
{
Lang_cobol = language;
}
static parserDefinition* commonCobolParserDefinition (const char *name,
simpleParser parser)
{
parserDefinition* def = parserNew (name);
def->initialize = initializeCobolParser;
def->parser = parser;
def->kindTable = CobolKinds;
def->kindCount = ARRAY_SIZE(CobolKinds);
def->keywordTable = cobolKeywordTable;
def->keywordCount = ARRAY_SIZE(cobolKeywordTable);
def->useCork = true;
return def;
}
extern parserDefinition* CobolParser (void)
{
static const char *const extensions [] = {
"cbl", "cob", "cpy", "CBL", "COB", NULL };
parserDefinition* def = parserNew ("Cobol");
"cbl", "cob", "CBL", "COB", NULL };
parserDefinition* def = commonCobolParserDefinition ("Cobol",
findCOBOLFixedTags);
def->extensions = extensions;
def->tagRegexTable = cobolTagRegexTable;
def->tagRegexCount = ARRAY_SIZE (cobolTagRegexTable);
def->method = METHOD_NOT_CRAFTED|METHOD_REGEX;
return def;
}
extern parserDefinition* CobolFreeParser (void)
{
return commonCobolParserDefinition ("CobolFree", findCOBOLFreeTags);
}
extern parserDefinition* CobolVariableParser (void)
{
return commonCobolParserDefinition ("CobolVariable", findCOBOLVariableTags);
}

View File

@ -490,10 +490,12 @@ static void add_top_level_items(GeanyDocument *doc)
tag_list_add_groups(tag_store,
&tv_iters.tag_class, _("Program"), ICON_CLASS,
&tv_iters.tag_function, _("File"), ICON_METHOD,
&tv_iters.tag_interface, _("Divisions"), ICON_NAMESPACE,
&tv_iters.tag_namespace, _("Sections"), ICON_NAMESPACE,
&tv_iters.tag_macro, _("Paragraph"), ICON_OTHER,
&tv_iters.tag_struct, _("Group"), ICON_STRUCT,
&tv_iters.tag_variable, _("Data"), ICON_VAR,
&tv_iters.tag_externvar, _("Copies"), ICON_NAMESPACE,
NULL);
break;
case GEANY_FILETYPES_CONF:

View File

@ -423,11 +423,13 @@ static TMParserMapEntry map_R[] = {
static TMParserMapEntry map_COBOL[] = {
{'d', tm_tag_variable_t},
{'D', tm_tag_interface_t},
{'f', tm_tag_function_t},
{'g', tm_tag_struct_t},
{'p', tm_tag_macro_t},
{'P', tm_tag_class_t},
{'s', tm_tag_namespace_t},
{'S', tm_tag_externvar_t},
};
static TMParserMapEntry map_OBJC[] = {
@ -768,6 +770,7 @@ gboolean tm_parser_has_full_context(TMParserType lang)
case TM_PARSER_C:
case TM_PARSER_CPP:
case TM_PARSER_CSHARP:
case TM_PARSER_COBOL:
case TM_PARSER_D:
case TM_PARSER_FERITE:
case TM_PARSER_GLSL:

View File

@ -1,9 +1,6 @@
dist_check_SCRIPTS = runner.sh
# Disabled tests:
# simple.cbl
NULL =
test_sources = \
1795612.js \
@ -117,6 +114,11 @@ test_sources = \
case_sensitivity.php \
char-selector.f90 \
classes.php \
cobol/helloworld.cbl \
cobol/helloworld2.cbl \
cobol/levels.cbl \
cobol/quoted-program-id.cbl \
cobol/simple.cbl \
common.f \
complex-return.js \
continuation.f90 \

View File

@ -0,0 +1,14 @@
00000* VALIDATION OF BASE COBOL INSTALL 00050000
01000 IDENTIFICATION DIVISION. 00060000
01100 PROGRAM-ID. 'HELLO'. 00070000
02000 ENVIRONMENT DIVISION. 00080000
02100 CONFIGURATION SECTION. 00090000
02110 SOURCE-COMPUTER. GNULINUX. 00100000
02120 OBJECT-COMPUTER. HERCULES. 00110000
02200 SPECIAL-NAMES. 00120000
02210 CONSOLE IS CONSL. 00130000
03000 DATA DIVISION. 00140000
04000 PROCEDURE DIVISION. 00150000
04100 00-MAIN. 00160000
04110 DISPLAY 'HELLO, WORLD' UPON CONSL. 00170000
04900 STOP RUN. 00180000

View File

@ -0,0 +1,11 @@
# format=tagmanager
00-MAINÌ65536Ö0
CONFIGURATIONÌ256Ö0
DATAÌ32Ö0
ENVIRONMENTÌ32Ö0
HELLOÌ1Ö0
IDENTIFICATIONÌ32Ö0
OBJECT-COMPUTERÌ65536Ö0
PROCEDUREÌ32Ö0
SOURCE-COMPUTERÌ65536Ö0
SPECIAL-NAMESÌ65536Ö0

View File

@ -0,0 +1,19 @@
00000* VALIDATION OF BASE COBOL INSTALL
IDENTIFICATION DIVISION.
01100 PROGRAM-ID. 'HELLO WORLD'.
02000 ENVIRONMENT DIV
-ISION.
02100 CONFIGURATION SECTION.
02110 SOURCE-COMPUTER. GNULINUX.
02120 OBJECT-COMPUTER. HERCULES.
02200 SPECIAL
--NAMES.
02210 CONSOLE IS CONSL.
03000 DATA DIVISION.
04000 PROCEDUR
- E DIVISION.
04100 00-MAIN.
04110 DISPLAY
'HELLO, WORLD'
UPON CONSL.
04900 STOP RUN.

View File

@ -0,0 +1,11 @@
# format=tagmanager
00-MAINÌ65536Ö0
CONFIGURATIONÌ256Ö0
DATAÌ32Ö0
ENVIRONMENTÌ32Ö0
HELLO WORLDÌ1Ö0
IDENTIFICATIONÌ32Ö0
OBJECT-COMPUTERÌ65536Ö0
PROCEDUREÌ32Ö0
SOURCE-COMPUTERÌ65536Ö0
SPECIAL-NAMESÌ65536Ö0

View File

@ -0,0 +1,27 @@
IDENTIFICATION DIVISION.
PROGRAM-ID. Test-Items.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 RECORD1.
05 ITEM1 PIC X(1).
05 ITEM2 PIC A(1).
88 ODD VALUES 1, 3, 5, 7, 9.
88 EVEN VALUES 2, 4, 6, 8.
05 ITEM3 PIC X(6).
66 RDITEM4 RENAMES ITEM1 THRU ITEM2.
66 RDITEM5 RENAMES ITEM1 THROUGH ITEM3.
77 STDLN1 PIC A(4).
01 REC2.
02 G1.
05 ITEM1 PICTURE X(10).
05 ITEM2 PIC X(10).
66 OTHERNAME1 RENAMES ITEM1 IN REC2.
66 OTHERNAME2 RENAMES G1.
PROCEDURE DIVISION.
MAIN-PROCEDURE.
DISPLAY "Hello world".
DISPLAY OTHERNAME2.
STOP RUN.
END PROGRAM Test-Items.

View File

@ -0,0 +1,22 @@
# format=tagmanager
DATAÌ32Ö0
EVENÌ16384ÎRECORD1.ITEM2Ö0
G1Ì2048ÎREC2Ö0
IDENTIFICATIONÌ32Ö0
ITEM1Ì16384ÎREC2.G1Ö0
ITEM1Ì16384ÎRECORD1Ö0
ITEM2Ì16384ÎREC2.G1Ö0
ITEM2Ì16384ÎRECORD1Ö0
ITEM3Ì16384ÎRECORD1Ö0
MAIN-PROCEDUREÌ65536Ö0
ODDÌ16384ÎRECORD1.ITEM2Ö0
OTHERNAME1Ì16384ÎREC2Ö0
OTHERNAME2Ì16384ÎREC2Ö0
PROCEDUREÌ32Ö0
RDITEM4Ì16384ÎRECORD1Ö0
RDITEM5Ì16384ÎRECORD1Ö0
REC2Ì2048Ö0
RECORD1Ì2048Ö0
STDLN1Ì16384Ö0
Test-ItemsÌ1Ö0
WORKING-STORAGEÌ256Ö0

View File

@ -0,0 +1,7 @@
IDENTIFICATION DIVISION.
PROGRAM-ID. 'Test program name'.
PROCEDURE DIVISION.
MAIN.
DISPLAY 'This is a test program'.
STOP RUN.
END PROGRAM 'Test program name'.

View File

@ -0,0 +1,5 @@
# format=tagmanager
IDENTIFICATIONÌ32Ö0
MAINÌ65536Ö0
PROCEDUREÌ32Ö0
Test program nameÌ1Ö0

View File

@ -0,0 +1,22 @@
# format=tagmanager
AUTHORÌ65536Ö0
BeginÌ65536Ö0
DATAÌ32Ö0
DW-DAYS-IN-MONTHÌ16384ÎGroup-Name.Data-Item1.DW-DAYS-IN-MONTHSÖ0
DW-DAYS-IN-MONTHSÌ16384ÎGroup-Name.Data-Item1Ö0
Data-Item1Ì16384ÎGroup-NameÖ0
ENVIRONMENTÌ32Ö0
FILEÌ256Ö0
FILE-CONTROLÌ65536Ö0
File-Data-ItemÌ16384ÎFile-Group-NameÖ0
File-Group-NameÌ2048Ö0
File-NameÌ16Ö0
Group-NameÌ2048Ö0
IDENTIFICATIONÌ32Ö0
INPUT-OUPUTÌ256Ö0
PROCEDUREÌ32Ö0
Program-NameÌ1Ö0
SH-WORK-MMDDYYYYÌ16384ÎGroup-Name.Data-Item1Ö0
SH-WORK-MMDDYYYY-2Ì16384ÎGroup-Name.Data-Item1Ö0
Subprogram-NameÌ65536Ö0
WORKING-STORAGEÌ256Ö0

View File

@ -1,19 +0,0 @@
# format=tagmanager
AUTHORÌ65536Ö0
BeginÌ65536Ö0
DW-DAYS-IN-MONTHÌ16384Ö0
DW-DAYS-IN-MONTHSÌ16384Ö0
Data-Item1Ì16384Ö0
FILEÌ256Ö0
FILE-CONTROLÌ65536Ö0
File-Data-ItemÌ16384Ö0
File-Group-NameÌ2048Ö0
File-NameÌ16Ö0
Group-NameÌ2048Ö0
INPUT-OUPUTÌ256Ö0
PROGRAM-IDÌ65536Ö0
Program-NameÌ1Ö0
SH-WORK-MMDDYYYYÌ16384Ö0
SH-WORK-MMDDYYYY-2Ì16384Ö0
Subprogram-NameÌ65536Ö0
WORKING-STORAGEÌ256Ö0