13ae02089SMasatake YAMATO /*
23ae02089SMasatake YAMATO * Copyright (c) 2000-2003, Darren Hiebert
33ae02089SMasatake YAMATO *
43ae02089SMasatake YAMATO * This source code is released for free distribution under the terms of the
50ce38835Sviccuad * GNU General Public License version 2 or (at your option) any later version.
63ae02089SMasatake YAMATO *
73ae02089SMasatake YAMATO * This module contains functions for generating tags for COBOL language
83ae02089SMasatake YAMATO * files.
93ae02089SMasatake YAMATO */
103ae02089SMasatake YAMATO
11*bcc2ead4SColomban Wendling /* Some references:
12*bcc2ead4SColomban Wendling * - https://www.cs.vu.nl/grammarware/browsable/cobol/
13*bcc2ead4SColomban Wendling * - https://www.cs.vu.nl/grammarware/browsable/vs-cobol-ii/
14*bcc2ead4SColomban Wendling * - https://open-cobol.sourceforge.io/guides/grammar.pdf
15*bcc2ead4SColomban Wendling * - http://mapage.noos.fr/~bpinon/a_cobol_parser.htm
16*bcc2ead4SColomban Wendling * - https://en.wikipedia.org/wiki/COBOL
17*bcc2ead4SColomban Wendling */
18*bcc2ead4SColomban Wendling
193ae02089SMasatake YAMATO /*
203ae02089SMasatake YAMATO * INCLUDE FILES
213ae02089SMasatake YAMATO */
223ae02089SMasatake YAMATO #include "general.h" /* must always come first */
2306def60bSColomban Wendling #include "debug.h"
24e57cf27dSColomban Wendling #include "entry.h"
2595ecd0e1SMasatake YAMATO #include "keyword.h"
26e57cf27dSColomban Wendling #include "nestlevel.h"
273ae02089SMasatake YAMATO #include "parse.h"
28e57cf27dSColomban Wendling #include "read.h"
293db72c21SMasatake YAMATO #include "routines.h"
303ae02089SMasatake YAMATO
3195ecd0e1SMasatake YAMATO typedef enum {
32e57cf27dSColomban Wendling K_FILE,
33e57cf27dSColomban Wendling K_GROUP,
34e57cf27dSColomban Wendling K_PROGRAM,
35e57cf27dSColomban Wendling K_SECTION,
36e57cf27dSColomban Wendling K_DIVISION,
3795ecd0e1SMasatake YAMATO K_PARAGRAPH,
38176ada67SMasatake YAMATO K_DATA,
39e167948bSMasatake YAMATO K_SOURCEFILE,
4095ecd0e1SMasatake YAMATO } cobolKind;
4195ecd0e1SMasatake YAMATO
42e167948bSMasatake YAMATO typedef enum {
43db025d38SMasatake YAMATO COBOL_SOURCEFILE_COPIED,
44e167948bSMasatake YAMATO } cobolSourcefileRole;
45e167948bSMasatake YAMATO
4613457258SMasatake YAMATO static roleDefinition CobolSourcefileRoles [] = {
47db025d38SMasatake YAMATO { true, "copied", "copied in source file" },
48e167948bSMasatake YAMATO };
49e167948bSMasatake YAMATO
50e112e8abSMasatake YAMATO static kindDefinition CobolKinds[] = {
51e57cf27dSColomban Wendling { true, 'f', "fd", "file descriptions (FD, SD, RD)" },
52e57cf27dSColomban Wendling { true, 'g', "group", "group items" },
53e57cf27dSColomban Wendling { true, 'P', "program", "program ids" },
54e57cf27dSColomban Wendling { true, 's', "section", "sections" },
55e57cf27dSColomban Wendling { true, 'D', "division", "divisions" },
5695ecd0e1SMasatake YAMATO { true, 'p', "paragraph", "paragraphs" },
57176ada67SMasatake YAMATO { true, 'd', "data", "data items" },
58e167948bSMasatake YAMATO { true, 'S', "sourcefile", "source code file",
59e167948bSMasatake YAMATO .referenceOnly = true, ATTACH_ROLES(CobolSourcefileRoles)},
6095ecd0e1SMasatake YAMATO };
6195ecd0e1SMasatake YAMATO
62e57cf27dSColomban Wendling static langType Lang_cobol;
63dc0f490fSMasatake YAMATO
64e57cf27dSColomban Wendling enum {
65e57cf27dSColomban Wendling KEYWORD_FD,
66e57cf27dSColomban Wendling KEYWORD_SD,
67e57cf27dSColomban Wendling KEYWORD_RD,
68e57cf27dSColomban Wendling KEYWORD_SECTION,
69e57cf27dSColomban Wendling KEYWORD_DIVISION,
70e57cf27dSColomban Wendling KEYWORD_CONTINUE,
71e57cf27dSColomban Wendling KEYWORD_END_EXEC,
72e57cf27dSColomban Wendling KEYWORD_FILLER,
73e57cf27dSColomban Wendling KEYWORD_BLANK,
74e57cf27dSColomban Wendling KEYWORD_OCCURS,
75e57cf27dSColomban Wendling KEYWORD_IS,
76e57cf27dSColomban Wendling KEYWORD_JUST,
77e57cf27dSColomban Wendling KEYWORD_PIC,
78e57cf27dSColomban Wendling KEYWORD_REDEFINES,
79e57cf27dSColomban Wendling KEYWORD_RENAMES,
80e57cf27dSColomban Wendling KEYWORD_SIGN,
81e57cf27dSColomban Wendling KEYWORD_SYNC,
82e57cf27dSColomban Wendling KEYWORD_USAGE,
83e57cf27dSColomban Wendling KEYWORD_VALUE,
84e57cf27dSColomban Wendling KEYWORD_PROGRAM_ID,
85e57cf27dSColomban Wendling KEYWORD_EXIT,
86e57cf27dSColomban Wendling KEYWORD_COPY,
87e57cf27dSColomban Wendling };
8895ecd0e1SMasatake YAMATO
8995ecd0e1SMasatake YAMATO static const keywordTable cobolKeywordTable[] = {
90e57cf27dSColomban Wendling #define DEFINE_KEYWORD(n) { #n, KEYWORD_##n }
91e57cf27dSColomban Wendling DEFINE_KEYWORD (FD),
92e57cf27dSColomban Wendling DEFINE_KEYWORD (SD),
93e57cf27dSColomban Wendling DEFINE_KEYWORD (RD),
94e57cf27dSColomban Wendling DEFINE_KEYWORD (SECTION),
95e57cf27dSColomban Wendling DEFINE_KEYWORD (DIVISION),
96e57cf27dSColomban Wendling DEFINE_KEYWORD (CONTINUE),
97e57cf27dSColomban Wendling { "END-EXEC", KEYWORD_END_EXEC },
98e57cf27dSColomban Wendling DEFINE_KEYWORD (EXIT),
99e57cf27dSColomban Wendling DEFINE_KEYWORD (FILLER),
100e57cf27dSColomban Wendling DEFINE_KEYWORD (BLANK),
101e57cf27dSColomban Wendling DEFINE_KEYWORD (OCCURS),
102e57cf27dSColomban Wendling DEFINE_KEYWORD (IS),
103e57cf27dSColomban Wendling DEFINE_KEYWORD (JUST),
104e57cf27dSColomban Wendling DEFINE_KEYWORD (PIC),
1050b3cdb6aSColomban Wendling { "PICTURE", KEYWORD_PIC },
106e57cf27dSColomban Wendling DEFINE_KEYWORD (REDEFINES),
107e57cf27dSColomban Wendling DEFINE_KEYWORD (RENAMES),
108e57cf27dSColomban Wendling DEFINE_KEYWORD (SIGN),
109e57cf27dSColomban Wendling DEFINE_KEYWORD (SYNC),
110e57cf27dSColomban Wendling DEFINE_KEYWORD (USAGE),
111e57cf27dSColomban Wendling DEFINE_KEYWORD (VALUE),
1120b3cdb6aSColomban Wendling { "VALUES", KEYWORD_VALUE },
113e57cf27dSColomban Wendling { "PROGRAM-ID", KEYWORD_PROGRAM_ID },
114e57cf27dSColomban Wendling DEFINE_KEYWORD (COPY),
11595ecd0e1SMasatake YAMATO };
11695ecd0e1SMasatake YAMATO
1173303a28cSColomban Wendling #define INDICATOR_COLUMN 7
1183303a28cSColomban Wendling #define PROGRAM_NAME_AREA_COLUMN 73
1193ae02089SMasatake YAMATO
120e57cf27dSColomban Wendling #define isIdentifierChar(c) (isalnum(c) || (c) == '-')
1218ccb114eSColomban Wendling #define isQuote(c) ((c) == '\'' || (c) == '"')
122176ada67SMasatake YAMATO
12306def60bSColomban Wendling typedef enum {
12406def60bSColomban Wendling /* Fixed: program starts at column 8, ends at column 72 */
12506def60bSColomban Wendling FORMAT_FIXED = 0x1,
12606def60bSColomban Wendling /* Free: program starts at column 1, no specific end */
12706def60bSColomban Wendling FORMAT_FREE = 0x2,
12806def60bSColomban Wendling /* Variable: program starts at column 8, no specific end */
12906def60bSColomban Wendling FORMAT_VARIABLE = FORMAT_FIXED | FORMAT_FREE
13006def60bSColomban Wendling } CobolFormat;
13106def60bSColomban Wendling
13206def60bSColomban Wendling static struct {
1333303a28cSColomban Wendling vString *line;
1343303a28cSColomban Wendling unsigned long int lineNumber;
1353303a28cSColomban Wendling MIOPos filePosition;
1363303a28cSColomban Wendling const char *nextLine;
13706def60bSColomban Wendling CobolFormat format;
13806def60bSColomban Wendling } CblInputState;
13906def60bSColomban Wendling
cblppInit(const CobolFormat format)14006def60bSColomban Wendling static void cblppInit (const CobolFormat format)
14106def60bSColomban Wendling {
1423303a28cSColomban Wendling CblInputState.line = vStringNew ();
1433303a28cSColomban Wendling CblInputState.lineNumber = 0;
1443303a28cSColomban Wendling CblInputState.nextLine = NULL;
14506def60bSColomban Wendling CblInputState.format = format;
14606def60bSColomban Wendling }
14706def60bSColomban Wendling
cblppDeinit(void)1483303a28cSColomban Wendling static void cblppDeinit (void)
14906def60bSColomban Wendling {
1503303a28cSColomban Wendling vStringDelete (CblInputState.line);
1513303a28cSColomban Wendling }
15206def60bSColomban Wendling
cblppGetColumn(const char * line,const unsigned int column)1533303a28cSColomban Wendling static const char *cblppGetColumn (const char *line,
1543303a28cSColomban Wendling const unsigned int column)
15506def60bSColomban Wendling {
1563303a28cSColomban Wendling unsigned int col = 0;
1573303a28cSColomban Wendling
1583303a28cSColomban Wendling for (; *line; line++)
1593303a28cSColomban Wendling {
1603303a28cSColomban Wendling col += (*line == '\t') ? 8 : 1;
1613303a28cSColomban Wendling if (col >= column)
1623303a28cSColomban Wendling return line;
1633303a28cSColomban Wendling }
1643303a28cSColomban Wendling
1653303a28cSColomban Wendling return NULL;
1663303a28cSColomban Wendling }
1673303a28cSColomban Wendling
cblppAppendLine(vString * buffer,const char * line)1683303a28cSColomban Wendling static void cblppAppendLine (vString *buffer,
1693303a28cSColomban Wendling const char *line)
1703303a28cSColomban Wendling {
1713303a28cSColomban Wendling if (CblInputState.format & FORMAT_FIXED)
1723303a28cSColomban Wendling {
1733303a28cSColomban Wendling const char *indicator = cblppGetColumn (line, INDICATOR_COLUMN);
1743303a28cSColomban Wendling
1753303a28cSColomban Wendling if (indicator && *indicator && *indicator != '*' && *indicator != '/')
1763303a28cSColomban Wendling {
1773303a28cSColomban Wendling const char *lineStart = indicator + 1;
1783303a28cSColomban Wendling const char *lineEnd = cblppGetColumn (line, PROGRAM_NAME_AREA_COLUMN);
1793303a28cSColomban Wendling
1803303a28cSColomban Wendling if (*indicator == '-')
1813303a28cSColomban Wendling {
1823303a28cSColomban Wendling vStringStripTrailing (buffer);
1833303a28cSColomban Wendling while (isspace (*lineStart))
1843303a28cSColomban Wendling lineStart++;
1853303a28cSColomban Wendling }
1863303a28cSColomban Wendling
1873303a28cSColomban Wendling if (CblInputState.format == FORMAT_FIXED)
1883303a28cSColomban Wendling vStringNCatS (buffer, lineStart, lineEnd - lineStart);
18906def60bSColomban Wendling else
1903303a28cSColomban Wendling vStringCatS (buffer, lineStart);
19106def60bSColomban Wendling }
19206def60bSColomban Wendling }
1933303a28cSColomban Wendling else if (line[0] != '*' && line[0] != '/')
1943303a28cSColomban Wendling vStringCatS (buffer, line);
195e57cf27dSColomban Wendling }
196e57cf27dSColomban Wendling
1973303a28cSColomban Wendling /* TODO: skip *> comments */
cblppGetLine(void)1983303a28cSColomban Wendling static const char *cblppGetLine (void)
199e57cf27dSColomban Wendling {
2003303a28cSColomban Wendling const char *line;
2013303a28cSColomban Wendling
2023303a28cSColomban Wendling if (CblInputState.nextLine)
203e57cf27dSColomban Wendling {
2043303a28cSColomban Wendling line = CblInputState.nextLine;
2053303a28cSColomban Wendling CblInputState.nextLine = NULL;
206e57cf27dSColomban Wendling }
207e57cf27dSColomban Wendling else
2083303a28cSColomban Wendling line = (const char *) readLineFromInputFile ();
2093303a28cSColomban Wendling
2103303a28cSColomban Wendling CblInputState.lineNumber = getInputLineNumber ();
2113303a28cSColomban Wendling CblInputState.filePosition = getInputFilePosition ();
2123303a28cSColomban Wendling
2133303a28cSColomban Wendling if (!line)
2143303a28cSColomban Wendling return NULL;
2153303a28cSColomban Wendling
2163303a28cSColomban Wendling vStringClear (CblInputState.line);
2173303a28cSColomban Wendling cblppAppendLine (CblInputState.line, line);
2183303a28cSColomban Wendling
2193303a28cSColomban Wendling /* check for continuation lines */
220ed9c07abSColomban Wendling if (CblInputState.format & FORMAT_FIXED)
221ed9c07abSColomban Wendling {
222ed9c07abSColomban Wendling while (true)
223e57cf27dSColomban Wendling {
2243303a28cSColomban Wendling const char *indicator;
2253303a28cSColomban Wendling line = (const char *) readLineFromInputFile ();
2263303a28cSColomban Wendling if (! line)
2273303a28cSColomban Wendling break;
2283303a28cSColomban Wendling indicator = cblppGetColumn (line, INDICATOR_COLUMN);
2293303a28cSColomban Wendling if (indicator && *indicator == '-')
2303303a28cSColomban Wendling cblppAppendLine (CblInputState.line, line);
2313303a28cSColomban Wendling else
232e57cf27dSColomban Wendling break;
233e57cf27dSColomban Wendling }
234e57cf27dSColomban Wendling
2353303a28cSColomban Wendling CblInputState.nextLine = line;
236ed9c07abSColomban Wendling }
2373303a28cSColomban Wendling
2383303a28cSColomban Wendling return vStringValue (CblInputState.line);
239e57cf27dSColomban Wendling }
240e57cf27dSColomban Wendling
initCOBOLRefTagEntry(tagEntryInfo * e,const char * name,const cobolKind kind,const int role)2413303a28cSColomban Wendling static void initCOBOLRefTagEntry (tagEntryInfo *e, const char *name,
2423303a28cSColomban Wendling const cobolKind kind, const int role)
243e57cf27dSColomban Wendling {
2443303a28cSColomban Wendling initRefTagEntry (e, name, kind, role);
2453303a28cSColomban Wendling e->lineNumber = CblInputState.lineNumber;
2463303a28cSColomban Wendling e->filePosition = CblInputState.filePosition;
247176ada67SMasatake YAMATO }
248176ada67SMasatake YAMATO
initCOBOLTagEntry(tagEntryInfo * e,const char * name,const cobolKind kind)2493303a28cSColomban Wendling static void initCOBOLTagEntry (tagEntryInfo *e, const char *name, const cobolKind kind)
2503303a28cSColomban Wendling {
2513303a28cSColomban Wendling initCOBOLRefTagEntry (e, name, kind, ROLE_DEFINITION_INDEX);
2523303a28cSColomban Wendling }
2533303a28cSColomban Wendling
makeCOBOLRefTag(const char * name,const cobolKind kind,const int role)2543303a28cSColomban Wendling static int makeCOBOLRefTag (const char *name, const cobolKind kind, const int role)
255176ada67SMasatake YAMATO {
256e57cf27dSColomban Wendling if (CobolKinds[kind].enabled)
2573303a28cSColomban Wendling {
2583303a28cSColomban Wendling tagEntryInfo e;
2593303a28cSColomban Wendling
2603303a28cSColomban Wendling initCOBOLRefTagEntry (&e, name, kind, role);
2613303a28cSColomban Wendling
2623303a28cSColomban Wendling return makeTagEntry (&e);
2633303a28cSColomban Wendling }
2643303a28cSColomban Wendling
265e57cf27dSColomban Wendling return CORK_NIL;
266176ada67SMasatake YAMATO }
267176ada67SMasatake YAMATO
makeCOBOLTag(const char * name,const cobolKind kind)2683303a28cSColomban Wendling static int makeCOBOLTag (const char *name, const cobolKind kind)
26995ecd0e1SMasatake YAMATO {
2703303a28cSColomban Wendling return makeCOBOLRefTag (name, kind, ROLE_DEFINITION_INDEX);
27195ecd0e1SMasatake YAMATO }
27295ecd0e1SMasatake YAMATO
2733303a28cSColomban Wendling #define CBL_NL(nl) (*((unsigned int *) (nestingLevelGetUserData (nl))))
274ec945a05SColomban Wendling
popNestingLevelsToLevelNumber(NestingLevels * levels,const unsigned int levelNumber)2753303a28cSColomban Wendling static NestingLevel *popNestingLevelsToLevelNumber (NestingLevels *levels, const unsigned int levelNumber)
276ec945a05SColomban Wendling {
277ec945a05SColomban Wendling NestingLevel *nl;
278ec945a05SColomban Wendling
279ec945a05SColomban Wendling while (true)
280ec945a05SColomban Wendling {
281ec945a05SColomban Wendling nl = nestingLevelsGetCurrent (levels);
282ec945a05SColomban Wendling if (! nl || CBL_NL (nl) < levelNumber)
283ec945a05SColomban Wendling break;
284ec945a05SColomban Wendling nestingLevelsPop (levels);
285ec945a05SColomban Wendling }
286ec945a05SColomban Wendling
287ec945a05SColomban Wendling return nl;
288ec945a05SColomban Wendling }
289ec945a05SColomban Wendling
isNumeric(const char * nptr,unsigned long int * num)2903303a28cSColomban Wendling static bool isNumeric (const char *nptr, unsigned long int *num)
2913303a28cSColomban Wendling {
2923303a28cSColomban Wendling char *endptr;
2933303a28cSColomban Wendling unsigned long int v;
2943303a28cSColomban Wendling
2953303a28cSColomban Wendling v = strtoul (nptr, &endptr, 10);
2963303a28cSColomban Wendling if (nptr != endptr && *endptr == 0)
2973303a28cSColomban Wendling {
2983303a28cSColomban Wendling if (num)
2993303a28cSColomban Wendling *num = v;
3003303a28cSColomban Wendling return true;
3013303a28cSColomban Wendling }
3023303a28cSColomban Wendling return false;
3033303a28cSColomban Wendling }
3043303a28cSColomban Wendling
findCOBOLTags(const CobolFormat format)305174851b3SColomban Wendling static void findCOBOLTags (const CobolFormat format)
306e167948bSMasatake YAMATO {
307ec945a05SColomban Wendling NestingLevels *levels;
3083303a28cSColomban Wendling const char *line;
309e167948bSMasatake YAMATO
310174851b3SColomban Wendling cblppInit (format);
31106def60bSColomban Wendling
3123303a28cSColomban Wendling levels = nestingLevelsNew (sizeof (unsigned int));
3133303a28cSColomban Wendling
3143303a28cSColomban Wendling while ((line = cblppGetLine ()) != NULL)
315e57cf27dSColomban Wendling {
3163303a28cSColomban Wendling char word[64];
3173303a28cSColomban Wendling int keyword;
3183303a28cSColomban Wendling unsigned long int levelNumber;
319e57cf27dSColomban Wendling
3208ccb114eSColomban Wendling #define READ_WHILE(word, cond) \
321e57cf27dSColomban Wendling do { \
3223303a28cSColomban Wendling unsigned int i; \
3238ccb114eSColomban Wendling for (i = 0; i < (ARRAY_SIZE (word) - 1) && *line && (cond); line++) \
3243303a28cSColomban Wendling word[i++] = *line; \
3253303a28cSColomban Wendling word[i] = 0; \
3268ccb114eSColomban Wendling } while (0)
3278ccb114eSColomban Wendling #define READ_LITERAL(word) \
3288ccb114eSColomban Wendling do { \
3298ccb114eSColomban Wendling const char READ_LITERAL__q = isQuote (*line) ? *line++ : 0; \
3308ccb114eSColomban Wendling READ_WHILE (word, (READ_LITERAL__q && READ_LITERAL__q != *line) || \
3318ccb114eSColomban Wendling isIdentifierChar (*line)); \
3328ccb114eSColomban Wendling if (READ_LITERAL__q && READ_LITERAL__q == *line) \
3338ccb114eSColomban Wendling line++; \
3348ccb114eSColomban Wendling keyword = lookupCaseKeyword (word, Lang_cobol); \
3358ccb114eSColomban Wendling } while (0)
3368ccb114eSColomban Wendling #define READ_WORD(word, keyword) \
3378ccb114eSColomban Wendling do { \
3388ccb114eSColomban Wendling READ_WHILE (word, isIdentifierChar (*line)); \
3393303a28cSColomban Wendling keyword = lookupCaseKeyword (word, Lang_cobol); \
340e57cf27dSColomban Wendling } while (0)
3413303a28cSColomban Wendling #define READ_KEYWORD(keyword) \
3423303a28cSColomban Wendling do { \
3433303a28cSColomban Wendling char READ_KEYWORD__word[64]; \
3443303a28cSColomban Wendling READ_WORD (READ_KEYWORD__word, keyword); \
3453303a28cSColomban Wendling } while (0)
3463303a28cSColomban Wendling #define SKIP_SPACES() do { while (isspace (*line)) line++; } while (0)
347e57cf27dSColomban Wendling
3483303a28cSColomban Wendling SKIP_SPACES ();
3493303a28cSColomban Wendling READ_WORD (word, keyword);
3503303a28cSColomban Wendling SKIP_SPACES ();
351e57cf27dSColomban Wendling
3523303a28cSColomban Wendling switch (keyword)
353e57cf27dSColomban Wendling {
3543303a28cSColomban Wendling case KEYWORD_FD:
3553303a28cSColomban Wendling case KEYWORD_SD:
3563303a28cSColomban Wendling case KEYWORD_RD:
3573303a28cSColomban Wendling READ_WORD (word, keyword);
3583303a28cSColomban Wendling SKIP_SPACES ();
3593303a28cSColomban Wendling if (*word && *line == '.')
3603303a28cSColomban Wendling makeCOBOLTag (word, K_FILE);
3613303a28cSColomban Wendling break;
362e57cf27dSColomban Wendling
3633303a28cSColomban Wendling case KEYWORD_PROGRAM_ID:
3643303a28cSColomban Wendling if (*line == '.')
365e57cf27dSColomban Wendling {
3663303a28cSColomban Wendling line++;
3673303a28cSColomban Wendling SKIP_SPACES ();
368e57cf27dSColomban Wendling }
3698ccb114eSColomban Wendling READ_LITERAL (word);
3703303a28cSColomban Wendling if (*word)
3713303a28cSColomban Wendling makeCOBOLTag (word, K_PROGRAM);
3723303a28cSColomban Wendling break;
373ec945a05SColomban Wendling
3743303a28cSColomban Wendling case KEYWORD_COPY:
3753303a28cSColomban Wendling READ_WORD (word, keyword); // FIXME: also allow LITERAL
3763303a28cSColomban Wendling if (*word)
3773303a28cSColomban Wendling makeCOBOLRefTag (word, K_SOURCEFILE, COBOL_SOURCEFILE_COPIED);
3783303a28cSColomban Wendling break;
3793303a28cSColomban Wendling
3803303a28cSColomban Wendling case KEYWORD_CONTINUE:
3813303a28cSColomban Wendling case KEYWORD_END_EXEC:
3823303a28cSColomban Wendling case KEYWORD_EXIT:
3833303a28cSColomban Wendling case KEYWORD_FILLER:
3843303a28cSColomban Wendling /* nothing, just ignore those in following cases */;
3853303a28cSColomban Wendling break;
3863303a28cSColomban Wendling
3873303a28cSColomban Wendling default:
3883303a28cSColomban Wendling if (isNumeric (word, &levelNumber))
3893303a28cSColomban Wendling {
3903303a28cSColomban Wendling READ_WORD (word, keyword);
3913303a28cSColomban Wendling SKIP_SPACES ();
3923303a28cSColomban Wendling
3933303a28cSColomban Wendling if (*word && keyword != KEYWORD_FILLER)
394e57cf27dSColomban Wendling {
395ec945a05SColomban Wendling int kind = KIND_GHOST_INDEX;
396ec945a05SColomban Wendling
3973303a28cSColomban Wendling if (*line == '.')
398ec945a05SColomban Wendling kind = K_GROUP;
3993303a28cSColomban Wendling else
400e57cf27dSColomban Wendling {
4013303a28cSColomban Wendling int keyword2;
4023303a28cSColomban Wendling
4033303a28cSColomban Wendling READ_KEYWORD (keyword2);
4043303a28cSColomban Wendling switch (keyword2)
405e57cf27dSColomban Wendling {
406e57cf27dSColomban Wendling case KEYWORD_BLANK:
407e57cf27dSColomban Wendling case KEYWORD_OCCURS:
408e57cf27dSColomban Wendling case KEYWORD_IS:
409e57cf27dSColomban Wendling case KEYWORD_JUST:
410e57cf27dSColomban Wendling case KEYWORD_PIC:
411e57cf27dSColomban Wendling case KEYWORD_REDEFINES:
412e57cf27dSColomban Wendling case KEYWORD_RENAMES:
413e57cf27dSColomban Wendling case KEYWORD_SIGN:
414e57cf27dSColomban Wendling case KEYWORD_SYNC:
415e57cf27dSColomban Wendling case KEYWORD_USAGE:
416e57cf27dSColomban Wendling case KEYWORD_VALUE:
417ec945a05SColomban Wendling kind = K_DATA;
418e57cf27dSColomban Wendling }
419e57cf27dSColomban Wendling }
420ec945a05SColomban Wendling
421ec945a05SColomban Wendling if (kind != KIND_GHOST_INDEX)
422ec945a05SColomban Wendling {
423ec945a05SColomban Wendling NestingLevel *nl;
424ec945a05SColomban Wendling tagEntryInfo entry;
425ec945a05SColomban Wendling int r;
426407b0a02SColomban Wendling unsigned int nestingLevelNumber;
427ec945a05SColomban Wendling
428407b0a02SColomban Wendling /* for nesting purposes, level 77 is identical to 1,
429407b0a02SColomban Wendling * and 66 to 2 */
430407b0a02SColomban Wendling switch (levelNumber)
431407b0a02SColomban Wendling {
432407b0a02SColomban Wendling default: nestingLevelNumber = levelNumber; break;
433407b0a02SColomban Wendling case 77: nestingLevelNumber = 1; break;
434407b0a02SColomban Wendling case 66: nestingLevelNumber = 2; break;
435407b0a02SColomban Wendling }
436407b0a02SColomban Wendling
437407b0a02SColomban Wendling nl = popNestingLevelsToLevelNumber (levels, nestingLevelNumber);
4383303a28cSColomban Wendling initCOBOLTagEntry (&entry, word, kind);
439407b0a02SColomban Wendling if (nl && CBL_NL (nl) < nestingLevelNumber)
440ec945a05SColomban Wendling entry.extensionFields.scopeIndex = nl->corkIndex;
441ec945a05SColomban Wendling r = makeTagEntry (&entry);
442407b0a02SColomban Wendling if (levelNumber < 50 /* exclude special levels */)
443407b0a02SColomban Wendling {
444ec945a05SColomban Wendling nl = nestingLevelsPush (levels, r);
4453303a28cSColomban Wendling CBL_NL (nl) = levelNumber;
4463303a28cSColomban Wendling }
4473303a28cSColomban Wendling }
4483303a28cSColomban Wendling }
449407b0a02SColomban Wendling }
4503303a28cSColomban Wendling else if (*word && *line == '.')
4513303a28cSColomban Wendling makeCOBOLTag (word, K_PARAGRAPH);
4523303a28cSColomban Wendling else
4533303a28cSColomban Wendling {
4543303a28cSColomban Wendling int keyword2;
455ec945a05SColomban Wendling
4563303a28cSColomban Wendling READ_KEYWORD (keyword2);
4573303a28cSColomban Wendling SKIP_SPACES ();
4583303a28cSColomban Wendling
4593303a28cSColomban Wendling if (keyword2 == KEYWORD_DIVISION && *line == '.')
4603303a28cSColomban Wendling makeCOBOLTag (word, K_DIVISION);
4613303a28cSColomban Wendling else if (keyword2 == KEYWORD_SECTION && *line == '.')
4623303a28cSColomban Wendling makeCOBOLTag (word, K_SECTION);
463ec945a05SColomban Wendling }
464e57cf27dSColomban Wendling }
465e57cf27dSColomban Wendling }
466e57cf27dSColomban Wendling
467ec945a05SColomban Wendling nestingLevelsFree (levels);
4683303a28cSColomban Wendling cblppDeinit ();
469e167948bSMasatake YAMATO }
470e167948bSMasatake YAMATO
findCOBOLFixedTags(void)471174851b3SColomban Wendling static void findCOBOLFixedTags (void)
472174851b3SColomban Wendling {
473174851b3SColomban Wendling findCOBOLTags (FORMAT_FIXED);
474174851b3SColomban Wendling }
475174851b3SColomban Wendling
findCOBOLFreeTags(void)476174851b3SColomban Wendling static void findCOBOLFreeTags (void)
477174851b3SColomban Wendling {
478174851b3SColomban Wendling findCOBOLTags (FORMAT_FREE);
479174851b3SColomban Wendling }
480174851b3SColomban Wendling
findCOBOLVariableTags(void)481174851b3SColomban Wendling static void findCOBOLVariableTags (void)
482174851b3SColomban Wendling {
483174851b3SColomban Wendling findCOBOLTags (FORMAT_VARIABLE);
484174851b3SColomban Wendling }
485174851b3SColomban Wendling
initializeCobolParser(langType language)48695ecd0e1SMasatake YAMATO static void initializeCobolParser (langType language)
48795ecd0e1SMasatake YAMATO {
488e57cf27dSColomban Wendling Lang_cobol = language;
48995ecd0e1SMasatake YAMATO }
49095ecd0e1SMasatake YAMATO
commonCobolParserDefinition(const char * name,simpleParser parser)491174851b3SColomban Wendling static parserDefinition* commonCobolParserDefinition (const char *name,
492174851b3SColomban Wendling simpleParser parser)
4933ae02089SMasatake YAMATO {
494174851b3SColomban Wendling parserDefinition* def = parserNew (name);
49595ecd0e1SMasatake YAMATO def->initialize = initializeCobolParser;
496174851b3SColomban Wendling def->parser = parser;
49709ae690fSMasatake YAMATO def->kindTable = CobolKinds;
49895ecd0e1SMasatake YAMATO def->kindCount = ARRAY_SIZE(CobolKinds);
49995ecd0e1SMasatake YAMATO def->keywordTable = cobolKeywordTable;
50095ecd0e1SMasatake YAMATO def->keywordCount = ARRAY_SIZE(cobolKeywordTable);
501ec945a05SColomban Wendling def->useCork = CORK_QUEUE;
5023ae02089SMasatake YAMATO return def;
5033ae02089SMasatake YAMATO }
504174851b3SColomban Wendling
CobolParser(void)505174851b3SColomban Wendling extern parserDefinition* CobolParser (void)
506174851b3SColomban Wendling {
507174851b3SColomban Wendling static const char *const extensions [] = {
508174851b3SColomban Wendling "cbl", "cob", "CBL", "COB", NULL };
509174851b3SColomban Wendling parserDefinition* def = commonCobolParserDefinition ("Cobol",
510174851b3SColomban Wendling findCOBOLFixedTags);
511174851b3SColomban Wendling def->extensions = extensions;
512174851b3SColomban Wendling return def;
513174851b3SColomban Wendling }
514174851b3SColomban Wendling
CobolFreeParser(void)515174851b3SColomban Wendling extern parserDefinition* CobolFreeParser (void)
516174851b3SColomban Wendling {
517174851b3SColomban Wendling return commonCobolParserDefinition ("CobolFree", findCOBOLFreeTags);
518174851b3SColomban Wendling }
519174851b3SColomban Wendling
CobolVariableParser(void)520174851b3SColomban Wendling extern parserDefinition* CobolVariableParser (void)
521174851b3SColomban Wendling {
522174851b3SColomban Wendling return commonCobolParserDefinition ("CobolVariable", findCOBOLVariableTags);
523174851b3SColomban Wendling }
524