2 ** Splint - annotation-assisted static program checker
3 ** Copyright (C) 1994-2003 University of Virginia,
4 ** Massachusetts Institute of Technology
6 ** This program is free software; you can redistribute it and/or modify it
7 ** under the terms of the GNU General Public License as published by the
8 ** Free Software Foundation; either version 2 of the License, or (at your
9 ** option) any later version.
11 ** This program is distributed in the hope that it will be useful, but
12 ** WITHOUT ANY WARRANTY; without even the implied warranty of
13 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 ** General Public License for more details.
16 ** The GNU General Public License is available from http://www.gnu.org/ or
17 ** the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
18 ** MA 02111-1307, USA.
20 ** For information on splint: info@splint.org
21 ** To report a bug: splint-bug@splint.org
22 ** For more information: http://www.splint.org
27 ** Processor for Larch Shared Language Init Files
30 # include "splintMacros.nf"
32 # include "signature.h"
33 # include "signature2.h"
35 # include "scanline.h"
36 # include "tokentable.h"
37 # include "syntable.h"
41 # include "lclscanline.h"
42 # include "lclsyntable.h"
43 # include "lcltokentable.h"
45 /* needed to parse init files */
49 # define LTRACE(rule) printf ("Reducing: %s\n", rule)
55 static void LocalUserError (ltoken p_t, /*@temp@*/ char *p_msg)
56 /*@modifies *g_warningstream@*/;
58 static /*@only@*/ ltoken nextToken;
60 static /*@only@*/ /*@null@*/ inputStream s_initFile = inputStream_undefined;
62 static void InitFile (void) /*@modifies nextToken@*/ ;
63 static void InitLines (void) /*@modifies nextToken@*/ ;
64 static void InitLine (void) /*@modifies nextToken@*/ ;
65 static void Classification (void) /*@modifies nextToken@*/ ;
66 static void CharClass (void) /*@modifies nextToken@*/ ;
68 static void EndCommentChars (void) /*@modifies nextToken@*/ ;
69 static void IdChars (void) /*@modifies nextToken@*/ ;
70 static void OpChars (void) /*@modifies nextToken@*/ ;
71 static void ExtensionChar (void) /*@modifies nextToken@*/ ;
72 static void SingChars (void) /*@modifies nextToken@*/ ;
73 static void WhiteChars (void) /*@modifies nextToken@*/ ;
74 static void EndCommentChar (void) /*@modifies nextToken@*/ ;
75 static void IdChar (void) /*@modifies nextToken@*/ ;
76 static void OpChar (void) /*@modifies nextToken@*/ ;
77 static void SingChar (void) /*@modifies nextToken@*/ ;
78 static void WhiteChar (void) /*@modifies nextToken@*/ ;
80 static void TokenClass (void) /*@modifies nextToken@*/ ;
81 static void QuantifierSymToks (void) /*@modifies nextToken@*/ ;
82 static void LogicalOpToks (void) /*@modifies nextToken@*/ ;
83 static void EqOpToks (void) /*@modifies nextToken@*/ ;
84 static void EquationSymToks (void) /*@modifies nextToken@*/ ;
85 static void EqSepSymToks (void) /*@modifies nextToken@*/ ;
86 static void SelectSymToks (void) /*@modifies nextToken@*/ ;
87 static void OpenSymToks (void) /*@modifies nextToken@*/ ;
88 static void SepSymToks (void) /*@modifies nextToken@*/ ;
89 static void CloseSymToks (void) /*@modifies nextToken@*/ ;
90 static void SimpleIdToks (void) /*@modifies nextToken@*/ ;
91 static void MapSymToks (void) /*@modifies nextToken@*/ ;
92 static void MarkerSymToks (void) /*@modifies nextToken@*/ ;
93 static void CommentSymToks (void) /*@modifies nextToken@*/ ;
94 static void QuantifierSymTok (void) /*@modifies nextToken@*/ ;
95 static void LogicalOpTok (void) /*@modifies nextToken@*/ ;
96 static void EqOpTok (void) /*@modifies nextToken@*/ ;
97 static void EquationSymTok (void) /*@modifies nextToken@*/ ;
98 static void EqSepSymTok (void) /*@modifies nextToken@*/ ;
99 static void SelectSymTok (void) /*@modifies nextToken@*/ ;
100 static void OpenSymTok (void) /*@modifies nextToken@*/ ;
101 static void SepSymTok (void) /*@modifies nextToken@*/ ;
102 static void CloseSymTok (void) /*@modifies nextToken@*/ ;
103 static void SimpleIdTok (void) /*@modifies nextToken@*/ ;
104 static void MapSymTok (void) /*@modifies nextToken@*/ ;
105 static void MarkerSymTok (void) /*@modifies nextToken@*/ ;
106 static void CommentSymTok (void) /*@modifies nextToken@*/ ;
107 static void SynClass (void) /*@modifies nextToken@*/ ;
108 static void OldToken (void) /*@modifies nextToken@*/ ;
109 static void NewToken (void) /*@modifies nextToken@*/ ;
110 static void Token (void) /*@modifies nextToken@*/ ;
112 static void InitReduce (LSLInitRuleCode p_rule) /*@modifies nextToken@*/ ;
113 static void UpdateXCharKeywords (charCode) /*@modifies nextToken@*/ ;
114 static void ProcessExtensionChar (void) /*@modifies nextToken@*/ ;
115 static void ProcessEndCommentChar (void) /*@modifies nextToken@*/ ;
116 static void ProcessSingleChar (charCode p_code) /*@modifies nextToken@*/ ;
117 static void ProcessToken (ltokenCode p_code) /*@modifies nextToken@*/ ;
118 static void ProcessSynonym (void) /*@modifies nextToken@*/ ;
120 /* If TRUE character has been redefined as a singleChar. */
121 static bool defineSingleChar[LASTCHAR + 1];
123 static charCode currentExtensionChar;
125 /* LSL init file keyword tokens. */
127 static /*@dependent@*/ ltoken endCommentCharToken;
128 static /*@dependent@*/ ltoken idCharToken;
129 static /*@dependent@*/ ltoken opCharToken;
130 static /*@dependent@*/ ltoken extensionCharToken;
131 static /*@dependent@*/ ltoken singleCharToken;
132 static /*@dependent@*/ ltoken whiteCharToken;
133 static /*@dependent@*/ ltoken quantifierSymToken;
134 static /*@dependent@*/ ltoken logicalOpToken;
135 static /*@dependent@*/ ltoken eqOpToken;
136 static /*@dependent@*/ ltoken equationSymToken;
137 static /*@dependent@*/ ltoken eqSepSymToken;
138 static /*@dependent@*/ ltoken selectSymToken;
139 static /*@dependent@*/ ltoken openSymToken;
140 static /*@dependent@*/ ltoken sepSymToken;
141 static /*@dependent@*/ ltoken closeSymToken;
142 static /*@dependent@*/ ltoken simpleIdToken;
143 static /*@dependent@*/ ltoken mapSymToken;
144 static /*@dependent@*/ ltoken markerSymToken;
145 static /*@dependent@*/ ltoken commentSymToken;
146 static /*@dependent@*/ ltoken synonymToken;
149 hasFirstChar (ltoken tok)
151 return (ltoken_isChar (tok)
152 && lscanCharClass (cstring_firstChar (ltoken_unparse (tok))) == SINGLECHAR);
156 lslinit_setInitFile (inputStream s)
158 llassert (inputStream_isUndefined (s_initFile));
164 ** Parsing functions for init file processing, in the same order as the
165 ** grammar file lslinit.cfg. This is top-down order, as much as possible.
169 static void lslinit_processInitFile (void)
172 InitReduce (INITFILE1);
174 if (ltoken_getCode (nextToken) != LEOFTOKEN)
176 LocalUserError (nextToken, "unexpected tokens after end-of-file");
183 InitReduce (INITLINES1);
185 if (ltoken_getCode (nextToken) != LEOFTOKEN)
188 InitReduce (INITLINES2);
191 while (ltoken_getCode (nextToken) != LEOFTOKEN)
194 InitReduce (INITLINES3);
202 if (ltoken_getCode (nextToken) == LST_EOL)
204 /* Nothing on line. */
205 InitReduce (INITLINE1);
210 InitReduce (INITLINE2);
213 if (ltoken_getCode (nextToken) != LST_EOL)
215 LocalUserError (nextToken, "Unexpected tokens on line");
218 ltoken_free (nextToken);
219 nextToken = LSLScanNextToken ();
223 Classification (void)
225 if (ltoken_getRawText (nextToken) == ltoken_getText (endCommentCharToken)
226 || ltoken_getRawText (nextToken) == ltoken_getText (idCharToken)
227 || ltoken_getRawText (nextToken) == ltoken_getText (opCharToken)
228 || ltoken_getRawText (nextToken) == ltoken_getText (extensionCharToken)
229 || ltoken_getRawText (nextToken) == ltoken_getText (singleCharToken)
230 || ltoken_getRawText (nextToken) == ltoken_getText (whiteCharToken))
233 InitReduce (CLASSIFICATION1);
235 else if (ltoken_getRawText (nextToken) == ltoken_getText (quantifierSymToken)
236 || ltoken_getRawText (nextToken) == ltoken_getText (logicalOpToken)
237 || ltoken_getRawText (nextToken) == ltoken_getText (eqOpToken)
238 || ltoken_getRawText (nextToken) == ltoken_getText (equationSymToken)
239 || ltoken_getRawText (nextToken) == ltoken_getText (eqSepSymToken)
240 || ltoken_getRawText (nextToken) == ltoken_getText (selectSymToken)
241 || ltoken_getRawText (nextToken) == ltoken_getText (openSymToken)
242 || ltoken_getRawText (nextToken) == ltoken_getText (sepSymToken)
243 || ltoken_getRawText (nextToken) == ltoken_getText (closeSymToken)
244 || ltoken_getRawText (nextToken) == ltoken_getText (simpleIdToken)
245 || ltoken_getRawText (nextToken) == ltoken_getText (mapSymToken)
246 || ltoken_getRawText (nextToken) == ltoken_getText (markerSymToken)
247 || ltoken_getRawText (nextToken) == ltoken_getText (commentSymToken))
250 InitReduce (CLASSIFICATION2);
252 else if (ltoken_getRawText (nextToken) == ltoken_getText (synonymToken))
255 InitReduce (CLASSIFICATION3);
259 LocalUserError (nextToken,
260 "expected character, token, or synonym classification");
267 ltoken charClassToken;
269 charClassToken = nextToken;
271 nextToken = LSLScanNextToken (); /* Discard char class keyword. */
273 if (ltoken_getRawText (charClassToken) == ltoken_getText (endCommentCharToken))
276 InitReduce (CHARCLASS1);
278 else if (ltoken_getRawText (charClassToken) == ltoken_getText (idCharToken))
281 InitReduce (CHARCLASS2);
283 else if (ltoken_getRawText (charClassToken) == ltoken_getText (opCharToken))
286 InitReduce (CHARCLASS3);
288 else if (ltoken_getRawText (charClassToken)
289 == ltoken_getText (extensionCharToken))
292 InitReduce (CHARCLASS4);
294 else if (ltoken_getRawText (charClassToken) == ltoken_getText (singleCharToken))
297 InitReduce (CHARCLASS5);
299 else if (ltoken_getRawText (charClassToken) == ltoken_getText (whiteCharToken))
302 InitReduce (CHARCLASS6);
306 LocalUserError (nextToken, "expected character classification");
309 ltoken_free (charClassToken);
313 EndCommentChars (void)
316 InitReduce (LRC_ENDCOMMENT1);
318 while (ltoken_getCode (nextToken) != LST_EOL)
321 InitReduce (LRC_ENDCOMMENT2);
330 InitReduce (IDCHARS1);
332 while (ltoken_getCode (nextToken) != LST_EOL)
335 InitReduce (IDCHARS2);
343 InitReduce (OPCHARS1);
345 while (ltoken_getCode (nextToken) != LST_EOL)
348 InitReduce (OPCHARS2);
355 if (ltoken_isChar (nextToken)
356 && lscanCharClass (cstring_firstChar (ltoken_unparse (nextToken))) == SINGLECHAR)
358 LSLGenShiftOnly (nextToken);
359 nextToken = LSLScanNextToken ();
360 InitReduce (LRC_EXTENSIONCHAR1);
364 LocalUserError (nextToken, "expected only one character");
372 InitReduce (SINGCHARS1);
374 while (ltoken_getCode (nextToken) != LST_EOL)
377 InitReduce (SINGCHARS2);
385 InitReduce (WHITECHARS1);
387 while (ltoken_getCode (nextToken) != LST_EOL)
390 InitReduce (WHITECHARS2);
395 EndCommentChar (void)
397 if (ltoken_isChar (nextToken))
399 LSLGenShiftOnly (nextToken);
400 nextToken = LSLScanNextToken ();
401 InitReduce (LRC_ENDCOMMENTCHAR1);
405 LocalUserError (nextToken, "expected only one character");
412 if (hasFirstChar (nextToken))
414 LSLGenShiftOnly (nextToken);
415 nextToken = LSLScanNextToken ();
416 InitReduce (IDCHAR1);
420 LocalUserError (nextToken, "character is already defined, cannot redefine");
427 if (hasFirstChar (nextToken))
429 LSLGenShiftOnly (nextToken);
430 nextToken = LSLScanNextToken ();
431 InitReduce (OPCHAR1);
435 LocalUserError (nextToken, "character is already defined, cannot redefine");
442 if (hasFirstChar (nextToken))
444 LSLGenShiftOnly (nextToken);
445 nextToken = LSLScanNextToken ();
446 InitReduce (SINGCHAR1);
450 LocalUserError (nextToken, "character is already defined, cannot redefine");
457 if (hasFirstChar (nextToken))
459 LSLGenShiftOnly (nextToken);
460 nextToken = LSLScanNextToken ();
461 InitReduce (WHITECHAR1);
465 LocalUserError (nextToken, "character is already defined, cannot redefine");
472 ltoken tokenClassToken;
474 tokenClassToken = nextToken;
476 nextToken = LSLScanNextToken ();
478 if (ltoken_getRawText (tokenClassToken) == ltoken_getText (quantifierSymToken))
480 QuantifierSymToks ();
481 InitReduce (TOKENCLASS1);
483 else if (ltoken_getRawText (tokenClassToken) == ltoken_getText (logicalOpToken))
486 InitReduce (TOKENCLASS2);
488 else if (ltoken_getRawText (tokenClassToken) == ltoken_getText (eqOpToken))
491 InitReduce (TOKENCLASS3);
493 else if (ltoken_getRawText (tokenClassToken)
494 == ltoken_getText (equationSymToken))
497 InitReduce (TOKENCLASS4);
499 else if (ltoken_getRawText (tokenClassToken) == ltoken_getText (eqSepSymToken))
502 InitReduce (TOKENCLASS5);
504 else if (ltoken_getRawText (tokenClassToken) == ltoken_getText (selectSymToken))
507 InitReduce (TOKENCLASS6);
509 else if (ltoken_getRawText (tokenClassToken) == ltoken_getText (openSymToken))
512 InitReduce (TOKENCLASS7);
514 else if (ltoken_getRawText (tokenClassToken) == ltoken_getText (sepSymToken))
517 InitReduce (TOKENCLASS8);
519 else if (ltoken_getRawText (tokenClassToken) == ltoken_getText (closeSymToken))
522 InitReduce (TOKENCLASS9);
524 else if (ltoken_getRawText (tokenClassToken) == ltoken_getText (simpleIdToken))
527 InitReduce (TOKENCLASS10);
529 else if (ltoken_getRawText (tokenClassToken) == ltoken_getText (mapSymToken))
532 InitReduce (TOKENCLASS11);
534 else if (ltoken_getRawText (tokenClassToken) == ltoken_getText (markerSymToken))
537 InitReduce (TOKENCLASS12);
539 else if (ltoken_getRawText (tokenClassToken)
540 == ltoken_getText (commentSymToken))
543 InitReduce (TOKENCLASS13);
547 LocalUserError (nextToken, "expected token classification");
550 ltoken_free (tokenClassToken);
554 QuantifierSymToks (void)
557 InitReduce (QUANTIFIERSYMTOKS1);
559 while (ltoken_getCode (nextToken) != LST_EOL)
562 InitReduce (QUANTIFIERSYMTOKS2);
570 InitReduce (LOGICALOPTOKS1);
572 while (ltoken_getCode (nextToken) != LST_EOL)
575 InitReduce (LOGICALOPTOKS2);
583 InitReduce (LRC_EQOPTOKS1);
585 while (ltoken_getCode (nextToken) != LST_EOL)
588 InitReduce (LRC_EQOPTOKS2);
593 EquationSymToks (void)
596 InitReduce (LRC_EQUATIONSYMTOKS1);
598 while (ltoken_getCode (nextToken) != LST_EOL)
601 InitReduce (LRC_EQUATIONSYMTOKS2);
609 InitReduce (LRC_EQSEPSYMTOKS1);
611 while (ltoken_getCode (nextToken) != LST_EOL)
614 InitReduce (LRC_EQSEPSYMTOKS2);
622 InitReduce (SELECTSYMTOKS1);
624 while (ltoken_getCode (nextToken) != LST_EOL)
627 InitReduce (SELECTSYMTOKS2);
635 InitReduce (OPENSYMTOKS1);
637 while (ltoken_getCode (nextToken) != LST_EOL)
640 InitReduce (OPENSYMTOKS2);
648 InitReduce (SEPSYMTOKS1);
650 while (ltoken_getCode (nextToken) != LST_EOL)
653 InitReduce (SEPSYMTOKS2);
661 InitReduce (CLOSESYMTOKS1);
663 while (ltoken_getCode (nextToken) != LST_EOL)
666 InitReduce (CLOSESYMTOKS2);
674 InitReduce (SIMPLEIDTOKS1);
676 while (ltoken_getCode (nextToken) != LST_EOL)
679 InitReduce (SIMPLEIDTOKS2);
687 InitReduce (MAPSYMTOKS1);
689 while (ltoken_getCode (nextToken) != LST_EOL)
692 InitReduce (MAPSYMTOKS2);
700 InitReduce (MARKERSYMTOKS1);
702 while (ltoken_getCode (nextToken) != LST_EOL)
705 InitReduce (MARKERSYMTOKS2);
710 CommentSymToks (void)
713 InitReduce (COMMENTSYMTOKS1);
715 while (ltoken_getCode (nextToken) != LST_EOL)
718 InitReduce (COMMENTSYMTOKS2);
723 QuantifierSymTok (void)
726 InitReduce (QUANTIFIERSYMTOK1);
733 InitReduce (LOGICALOPTOK1);
740 InitReduce (LRC_EQOPTOK1);
744 EquationSymTok (void)
746 /* ### EquationSymTok (); ### */
748 InitReduce (LRC_EQUATIONSYMTOK1);
755 InitReduce (LRC_EQSEPSYMTOK1);
763 InitReduce (SELECTSYMTOK1);
770 InitReduce (OPENSYMTOK1);
777 InitReduce (SEPSYMTOK1);
784 InitReduce (CLOSESYMTOK1);
791 InitReduce (SIMPLEIDTOK1);
798 InitReduce (MAPSYMTOK1);
805 InitReduce (MARKERSYMTOK1);
813 InitReduce (COMMENTSYMTOK1);
820 if (ltoken_getRawText (nextToken) == ltoken_getText (synonymToken))
822 ltoken_free (nextToken);
823 nextToken = LSLScanNextToken ();
828 InitReduce (SYNCLASS1);
832 LocalUserError (nextToken, "expected synonym classification");
841 InitReduce (OLDTOKEN1);
849 InitReduce (NEWTOKEN1);
856 if (ltoken_getCode (nextToken) == LST_EOL
857 || ltoken_getCode (nextToken) == LEOFTOKEN)
859 LocalUserError (nextToken, "unexpected end-of-line or end-of-file");
863 LSLGenShiftOnly (nextToken);
864 nextToken = LSLScanNextToken ();
869 ** Init File Processing Routines, these routines use the shift-reduce sequence
870 ** produced by the init file parser and update the necessary tables for the
873 ** The same shift stack is used that LSL parser uses. A different reduce
874 ** procedure is used because the init file grammar is different from the LSL
880 InitReduce (LSLInitRuleCode rule)
885 LTRACE ("INITFILE1");
889 LTRACE ("INITLINES1");
893 LTRACE ("INITLINES2");
897 LTRACE ("INITLINES3");
901 LTRACE ("INITLINE1");
905 LTRACE ("INITLINE2");
908 case CLASSIFICATION1:
909 LTRACE ("CLASSIFICATION1");
912 case CLASSIFICATION2:
913 LTRACE ("CLASSIFICATION2");
916 case CLASSIFICATION3:
917 LTRACE ("CLASSIFICATION3");
921 LTRACE ("CHARCLASS1");
925 LTRACE ("CHARCLASS2");
929 LTRACE ("CHARCLASS3");
933 LTRACE ("CHARCLASS4");
937 LTRACE ("CHARCLASS5");
941 LTRACE ("CHARCLASS6");
944 case LRC_ENDCOMMENT1:
945 LTRACE ("LRC_ENDCOMMENT1");
948 case LRC_ENDCOMMENT2:
949 LTRACE ("LRC_ENDCOMMENT2");
968 case LRC_EXTENSIONCHAR1:
969 LTRACE ("LRC_EXTENSIONCHAR1");
970 ProcessExtensionChar ();
974 LTRACE ("SINGCHARS1");
978 LTRACE ("SINGCHARS2");
982 LTRACE ("WHITECHARS1");
986 LTRACE ("WHITECHARS2");
989 case LRC_ENDCOMMENTCHAR1:
990 LTRACE ("LRC_ENDCOMMENTCHAR1");
991 ProcessEndCommentChar ();
996 ProcessSingleChar (IDCHAR);
1001 ProcessSingleChar (OPCHAR);
1005 LTRACE ("SINGCHAR1");
1006 ProcessSingleChar (SINGLECHAR);
1011 ProcessSingleChar (WHITECHAR);
1015 LTRACE ("TOKENCLASS1");
1019 LTRACE ("TOKENCLASS2");
1023 LTRACE ("TOKENCLASS3");
1027 LTRACE ("TOKENCLASS4");
1031 LTRACE ("TOKENCLASS5");
1035 LTRACE ("TOKENCLASS6");
1039 LTRACE ("TOKENCLASS7");
1043 LTRACE ("TOKENCLASS8");
1047 LTRACE ("TOKENCLASS9");
1051 LTRACE ("TOKENCLASS10");
1055 LTRACE ("TOKENCLASS11");
1059 LTRACE ("TOKENCLASS12");
1063 LTRACE ("TOKENCLASS13");
1066 case QUANTIFIERSYMTOKS1:
1067 LTRACE ("QUALIFERSYMTOKS1");
1070 case QUANTIFIERSYMTOKS2:
1071 LTRACE ("QUANTIFIERSYMTOKS2");
1074 case LOGICALOPTOKS1:
1075 LTRACE ("LOGICALOPTOKS1");
1078 case LOGICALOPTOKS2:
1079 LTRACE ("LOGICALOPTOKS2");
1083 LTRACE ("LRC_EQOPTOKS1");
1087 LTRACE ("LRC_EQOPTOKS2");
1090 case LRC_EQUATIONSYMTOKS1:
1091 LTRACE ("LRC_EQUATIONSYMTOKS1");
1094 case LRC_EQUATIONSYMTOKS2:
1095 LTRACE ("LRC_EQUATIONSYMTOKS2");
1098 case LRC_EQSEPSYMTOKS1:
1099 LTRACE ("LRC_EQSEPSYMTOKS1");
1102 case LRC_EQSEPSYMTOKS2:
1103 LTRACE ("LRC_EQSEPSYMTOKS2");
1106 case SELECTSYMTOKS1:
1107 LTRACE ("SELECTSYMTOKS1");
1110 case SELECTSYMTOKS2:
1111 LTRACE ("SELECTSYMTOKS2");
1115 LTRACE ("OPENSYMTOKS1");
1119 LTRACE ("OPENSYMTOKS2");
1123 LTRACE ("SEPSYMTOKS1");
1127 LTRACE ("SEPSYMTOKS2");
1131 LTRACE ("CLOSESYMTOKS1");
1135 LTRACE ("CLOSESYMTOKS2");
1139 LTRACE ("SIMPLEIDTOKS1");
1143 LTRACE ("SIMPLEIDTOKS2");
1147 LTRACE ("MAPSYMTOKS1");
1151 LTRACE ("MAPSYMTOKS2");
1154 case MARKERSYMTOKS1:
1155 LTRACE ("MARKERSYMTOKS1");
1158 case MARKERSYMTOKS2:
1159 LTRACE ("MARKERSYMTOKS2");
1162 case COMMENTSYMTOKS1:
1163 LTRACE ("COMMENTSYMTOKS1");
1166 case COMMENTSYMTOKS2:
1167 LTRACE ("COMMENTSYMTOKS2");
1170 case QUANTIFIERSYMTOK1:
1171 LTRACE ("QUANTIFERSYMTOK1");
1172 ProcessToken (LST_QUANTIFIERSYM);
1176 LTRACE ("LOGICALOPTOK1");
1177 ProcessToken (LST_LOGICALOP);
1181 LTRACE ("LRC_EQOPTOK1");
1182 ProcessToken (LST_EQOP);
1185 case LRC_EQUATIONSYMTOK1:
1186 LTRACE ("LRC_EQUATIONSYMTOK1");
1187 ProcessToken (LST_EQUATIONSYM);
1190 case LRC_EQSEPSYMTOK1:
1191 LTRACE ("LRC_EQSEPSYMTOK1");
1192 ProcessToken (LST_EQSEPSYM);
1196 LTRACE ("SELECTSYMTOK1");
1197 ProcessToken (LST_SELECTSYM);
1201 LTRACE ("OPENSYMTOK1");
1202 ProcessToken (LST_OPENSYM);
1206 LTRACE ("SEPSYMTOK1");
1207 ProcessToken (LST_SEPSYM);
1211 LTRACE ("CLOSESYMTOK1");
1212 ProcessToken (LST_CLOSESYM);
1216 LTRACE ("SIMPLEIDTOK1");
1217 ProcessToken (LST_SIMPLEID);
1221 LTRACE ("MAPSYMTOK1");
1222 ProcessToken (LST_MAPSYM);
1226 LTRACE ("MARKERSYMTOK1");
1227 ProcessToken (LST_MARKERSYM);
1230 case COMMENTSYMTOK1:
1231 LTRACE ("COMMENTSYMTOK1");
1232 ProcessToken (LST_COMMENTSYM);
1236 LTRACE ("SYNCLASS1");
1241 LTRACE ("OLDTOKEN1");
1245 LTRACE ("NEWTOKEN1");
1249 llcontbuglit ("InitReduce: bad switch");
1253 } /* end InitReduce () */
1257 /* Reset the first character of the predefined extensionChar keywords when */
1258 /* the extensionChar changes. e.g. "extensionChar @" changes "forall" to */
1262 UpdateXCharKeywords (charCode xCharCode)
1264 char xChar = (char) xCharCode;
1267 str = ltoken_getTextChars (ltoken_forall);
1270 str = ltoken_getTextChars (ltoken_and);
1273 str = ltoken_getTextChars (ltoken_or);
1276 str = ltoken_getTextChars (ltoken_implies);
1279 str = ltoken_getTextChars (ltoken_eq);
1282 str = ltoken_getTextChars (ltoken_neq);
1285 str = ltoken_getTextChars (ltoken_equals);
1288 str = ltoken_getTextChars (ltoken_eqsep);
1291 str = ltoken_getTextChars (ltoken_select);
1294 str = ltoken_getTextChars (ltoken_open);
1297 str = ltoken_getTextChars (ltoken_sep);
1300 str = ltoken_getTextChars (ltoken_close);
1303 str = ltoken_getTextChars (ltoken_id);
1306 str = ltoken_getTextChars (ltoken_arrow);
1309 str = ltoken_getTextChars (ltoken_marker);
1312 str = ltoken_getTextChars (ltoken_comment);
1317 /* Different from ProcessCharClass because only allow one extension */
1318 /* character. Therefore, the present extension character must be set to a */
1322 ProcessExtensionChar (void)
1324 ltoken stackToken = LSLGenTopPopShiftStack ();
1325 char firstChar = cstring_firstChar (ltoken_unparse (stackToken));
1327 if (!defineSingleChar[(int)firstChar]
1328 && lscanCharClass (firstChar) == SINGLECHAR)
1330 /* Is a single character that has not been defined before. */
1331 /* Can only have one extension char. Release old one. */
1332 lsetCharClass (firstChar, CHC_EXTENSION);
1334 /* this is a (bogus) type bug! caught by splint */
1335 /* lsetCharClass (currentExtensionChar, SINGLECHAR); */
1337 lsetCharClass ((char) currentExtensionChar, SINGLECHAR);
1339 currentExtensionChar = (charCode) firstChar;
1340 UpdateXCharKeywords (currentExtensionChar);
1344 /* Already redefined. Don't allow to be redefined. */
1345 LocalUserError (stackToken, "character is already defined, cannot redefine");
1347 ltoken_free (stackToken);
1350 /* Different from ProcessSingleChar because allow any characters to be */
1351 /* endCommentChar and also set a different part of the scanner structure. */
1354 ProcessEndCommentChar (void)
1356 ltoken stackToken = LSLGenTopPopShiftStack ();
1357 char firstChar = cstring_firstChar (ltoken_unparse (stackToken));
1359 if (LSLIsEndComment (firstChar))
1361 LocalUserError (stackToken,
1362 "already defined as a endCommentChar, cannot redefine");
1366 lsetEndCommentChar (firstChar, TRUE);
1368 ltoken_free (stackToken);
1372 ProcessSingleChar (charCode code)
1374 ltoken stackToken = LSLGenTopPopShiftStack ();
1375 char firstChar = cstring_firstChar (ltoken_unparse (stackToken));
1377 if (!defineSingleChar[(int)firstChar]
1378 && lscanCharClass (firstChar) == SINGLECHAR)
1380 /* Is a single character that has not been defined before. */
1381 /* It's OK to redefine once. */
1382 lsetCharClass (firstChar, code);
1383 /* OK to mark as a defined singleChar even if not. Only check */
1384 /* defineSingleChar[] if defining a singleChar. */
1385 defineSingleChar[(int)firstChar] = TRUE;
1389 LocalUserError (stackToken, "character is already defined, cannot redefine");
1391 ltoken_free (stackToken);
1395 ProcessToken (ltokenCode code)
1397 ltoken stackToken, temp;
1400 stackToken = LSLGenTopPopShiftStack ();
1401 sym = ltoken_getText (stackToken);
1405 LocalUserError (stackToken,
1406 "already defined as a synonym, cannot redefine");
1409 /* Get the token from the token table, so can check if the token */
1410 /* was updated by a previous token. */
1411 temp = LSLGetToken (sym);
1413 if (ltoken_isStateDefined (temp))
1415 if ((code == LST_OPENSYM && sym == lsymbol_fromChars ("[")) ||
1416 (code == LST_CLOSESYM && sym == lsymbol_fromChars ("]")))
1418 /* ignore "openSym [" and "closeSym ]" TokenClass */
1419 ltoken_free (stackToken);
1424 LocalUserError (stackToken, "already defined, cannot redefine");
1429 LSLUpdateToken (code, ltoken_getText (stackToken), TRUE);
1430 ltoken_free (stackToken);
1435 ProcessSynonym (void)
1440 newtok = LSLGenTopPopShiftStack ();
1441 oldtok = LSLGenTopPopShiftStack ();
1443 if (ltoken_wasSyn (newtok))
1445 /* The token has a synonym. This means that the synonym was in the */
1446 /* init file, so complain about redefining as a synonym again */
1447 LocalUserError (newtok, "newtok already is a synonym, cannot redefine");
1450 if (ltoken_hasSyn (newtok))
1453 ** newtok already has a synonym defined for it. Do not allow
1454 ** synonyms to be chained.
1457 LocalUserError (newtok,
1458 "newtok already has a synonym, cannot chain synonyms");
1461 if (ltoken_isStateDefined (newtok))
1463 LocalUserError (newtok, "newtok already defined, cannot redefine");
1466 LSLAddSyn (ltoken_getText (newtok), ltoken_getText (oldtok));
1467 ltoken_free (oldtok);
1468 ltoken_free (newtok);
1473 * Utilities, in alphabetical order
1477 LocalUserError (ltoken t, /*@temp@*/ char *msg)
1479 lldiagmsg (message ("%s %s in the LSL init file:",
1480 ltoken_unparse (t), cstring_fromChars (msg)));
1482 ltoken_free (nextToken);
1483 nextToken = LSLScanNextToken ();
1485 while (ltoken_getCode (nextToken) != LST_EOL)
1487 ltoken_free (nextToken);
1488 nextToken = LSLScanNextToken ();
1493 ** Required initialization and cleanup routines
1496 static /*@exposed@*/ ltoken insertSimpleToken (char *text)
1497 /*@modifies internalState@*/
1499 return (LSLInsertToken (LST_SIMPLEID, lsymbol_fromChars (text), 0, FALSE));
1503 lslinit_initProcessInitFile (void)
1507 LSLGenInit (TRUE); /* parsing LSLinit not LCLinit */
1510 ** Insert the init file keywords into the token table as undefined
1511 ** SIMPLEIDs. They are defined as simpleIds since they must be treated
1512 ** that way if they do not appear as the first token on a line, and
1513 ** they must be treated that way for the actual LSL parsing. Save the
1514 ** tokens so can recognize as init file keywords when necessary.
1517 endCommentCharToken = insertSimpleToken ("endCommentChar");
1518 idCharToken = insertSimpleToken ("idChar");
1519 opCharToken = insertSimpleToken ("opChar");
1520 extensionCharToken = insertSimpleToken ("extensionChar");
1521 singleCharToken = insertSimpleToken ("singleChar");
1522 whiteCharToken = insertSimpleToken ("whiteChar");
1524 quantifierSymToken = insertSimpleToken ("quantifierSym");
1525 logicalOpToken = insertSimpleToken ("logicalOp");
1526 eqOpToken = insertSimpleToken ("eqOp");
1527 equationSymToken = insertSimpleToken ("equationSym");
1528 eqSepSymToken = insertSimpleToken ("eqSepSym");
1529 selectSymToken = insertSimpleToken ("selectSym");
1530 openSymToken = insertSimpleToken ("openSym");
1531 sepSymToken = insertSimpleToken ("sepSym");
1532 closeSymToken = insertSimpleToken ("closeSym");
1533 simpleIdToken = insertSimpleToken ("simpleId");
1534 mapSymToken = insertSimpleToken ("mapSym");
1535 markerSymToken = insertSimpleToken ("markerSym");
1536 commentSymToken = insertSimpleToken ("commentSym");
1537 synonymToken = insertSimpleToken ("synonym");
1539 for (i = 0; i <= LASTCHAR; i++)
1541 defineSingleChar[i] = FALSE;
1545 ** Record the current extension character so can redefine back to
1546 ** singleChar if a new extension character is redefined.
1549 currentExtensionChar = (charCode) CHAREXTENDER;
1551 LSLReportEolTokens (TRUE);
1552 ltoken_free (nextToken);
1553 nextToken = LSLScanNextToken ();
1556 void lslinit_process (void)
1557 /*@globals undef g_symtab; @*/
1558 /*@modifies g_symtab, internalState, fileSystem; @*/
1561 ** Open init file provided by user, or use the default LCL init file
1564 cstring larchpath = context_getLarchPath ();
1565 inputStream initstream = inputStream_undefined;
1569 if (inputStream_isUndefined (s_initFile))
1571 s_initFile = inputStream_create (cstring_makeLiteral (INITFILENAME),
1572 cstring_makeLiteralTemp (LCLINIT_SUFFIX),
1575 if (!inputStream_getPath (larchpath, s_initFile))
1577 lldiagmsg (message ("Continuing without LCL init file: %s",
1578 inputStream_fileName (s_initFile)));
1582 if (!inputStream_open (s_initFile))
1584 lldiagmsg (message ("Continuing without LCL init file: %s",
1585 inputStream_fileName (s_initFile)));
1591 if (!inputStream_open (s_initFile))
1593 lldiagmsg (message ("Continuing without LCL init file: %s",
1594 inputStream_fileName (s_initFile)));
1598 /* Initialize checker */
1605 LCLSynTableReset ();
1606 LCLTokenTableInit ();
1612 LCLScanLineReset ();
1618 /* need this to initialize LCL checker */
1620 llassert (inputStream_isDefined (s_initFile));
1621 if (inputStream_isOpen (s_initFile))
1625 LCLScanReset (s_initFile);
1634 check (inputStream_close (s_initFile));
1637 /* Initialize LSL init files, for parsing LSL signatures from LSL */
1639 initstream = inputStream_create (cstring_makeLiteral ("lslinit.lsi"),
1640 cstring_makeLiteralTemp (".lsi"),
1643 if (!inputStream_getPath (larchpath, initstream))
1645 lldiagmsg (message ("Continuing without LSL init file: %s",
1646 inputStream_fileName (initstream)));
1650 if (!inputStream_open (initstream))
1652 lldiagmsg (message ("Continuing without LSL init file: %s",
1653 inputStream_fileName (initstream)));
1669 if (inputStream_isOpen (initstream))
1672 LSLScanReset (initstream);
1673 lslinit_initProcessInitFile ();
1674 lslinit_processInitFile ();
1675 check (inputStream_close (initstream));
1678 inputStream_free (initstream);
1683 (cstring_makeLiteral ("LSL init file error. Attempting to continue."));
1687 g_symtab = symtable_new ();
1690 ** sort_init must come after symtab has been initialized
1697 ** Equivalent to importing old spec_csupport.lcl
1698 ** define immutable LCL type "bool" and bool constants TRUE and FALSE
1699 ** and initialized them to be equal to LSL's "true" and "false".
1701 ** Reads in CTrait.syms (derived from CTrait.lsl) on LARCH_PATH.
1705 LCLReportEolTokens (FALSE);