1 /*
2  * Copyright (c) 2005-2019, NVIDIA CORPORATION.  All rights reserved.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  */
17 
18 /*  define structures and data for keyword processing: */
19 
20 typedef struct {
21   char *keytext;       /* keyword text in lower case */
22   int toktyp;          /* token id (as used in parse tables) */
23   LOGICAL nonstandard; /* TRUE if nonstandard (extension to f90) */
24 } KWORD;
25 
26 typedef struct {
27   int kcount;  /* number of keywords in this table */
28   KWORD *kwds; /* pointer to first in array of KWORD */
29                /* the following members are filled in by init_ktable() to record
30                 * the indices of the first and last keywords beginning with a
31                 * certain letter.   If first[] is zero, there does not exist a
32                 * keyword which begins with the respective letter.  A nonzero
33                 * value is the index into the keyword table.
34                 */
35   short first[26]; /* indexed by ('a' ... 'z') - 'a' */
36   short last[26];  /* indexed by ('a' ... 'z') - 'a' */
37 } KTABLE;
38 
39 /* NOTE:  When entering keywords in the tables, two or more consecutive tokens
40  * that can be seen in the grammar should be combined into a single token.
41  * This is because the keyword search routine is not designed to extract two
42  * or more tokens from a single identifier. For example, consider the
43  * statement  DO WHILE ( <expr> ).  One way of looking at the statement is
44  * that it begins with the two keywords DO and WHILE.  The routine alpha
45  * sees the name DOWHILE; relevant tokens are "do", "doublecomplex", and
46  * "doubleprecision".  When the keyword search routine looks at "dowhile",
47  * it determines that it should look AFTER "doubleprecision" --- the character
48  * 'w' is greater than 'u'.  Consequently, no keyword, in particular DO, is
49  * found.   For the statement, DO 10 WHILE ( <expr> ), the keyword DO is
50  * found in "do10while";  it is determined that it must look BEFORE
51  * "doublecomplex" ('1' < 'u').  DO statements of the form,
52  *     DO <var> =
53  * are not a problem because of the '='; the keyword DO is found as a special
54  * case in routine alpha since there is an "exposed" equals sign.
55  *
56  * If a keyword is a prefix of another keyword, it is possible that the
57  * keyword search routine will not find the 'shorter' prefix of an identifier.
58  * E.g.,  real and realign are keywords
59  *        The identifier realpi will not be found since 'realpi' > 'realign';
60  *        the search routine searches past realign instead of before.
61  * For cases like this, the keyword table must only contain the 'shorter'
62  * prefix; it's up to alpha() to determine look for the additional keywords;
63  * e.g., 'realign' is 'real' followed by 'ign'.
64  *
65  */
66 
67 /*
68  * When the input is freeform, certain keywords may contain blanks.
69  * For those whose 'first' ident is also a keyword, the processing in
70  * alpha() will search ahead to determine if what follows is an ident
71  * which can be combined with 'first' to form a keyword; e.g.,
72  *     end if, end program, etc.
73  * There are a few whose 'first' ident is not a keyword.  For these,
74  * define special macros (TKF_ ...) and initialize in the keyword
75  * table and let alpha() do the rest.  (NOTE that 0 is returned by
76  * keyword() if a name is not found in a keyword table).
77  */
78 #define TKF_ARRAY -1
79 #define TKF_ATOMIC -2
80 #define TKF_CANCELLATION -3
81 #define TKF_DISTPAR -4
82 #define TKF_DOCONCURRENT -5
83 #define TKF_DOUBLE -6
84 #define TKF_DOWHILE -7
85 #define TKF_ENDDISTPAR -8
86 #define TKF_GO -9
87 #define TKF_NO -10
88 #define TKF_SELECT -11
89 #define TKF_TARGETENTER -12
90 #define TKF_TARGETEXIT -13
91 #define TKF_BLOCK -14
92 #define TKF_ENDBLOCK -15
93 
94 static KWORD t1[] = {         /* normal keyword table */
95                      {"", 0}, /* a keyword index must be nonzero */
96                      {"abstract", TK_ABSTRACT},
97                      {"accept", TK_ACCEPT},
98                      {"align", TK_ALIGN},
99                      {"allocatable", TK_ALLOCATABLE},
100                      {"allocate", TK_ALLOCATE},
101                      {"array", TKF_ARRAY},
102                      {"assign", TK_ASSIGN},
103                      {"associate", TK_ASSOCIATE},
104                      {"asynchronous", TK_ASYNCHRONOUS},
105                      {"backspace", TK_BACKSPACE},
106                      {"bind", TK_BIND},
107                      {"block", TKF_BLOCK},
108                      {"blockdata", TK_BLOCKDATA},
109                      {"byte", TK_BYTE},
110                      {"call", TK_CALL},
111                      {"case", TK_CASE},
112                      {"casedefault", TK_CASEDEFAULT},
113                      {"character", TK_CHARACTER},
114                      {"class", TK_CLASS},
115                      {"close", TK_CLOSE},
116                      {"common", TK_COMMON},
117                      {"complex", TK_COMPLEX},
118                      {"concurrent", TK_CONCURRENT},
119                      {"contains", TK_CONTAINS},
120                      {"contiguous", TK_CONTIGUOUS},
121                      {"continue", TK_CONTINUE},
122                      {"cycle", TK_CYCLE},
123                      {"data", TK_DATA},
124                      {"deallocate", TK_DEALLOCATE},
125                      {"decode", TK_DECODE},
126                      {"default", TK_DEFAULT},
127                      {"dimension", TK_DIMENSION},
128                      {"do", TK_DO},
129                      {"doconcurrent", TKF_DOCONCURRENT},
130                      {"double", TKF_DOUBLE},
131                      {"doublecomplex", TK_DBLECMPLX},
132                      {"doubleprecision", TK_DBLEPREC},
133                      {"dowhile", TKF_DOWHILE},
134                      {"elemental", TK_ELEMENTAL},
135                      {"else", TK_ELSE},
136                      {"elseforall", TK_FORALL},
137                      {"elseif", TK_ELSEIF},
138                      {"elsewhere", TK_ELSEWHERE},
139                      {"encode", TK_ENCODE},
140                      {"end", TK_ENDSTMT},
141                      {"endassociate", TK_ENDASSOCIATE},
142                      {"endblock", TKF_ENDBLOCK},
143                      {"endblockdata", TK_ENDBLOCKDATA},
144                      {"enddo", TK_ENDDO},
145                      {"endenum", TK_ENDENUM},
146                      {"endfile", TK_ENDFILE},
147                      {"endforall", TK_ENDFORALL},
148                      {"endfunction", TK_ENDFUNCTION},
149                      {"endif", TK_ENDIF},
150                      {"endinterface", TK_ENDINTERFACE},
151                      {"endmap", TK_ENDMAP},
152                      {"endmodule", TK_ENDMODULE},
153                      {"endprocedure", TK_ENDPROCEDURE},
154                      {"endprogram", TK_ENDPROGRAM},
155                      {"endselect", TK_ENDSELECT},
156                      {"endstructure", TK_ENDSTRUCTURE},
157                      {"endsubmodule", TK_ENDSUBMODULE},
158                      {"endsubroutine", TK_ENDSUBROUTINE},
159                      {"endtype", TK_ENDTYPE},
160                      {"endunion", TK_ENDUNION},
161                      {"endwhere", TK_ENDWHERE},
162                      {"entry", TK_ENTRY},
163                      {"enum", TK_ENUM},
164                      {"enumerator", TK_ENUMERATOR},
165                      {"equivalence", TK_EQUIV},
166                      {"errorstop", TK_ERRORSTOP},
167                      {"exit", TK_EXIT},
168                      {"extends", TK_EXTENDS},
169                      {"external", TK_EXTERNAL},
170                      {"final", TK_FINAL},
171                      {"flush", TK_FLUSH},
172                      {"forall", TK_FORALL},
173                      {"format", TK_FORMAT},
174                      {"function", TK_FUNCTION},
175                      {"generic", TK_GENERIC},
176                      {"go", TKF_GO},
177                      {"goto", TK_GOTO},
178                      {"if", TK_IF},
179                      {"implicit", TK_IMPLICIT},
180                      {"import", TK_IMPORT},
181                      {"impure", TK_IMPURE},
182                      {"include", TK_INCLUDE},
183                      {"independent", TK_INDEPENDENT},
184                      {"inquire", TK_INQUIRE},
185                      {"integer", TK_INTEGER},
186                      {"intent", TK_INTENT},
187                      {"interface", TK_INTERFACE},
188                      {"intrinsic", TK_INTRINSIC},
189                      {"local", TK_LOCAL},
190                      {"local_init", TK_LOCAL_INIT},
191                      {"logical", TK_LOGICAL},
192                      {"map", TK_MAP},
193                      {"module", TK_MODULE},
194                      {"namelist", TK_NAMELIST},
195                      {"ncharacter", TK_NCHARACTER},
196                      {"no", TKF_NO},
197                      {"non_intrinsic", TK_NON_INTRINSIC},
198                      {"none", TK_NONE},
199                      {"nopass", TK_NOPASS},
200                      {"nosequence", TK_NOSEQUENCE},
201                      {"nullify", TK_NULLIFY},
202                      {"open", TK_OPEN},
203                      {"optional", TK_OPTIONAL},
204                      {"options", TK_OPTIONS},
205                      {"parameter", TK_PARAMETER},
206                      {"pass", TK_PASS},
207                      {"pause", TK_PAUSE},
208                      {"pointer", TK_POINTER},
209                      {"print", TK_PRINT},
210                      {"private", TK_PRIVATE},
211                      {"procedure", TK_PROCEDURE},
212                      {"program", TK_PROGRAM},
213                      {"protected", TK_PROTECTED},
214                      {"public", TK_PUBLIC},
215                      {"pure", TK_PURE},
216                      {"quiet", TK_QUIET},
217                      {"read", TK_READ},
218                      {"real", TK_REAL},
219                      {"record", TK_RECORD},
220                      {"recursive", TK_RECURSIVE},
221                      {"return", TK_RETURN},
222                      {"rewind", TK_REWIND},
223                      {"save", TK_SAVE},
224                      {"select", TKF_SELECT},
225                      {"selectcase", TK_SELECTCASE},
226                      {"selecttype", TK_SELECTTYPE},
227                      {"sequence", TK_SEQUENCE},
228                      {"shared", TK_SHARED},
229                      {"stop", TK_STOP},
230                      {"structure", TK_STRUCTURE},
231                      {"submodule", TK_SUBMODULE},
232                      {"subroutine", TK_SUBROUTINE},
233                      {"target", TK_TARGET},
234                      {"then", TK_THEN},
235                      {"type", TK_TYPE},
236                      {"union", TK_UNION},
237                      {"use", TK_USE},
238                      {"value", TK_VALUE},
239                      {"volatile", TK_VOLATILE},
240                      {"wait", TK_WAIT},
241                      {"where", TK_WHERE},
242                      {"while", TK_WHILE},
243                      {"write", TK_WRITE}};
244 
245 static KWORD t2[] = {         /* logical keywords */
246                      {"", 0}, /* a keyword index must be nonzero */
247                      {"a", TK_AND, TRUE},
248                      {"and", TK_AND, FALSE},
249                      {"eq", TK_EQ, FALSE},
250                      {"eqv", TK_EQV, FALSE},
251                      {"f", TK_LOGCONST, TRUE},
252                      {"false", TK_LOGCONST, FALSE},
253                      {"ge", TK_GE, FALSE},
254                      {"gt", TK_GT, FALSE},
255                      {"le", TK_LE, FALSE},
256                      {"lt", TK_LT, FALSE},
257                      {"n", TK_NOTX, TRUE},
258                      {"ne", TK_NE, FALSE},
259                      {"neqv", TK_NEQV, FALSE},
260                      {"not", TK_NOT, FALSE},
261                      {"o", TK_ORX, TRUE},
262                      {"or", TK_OR, FALSE},
263                      {"t", TK_LOGCONST, TRUE},
264                      {"true", TK_LOGCONST, FALSE},
265                      {"x", TK_XORX, TRUE},
266                      {"xor", TK_XOR, TRUE}};
267 
268 static KWORD t3[] = {
269     /* I/O keywords and ALLOCATE keywords */
270     {"", 0}, /* a keyword index must be nonzero */
271     {"access", TK_ACCESS},
272     {"action", TK_ACTION},
273     {"advance", TK_ADVANCE},
274     {"align", TK_ALIGN}, /* ... used in ALLOCATE stmt */
275     {"asynchronous", TK_ASYNCHRONOUS},
276     {"blank", TK_BLANK},
277     {"convert", TK_CONVERT},
278     {"decimal", TK_DECIMAL},
279     {"delim", TK_DELIM},
280     {"direct", TK_DIRECT},
281     {"disp", TK_DISPOSE},
282     {"dispose", TK_DISPOSE},
283     {"encoding", TK_ENCODING},
284     {"end", TK_END},
285     {"eor", TK_EOR},
286     {"err", TK_ERR},
287     {"errmsg", TK_ERRMSG}, /* ... used in ALLOCATE stmt */
288     {"exist", TK_EXIST},
289     {"file", TK_FILE},
290     {"fmt", TK_FMT},
291     {"form", TK_FORM},
292     {"formatted", TK_FMTTD},
293     {"id", TK_ID},
294     {"iolength", TK_IOLENGTH},
295     {"iomsg", TK_IOMSG},
296     {"iostat", TK_IOSTAT},
297     {"mold", TK_MOLD},
298     {"name", TK_NAME},
299     {"named", TK_NAMED},
300     {"newunit", TK_NEWUNIT},
301     {"nextrec", TK_NEXTREC},
302     {"nml", TK_NML},
303     {"number", TK_NUMBER},
304     {"opened", TK_OPENED},
305     {"pad", TK_PAD},
306     {"pending", TK_PENDING},
307     {"pinned", TK_PINNED}, /* ... used in ALLOCATE stmt */
308     {"pos", TK_POS},
309     {"position", TK_POSITION},
310     {"read", TK_READ},
311     {"readonly", TK_READONLY},
312     {"readwrite", TK_READWRITE},
313     {"rec", TK_REC},
314     {"recl", TK_RECL},
315     {"recordsize", TK_RECL}, /* ... identical to RECL    */
316     {"round", TK_ROUND},
317     {"sequential", TK_SEQUENTIAL},
318     {"shared", TK_SHARED},
319     {"sign", TK_SIGN},
320     {"size", TK_SIZE},
321     {"source", TK_SOURCE}, /* ... used in ALLOCATE stmt */
322     {"stat", TK_STAT},     /* ... used in ALLOCATE and DEALLOCATE stmts */
323     {"status", TK_STATUS},
324     {"stream", TK_STREAM},
325     {"type", TK_STATUS}, /* ... identical to STATUS  */
326     {"unformatted", TK_UNFORMATTED},
327     {"unit", TK_UNIT},
328     {"write", TK_WRITE},
329 };
330 
331 static KWORD t4[] = {         /* keywords appearing within a FORMAT stmt: */
332                      {"", 0}, /* a keyword index must be nonzero */
333                      /* {"$", TK_DOLLAR}, special case in alpha() */
334                      {"a", TK_A},
335                      {"b", TK_B},
336                      {"bn", TK_BN},
337                      {"bz", TK_BZ},
338                      {"d", TK_D},
339                      {"dc", TK_DC},
340                      {"dp", TK_DP},
341                      {"dt", TK_DT},
342                      {"e", TK_E},
343                      {"en", TK_EN},
344                      {"es", TK_ES},
345                      {"f", TK_F},
346                      {"g", TK_G},
347                      {"i", TK_I},
348                      {"l", TK_L},
349                      {"n", TK_N},
350                      {"o", TK_O},
351                      {"p", TK_P},
352                      {"q", TK_Q},
353                      {"s", TK_S},
354                      {"rc", TK_RC},
355                      {"rd", TK_RD},
356                      {"rn", TK_RN},
357                      {"rp", TK_RP},
358                      {"ru", TK_RU},
359                      {"rz", TK_RZ},
360                      {"sp", TK_SP},
361                      {"ss", TK_SS},
362                      {"t", TK_T},
363                      {"tl", TK_TL},
364                      {"tr", TK_TR},
365                      {"x", TK_X},
366                      {"z", TK_Z}};
367 
368 static KWORD t5[] = {
369     /* keywords appearing within PARALLEL directives */
370     {"", 0}, /* a keyword index must be nonzero */
371     {"aligned", TK_ALIGNED},
372     {"capture", TK_CAPTURE},
373     {"chunk", TK_CHUNK},
374     {"collapse", TK_COLLAPSE},
375     {"compare", TK_COMPARE},
376     {"copyin", TK_COPYIN},
377     {"copyprivate", TK_COPYPRIVATE},
378     {"default", TK_DEFAULT},
379     {"defaultmap", TK_DEFAULTMAP},
380     {"depend", TK_DEPEND},
381     {"device", TK_DEVICE},
382     {"dist_schedule", TK_DIST_SCHEDULE},
383     {"final", TK_FINAL},
384     {"firstprivate", TK_FIRSTPRIVATE},
385     {"from", TK_FROM},
386     {"grainsize", TK_GRAINSIZE},
387     {"if", TK_IF},
388     {"inbranch", TK_INBRANCH},
389     {"is_device_ptr", TK_IS_DEVICE_PTR},
390     {"lastlocal", TK_LASTPRIVATE},
391     {"lastprivate", TK_LASTPRIVATE},
392     {"linear", TK_LINEAR},
393     {"link", TK_LINK},
394     {"local", TK_PRIVATE},
395     {"map", TK_MP_MAP},
396     {"mergeable", TK_MERGEABLE},
397     {"mp_schedtype", TK_MP_SCHEDTYPE},
398     {"nogroup", TK_NOGROUP},
399     {"notinbranch", TK_NOTINBRANCH},
400     {"nowait", TK_NOWAIT},
401     {"num_tasks", TK_NUM_TASKS},
402     {"num_teams", TK_NUM_TEAMS},
403     {"num_threads", TK_NUM_THREADS},
404     {"ordered", TK_ORDERED},
405     {"priority", TK_PRIORITY},
406     {"private", TK_PRIVATE},
407     {"proc_bind", TK_PROC_BIND},
408     {"read", TK_READ},
409     {"reduction", TK_REDUCTION},
410     {"safelen", TK_SAFELEN},
411     {"schedule", TK_SCHEDULE},
412     {"seq_cst", TK_SEQ_CST},
413     {"share", TK_SHARED},
414     {"shared", TK_SHARED},
415     {"simd", TK_SIMD},
416     {"simdlen", TK_SIMDLEN},
417     {"thread_limit", TK_THREAD_LIMIT},
418     {"threads", TK_THREADS},
419     {"to", TK_TO},
420     {"uniform", TK_UNIFORM},
421     {"untied", TK_UNTIED},
422     {"update", TK_UPDATE},
423     {"write", TK_WRITE},
424 };
425 
426 static KWORD t6[] = {
427     /* keywords beginning OpenMP/PARALLEL directives */
428     {"", 0}, /* a keyword index must be nonzero */
429     {"atomic", TK_MP_ATOMIC},
430     {"barrier", TK_MP_BARRIER},
431     {"cancel", TK_MP_CANCEL},
432     {"cancellation", TKF_CANCELLATION},
433     {"cancellationpoint", TK_MP_CANCELLATIONPOINT},
434     {"critical", TK_MP_CRITICAL},
435     {"declare", TK_DECLARE},
436     {"declarereduction", TK_MP_DECLAREREDUCTION},
437     {"declaresimd", TK_MP_DECLARESIMD},
438     {"declaretarget", TK_MP_DECLARETARGET},
439     {"distribute", TK_MP_DISTRIBUTE},
440     {"distributeparallel", TKF_DISTPAR},
441     {"distributeparalleldo", TK_MP_DISTPARDO},
442     {"distributeparalleldosimd", TK_MP_DISTPARDOSIMD},
443     {"do", TK_MP_PDO},
444     {"doacross", TK_MP_DOACROSS},
445     {"dosimd", TK_MP_DOSIMD},
446     {"end", TK_ENDSTMT},
447     {"endatomic", TK_MP_ENDATOMIC},
448     {"endcritical", TK_MP_ENDCRITICAL},
449     {"enddistribute", TK_MP_ENDDISTRIBUTE},
450     {"enddistributeparallel", TKF_ENDDISTPAR},
451     {"enddistributeparalleldo", TK_MP_ENDDISTPARDO},
452     {"enddistributeparalleldosimd", TK_MP_ENDDISTPARDOSIMD},
453     {"enddo", TK_MP_ENDPDO},
454     {"enddosimd", TK_MP_ENDDOSIMD},
455     {"endmaster", TK_MP_ENDMASTER},
456     {"endordered", TK_MP_ENDORDERED},
457     {"endparallel", TK_MP_ENDPARALLEL},
458     {"endparalleldo", TK_MP_ENDPARDO},
459     {"endparalleldosimd", TK_MP_ENDPARDOSIMD},
460     {"endparallelsections", TK_MP_ENDPARSECTIONS},
461     {"endparallelworkshare", TK_MP_ENDPARWORKSHR},
462     {"endsections", TK_MP_ENDSECTIONS},
463     {"endsimd", TK_MP_ENDSIMD},
464     {"endsingle", TK_MP_ENDSINGLE},
465     {"endtarget", TK_MP_ENDTARGET},
466     {"endtargetdata", TK_MP_ENDTARGETDATA},
467     {"endtargetparallel", TK_MP_ENDTARGPAR},
468     {"endtargetparalleldo", TK_MP_ENDTARGPARDO},
469     {"endtargetparalleldosimd", TK_MP_ENDTARGPARDOSIMD},
470     {"endtargetsimd", TK_MP_ENDTARGSIMD},
471     {"endtargetteams", TK_MP_ENDTARGTEAMS},
472     {"endtargetteamsdistribute", TK_MP_ENDTARGTEAMSDIST},
473     {"endtargetteamsdistributeparalleldo", TK_MP_ENDTARGTEAMSDISTPARDO},
474     {"endtargetteamsdistributeparalleldosimd", TK_MP_ENDTARGTEAMSDISTPARDOSIMD},
475     {"endtargetteamsdistributesimd", TK_MP_ENDTARGTEAMSDISTSIMD},
476     {"endtask", TK_MP_ENDTASK},
477     {"endtaskgroup", TK_MP_ENDTASKGROUP},
478     {"endtaskloop", TK_MP_ENDTASKLOOP},
479     {"endtaskloopsimd", TK_MP_ENDTASKLOOPSIMD},
480     {"endteams", TK_MP_ENDTEAMS},
481     {"endteamsdistribute", TK_MP_ENDTEAMSDIST},
482     {"endteamsdistributeparalleldo", TK_MP_ENDTEAMSDISTPARDO},
483     {"endteamsdistributeparalleldosimd", TK_MP_ENDTEAMSDISTPARDOSIMD},
484     {"endteamsdistributesimd", TK_MP_ENDTEAMSDISTSIMD},
485     {"endworkshare", TK_MP_ENDWORKSHARE},
486     {"flush", TK_MP_FLUSH},
487     {"master", TK_MP_MASTER},
488     {"ordered", TK_MP_ORDERED},
489     {"parallel", TK_MP_PARALLEL},
490     {"paralleldo", TK_MP_PARDO},
491     {"paralleldosimd", TK_MP_PARDOSIMD},
492     {"parallelsections", TK_MP_PARSECTIONS},
493     {"parallelworkshare", TK_MP_PARWORKSHR},
494     {"section", TK_MP_SECTION},
495     {"sections", TK_MP_SECTIONS},
496     {"simd", TK_MP_SIMD},
497     {"single", TK_MP_SINGLE},
498     {"target", TK_MP_TARGET},
499     {"targetdata", TK_MP_TARGETDATA},
500     {"targetenter", TKF_TARGETENTER},
501     {"targetenterdata", TK_MP_TARGETENTERDATA},
502     {"targetexit", TKF_TARGETEXIT},
503     {"targetexitdata", TK_MP_TARGETEXITDATA},
504     {"targetparallel", TK_MP_TARGPAR},
505     {"targetparalleldo", TK_MP_TARGPARDO},
506     {"targetparalleldosimd", TK_MP_TARGPARDOSIMD},
507     {"targetsimd", TK_MP_TARGSIMD},
508     {"targetteams", TK_MP_TARGTEAMS},
509     {"targetteamsdistribute", TK_MP_TARGTEAMSDIST},
510     {"targetteamsdistributeparalleldo", TK_MP_TARGTEAMSDISTPARDO},
511     {"targetteamsdistributeparalleldosimd", TK_MP_TARGTEAMSDISTPARDOSIMD},
512     {"targetteamsdistributesimd", TK_MP_TARGTEAMSDISTSIMD},
513     {"targetupdate", TK_MP_TARGETUPDATE},
514     {"task", TK_MP_TASK},
515     {"taskgroup", TK_MP_TASKGROUP},
516     {"taskloop", TK_MP_TASKLOOP},
517     {"taskloopsimd", TK_MP_TASKLOOPSIMD},
518     {"taskwait", TK_MP_TASKWAIT},
519     {"taskyield", TK_MP_TASKYIELD},
520     {"teams", TK_MP_TEAMS},
521     {"teamsdistribute", TK_MP_TEAMSDIST},
522     {"teamsdistributeparalleldo", TK_MP_TEAMSDISTPARDO},
523     {"teamsdistributeparalleldosimd", TK_MP_TEAMSDISTPARDOSIMD},
524     {"teamsdistributesimd", TK_MP_TEAMSDISTSIMD},
525     {"threadprivate", TK_MP_THREADPRIVATE},
526     {"workshare", TK_MP_WORKSHARE},
527 };
528 
529 static KWORD t7[] = {
530     /* keywords which begin a 'cdec$' directive */
531     {"", 0}, /* a keyword index must be nonzero */
532     {"alias", TK_ALIAS},
533     {"attributes", TK_ATTRIBUTES},
534     {"craydistributepoint", TK_DISTRIBUTEPOINT},
535     {"distribute", TK_DISTRIBUTE},
536     {"distributepoint", TK_DISTRIBUTEPOINT},
537 };
538 
539 static KWORD t8[] = {
540     /* keywords which begin other directives */
541     {"", 0}, /* a keyword index must be nonzero */
542     {"local", TK_LOCAL},
543     {"prefetch", TK_PREFETCH},
544 };
545 
546 static KWORD t9[] = {
547     /* keywords for parsed PGI pragmas */
548     {"", 0}, /* a keyword index must be nonzero */
549     {"defaultkind", TK_DFLT},
550     {"ignore_tkr", TK_IGNORE_TKR},
551     {"movedesc", TK_MOVEDESC},
552     {"prefetch", TK_PREFETCH},
553 };
554 
555 static KWORD t11[] = {
556     /* keywords for kernel directives */
557     {"", 0}, /* a keyword index must be nonzero */
558     {"do", TK_DO},
559     {"kernel", TK_KERNEL},
560     {"nowait", TK_NOWAIT},
561 };
562 
563 static KWORD t12[] = {
564     {"", 0}, /* a keyword index must be nonzero */
565     {"compare", TK_PGICOMPARE},
566 };
567 
568 /* ****  NOTE -- each of these must appear in a call to init_ktable() in
569  *               scan_init().
570  */
571 static KTABLE normalkw = {sizeof(t1) / sizeof(KWORD), &t1[0]};
572 static KTABLE logicalkw = {sizeof(t2) / sizeof(KWORD), &t2[0]};
573 static KTABLE iokw = {sizeof(t3) / sizeof(KWORD), &t3[0]};
574 static KTABLE formatkw = {sizeof(t4) / sizeof(KWORD), &t4[0]};
575 static KTABLE parallelkw = {sizeof(t5) / sizeof(KWORD), &t5[0]};
576 static KTABLE parbegkw = {sizeof(t6) / sizeof(KWORD), &t6[0]};
577 static KTABLE deckw = {sizeof(t7) / sizeof(KWORD), &t7[0]};
578 static KTABLE pragma_kw = {sizeof(t8) / sizeof(KWORD), &t8[0]};
579 static KTABLE ppragma_kw = {sizeof(t9) / sizeof(KWORD), &t9[0]};
580 static KTABLE kernel_kw = {sizeof(t11) / sizeof(KWORD), &t11[0]};
581 static KTABLE pgi_kw = {sizeof(t12) / sizeof(KWORD), &t12[0]};
582 
583 /* char classification macros */
584 
585 #undef _CS
586 #undef _DI
587 #undef _BL
588 #undef _HD
589 #undef _HO
590 
591 #define _CS 1  /* alpha symbol */
592 #define _DI 2  /* digit */
593 #define _BL 4  /* blank */
594 #define _HD 8  /* hex digit */
595 #define _HO 16 /* Hollerith constant indicator */
596 
597 #undef iscsym
598 #define iscsym(c) (ctable[c] & _CS)
599 #undef isblank
600 #define isblank(c) (ctable[c] & _BL)
601 #undef iswhite
602 #define iswhite(c) ((c) <= ' ')
603 #define ishex(c) (ctable[c] & (_HD | _DI))
604 #define isident(c) (ctable[c] & (_CS | _DI))
605 #define isdig(c) (ctable[c] & _DI)
606 #define isodigit(c) ((c) >= '0' && (c) <= '7')
607 #define isholl(c) (ctable[c] & _HO)
608 
609 static char ctable[256] = {
610     0,         /* nul */
611     0,         /* soh */
612     0,         /* stx */
613     0,         /* etx */
614     0,         /* eot */
615     0,         /* enq */
616     0,         /* ack */
617     0,         /* bel */
618     0,         /* bs  */
619     _BL,       /* ht  */
620     0,         /* nl  */
621     _BL,       /* vt  */
622     _BL,       /* np  */
623     _BL,       /* cr  */
624     0,         /* so  */
625     0,         /* si  */
626     0,         /* dle */
627     0,         /* dc1 */
628     0,         /* dc2 */
629     0,         /* dc3 */
630     0,         /* dc4 */
631     0,         /* nak */
632     0,         /* syn */
633     0,         /* etb */
634     0,         /* can */
635     0,         /* em  */
636     0,         /* sub */
637     0,         /* esc */
638     0,         /* fs  */
639     0,         /* gs  */
640     0,         /* rs  */
641     0,         /* us  */
642     _BL,       /* sp  */
643     0,         /* !  */
644     0,         /* "  */
645     0,         /* #  */
646     _CS,       /* $  */
647     0,         /* %  */
648     0,         /* &  */
649     0,         /* '  */
650     0,         /* (  */
651     0,         /* )  */
652     0,         /* *  */
653     0,         /* +  */
654     0,         /* ,  */
655     0,         /* -  */
656     0,         /* .  */
657     0,         /* /  */
658     _DI,       /* 0  */
659     _DI,       /* 1  */
660     _DI,       /* 2  */
661     _DI,       /* 3  */
662     _DI,       /* 4  */
663     _DI,       /* 5  */
664     _DI,       /* 6  */
665     _DI,       /* 7  */
666     _DI,       /* 8  */
667     _DI,       /* 9  */
668     0,         /* :  */
669     0,         /* ;  */
670     0,         /* <  */
671     0,         /* =  */
672     0,         /* >  */
673     0,         /* ?  */
674     0,         /* @  */
675     _CS | _HD, /* A  */
676     _CS | _HD, /* B  */
677     _CS | _HD, /* C  */
678     _CS | _HD, /* D  */
679     _CS | _HD, /* E  */
680     _CS | _HD, /* F  */
681     _CS,       /* G  */
682     _CS | _HO, /* H  */
683     _CS,       /* I  */
684     _CS,       /* J  */
685     _CS,       /* K  */
686     _CS,       /* L  */
687     _CS,       /* M  */
688     _CS,       /* N  */
689     _CS,       /* O  */
690     _CS,       /* P  */
691     _CS,       /* Q  */
692     _CS,       /* R  */
693     _CS,       /* S  */
694     _CS,       /* T  */
695     _CS,       /* U  */
696     _CS,       /* V  */
697     _CS,       /* W  */
698     _CS,       /* X  */
699     _CS,       /* Y  */
700     _CS,       /* Z  */
701     0,         /* [  */
702     0,         /* \  */
703     0,         /* ]  */
704     0,         /* ^  */
705     _CS,       /* _  */
706     0,         /* `  */
707     _CS | _HD, /* a  */
708     _CS | _HD, /* b  */
709     _CS | _HD, /* c  */
710     _CS | _HD, /* d  */
711     _CS | _HD, /* e  */
712     _CS | _HD, /* f  */
713     _CS,       /* g  */
714     _CS | _HO, /* h  */
715     _CS,       /* i  */
716     _CS,       /* j  */
717     _CS,       /* k  */
718     _CS,       /* l  */
719     _CS,       /* m  */
720     _CS,       /* n  */
721     _CS,       /* o  */
722     _CS,       /* p  */
723     _CS,       /* q  */
724     _CS,       /* r  */
725     _CS,       /* s  */
726     _CS,       /* t  */
727     _CS,       /* u  */
728     _CS,       /* v  */
729     _CS,       /* w  */
730     _CS,       /* x  */
731     _CS,       /* y  */
732     _CS,       /* z  */
733     0,         /* {  */
734     0,         /* |  */
735     0,         /* }  */
736     0,         /* ~  */
737     0,         /* del */
738 };
739