2 ** Splint - annotation-assisted static program checker
3 ** Copyright (C) 1994-2002 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"
43 /* needed to parse init files */
47 # define LTRACE(rule) printf ("Reducing: %s\n", rule)
53 static void LocalUserError (ltoken p_t, /*@temp@*/ char *p_msg)
54 /*@modifies *g_warningstream@*/;
56 static /*@only@*/ ltoken nextToken;
58 static /*@only@*/ /*@null@*/ inputStream s_initFile = inputStream_undefined;
60 static void InitFile (void) /*@modifies nextToken@*/ ;
61 static void InitLines (void) /*@modifies nextToken@*/ ;
62 static void InitLine (void) /*@modifies nextToken@*/ ;
63 static void Classification (void) /*@modifies nextToken@*/ ;
64 static void CharClass (void) /*@modifies nextToken@*/ ;
66 static void EndCommentChars (void) /*@modifies nextToken@*/ ;
67 static void IdChars (void) /*@modifies nextToken@*/ ;
68 static void OpChars (void) /*@modifies nextToken@*/ ;
69 static void ExtensionChar (void) /*@modifies nextToken@*/ ;
70 static void SingChars (void) /*@modifies nextToken@*/ ;
71 static void WhiteChars (void) /*@modifies nextToken@*/ ;
72 static void EndCommentChar (void) /*@modifies nextToken@*/ ;
73 static void IdChar (void) /*@modifies nextToken@*/ ;
74 static void OpChar (void) /*@modifies nextToken@*/ ;
75 static void SingChar (void) /*@modifies nextToken@*/ ;
76 static void WhiteChar (void) /*@modifies nextToken@*/ ;
78 static void TokenClass (void) /*@modifies nextToken@*/ ;
79 static void QuantifierSymToks (void) /*@modifies nextToken@*/ ;
80 static void LogicalOpToks (void) /*@modifies nextToken@*/ ;
81 static void EqOpToks (void) /*@modifies nextToken@*/ ;
82 static void EquationSymToks (void) /*@modifies nextToken@*/ ;
83 static void EqSepSymToks (void) /*@modifies nextToken@*/ ;
84 static void SelectSymToks (void) /*@modifies nextToken@*/ ;
85 static void OpenSymToks (void) /*@modifies nextToken@*/ ;
86 static void SepSymToks (void) /*@modifies nextToken@*/ ;
87 static void CloseSymToks (void) /*@modifies nextToken@*/ ;
88 static void SimpleIdToks (void) /*@modifies nextToken@*/ ;
89 static void MapSymToks (void) /*@modifies nextToken@*/ ;
90 static void MarkerSymToks (void) /*@modifies nextToken@*/ ;
91 static void CommentSymToks (void) /*@modifies nextToken@*/ ;
92 static void QuantifierSymTok (void) /*@modifies nextToken@*/ ;
93 static void LogicalOpTok (void) /*@modifies nextToken@*/ ;
94 static void EqOpTok (void) /*@modifies nextToken@*/ ;
95 static void EquationSymTok (void) /*@modifies nextToken@*/ ;
96 static void EqSepSymTok (void) /*@modifies nextToken@*/ ;
97 static void SelectSymTok (void) /*@modifies nextToken@*/ ;
98 static void OpenSymTok (void) /*@modifies nextToken@*/ ;
99 static void SepSymTok (void) /*@modifies nextToken@*/ ;
100 static void CloseSymTok (void) /*@modifies nextToken@*/ ;
101 static void SimpleIdTok (void) /*@modifies nextToken@*/ ;
102 static void MapSymTok (void) /*@modifies nextToken@*/ ;
103 static void MarkerSymTok (void) /*@modifies nextToken@*/ ;
104 static void CommentSymTok (void) /*@modifies nextToken@*/ ;
105 static void SynClass (void) /*@modifies nextToken@*/ ;
106 static void OldToken (void) /*@modifies nextToken@*/ ;
107 static void NewToken (void) /*@modifies nextToken@*/ ;
108 static void Token (void) /*@modifies nextToken@*/ ;
110 static void InitReduce (LSLInitRuleCode p_rule) /*@modifies nextToken@*/ ;
111 static void UpdateXCharKeywords (charCode) /*@modifies nextToken@*/ ;
112 static void ProcessExtensionChar (void) /*@modifies nextToken@*/ ;
113 static void ProcessEndCommentChar (void) /*@modifies nextToken@*/ ;
114 static void ProcessSingleChar (charCode p_code) /*@modifies nextToken@*/ ;
115 static void ProcessToken (ltokenCode p_code) /*@modifies nextToken@*/ ;
116 static void ProcessSynonym (void) /*@modifies nextToken@*/ ;
118 /* If TRUE character has been redefined as a singleChar. */
119 static bool defineSingleChar[LASTCHAR + 1];
121 static charCode currentExtensionChar;
123 /* LSL init file keyword tokens. */
125 static /*@dependent@*/ ltoken endCommentCharToken;
126 static /*@dependent@*/ ltoken idCharToken;
127 static /*@dependent@*/ ltoken opCharToken;
128 static /*@dependent@*/ ltoken extensionCharToken;
129 static /*@dependent@*/ ltoken singleCharToken;
130 static /*@dependent@*/ ltoken whiteCharToken;
131 static /*@dependent@*/ ltoken quantifierSymToken;
132 static /*@dependent@*/ ltoken logicalOpToken;
133 static /*@dependent@*/ ltoken eqOpToken;
134 static /*@dependent@*/ ltoken equationSymToken;
135 static /*@dependent@*/ ltoken eqSepSymToken;
136 static /*@dependent@*/ ltoken selectSymToken;
137 static /*@dependent@*/ ltoken openSymToken;
138 static /*@dependent@*/ ltoken sepSymToken;
139 static /*@dependent@*/ ltoken closeSymToken;
140 static /*@dependent@*/ ltoken simpleIdToken;
141 static /*@dependent@*/ ltoken mapSymToken;
142 static /*@dependent@*/ ltoken markerSymToken;
143 static /*@dependent@*/ ltoken commentSymToken;
144 static /*@dependent@*/ ltoken synonymToken;
147 hasFirstChar (ltoken tok)
149 return (ltoken_isChar (tok)
150 && lscanCharClass (cstring_firstChar (ltoken_unparse (tok))) == SINGLECHAR);
154 lslinit_setInitFile (inputStream s)
156 llassert (inputStream_isUndefined (s_initFile));
162 ** Parsing functions for init file processing, in the same order as the
163 ** grammar file lslinit.cfg. This is top-down order, as much as possible.
167 static void lslinit_processInitFile (void)
170 InitReduce (INITFILE1);
172 if (ltoken_getCode (nextToken) != LEOFTOKEN)
174 LocalUserError (nextToken, "unexpected tokens after end-of-file");
181 InitReduce (INITLINES1);
183 if (ltoken_getCode (nextToken) != LEOFTOKEN)
186 InitReduce (INITLINES2);
189 while (ltoken_getCode (nextToken) != LEOFTOKEN)
192 InitReduce (INITLINES3);
200 if (ltoken_getCode (nextToken) == LST_EOL)
202 /* Nothing on line. */
203 InitReduce (INITLINE1);
208 InitReduce (INITLINE2);
211 if (ltoken_getCode (nextToken) != LST_EOL)
213 LocalUserError (nextToken, "Unexpected tokens on line");
216 ltoken_free (nextToken);
217 nextToken = LSLScanNextToken ();
221 Classification (void)
223 if (ltoken_getRawText (nextToken) == ltoken_getText (endCommentCharToken)
224 || ltoken_getRawText (nextToken) == ltoken_getText (idCharToken)
225 || ltoken_getRawText (nextToken) == ltoken_getText (opCharToken)
226 || ltoken_getRawText (nextToken) == ltoken_getText (extensionCharToken)
227 || ltoken_getRawText (nextToken) == ltoken_getText (singleCharToken)
228 || ltoken_getRawText (nextToken) == ltoken_getText (whiteCharToken))
231 InitReduce (CLASSIFICATION1);
233 else if (ltoken_getRawText (nextToken) == ltoken_getText (quantifierSymToken)
234 || ltoken_getRawText (nextToken) == ltoken_getText (logicalOpToken)
235 || ltoken_getRawText (nextToken) == ltoken_getText (eqOpToken)
236 || ltoken_getRawText (nextToken) == ltoken_getText (equationSymToken)
237 || ltoken_getRawText (nextToken) == ltoken_getText (eqSepSymToken)
238 || ltoken_getRawText (nextToken) == ltoken_getText (selectSymToken)
239 || ltoken_getRawText (nextToken) == ltoken_getText (openSymToken)
240 || ltoken_getRawText (nextToken) == ltoken_getText (sepSymToken)
241 || ltoken_getRawText (nextToken) == ltoken_getText (closeSymToken)
242 || ltoken_getRawText (nextToken) == ltoken_getText (simpleIdToken)
243 || ltoken_getRawText (nextToken) == ltoken_getText (mapSymToken)
244 || ltoken_getRawText (nextToken) == ltoken_getText (markerSymToken)
245 || ltoken_getRawText (nextToken) == ltoken_getText (commentSymToken))
248 InitReduce (CLASSIFICATION2);
250 else if (ltoken_getRawText (nextToken) == ltoken_getText (synonymToken))
253 InitReduce (CLASSIFICATION3);
257 LocalUserError (nextToken,
258 "expected character, token, or synonym classification");
265 ltoken charClassToken;
267 charClassToken = nextToken;
269 nextToken = LSLScanNextToken (); /* Discard char class keyword. */
271 if (ltoken_getRawText (charClassToken) == ltoken_getText (endCommentCharToken))
274 InitReduce (CHARCLASS1);
276 else if (ltoken_getRawText (charClassToken) == ltoken_getText (idCharToken))
279 InitReduce (CHARCLASS2);
281 else if (ltoken_getRawText (charClassToken) == ltoken_getText (opCharToken))
284 InitReduce (CHARCLASS3);
286 else if (ltoken_getRawText (charClassToken)
287 == ltoken_getText (extensionCharToken))
290 InitReduce (CHARCLASS4);
292 else if (ltoken_getRawText (charClassToken) == ltoken_getText (singleCharToken))
295 InitReduce (CHARCLASS5);
297 else if (ltoken_getRawText (charClassToken) == ltoken_getText (whiteCharToken))
300 InitReduce (CHARCLASS6);
304 LocalUserError (nextToken, "expected character classification");
307 ltoken_free (charClassToken);
311 EndCommentChars (void)
314 InitReduce (LRC_ENDCOMMENT1);
316 while (ltoken_getCode (nextToken) != LST_EOL)
319 InitReduce (LRC_ENDCOMMENT2);
328 InitReduce (IDCHARS1);
330 while (ltoken_getCode (nextToken) != LST_EOL)
333 InitReduce (IDCHARS2);
341 InitReduce (OPCHARS1);
343 while (ltoken_getCode (nextToken) != LST_EOL)
346 InitReduce (OPCHARS2);
353 if (ltoken_isChar (nextToken)
354 && lscanCharClass (cstring_firstChar (ltoken_unparse (nextToken))) == SINGLECHAR)
356 LSLGenShiftOnly (nextToken);
357 nextToken = LSLScanNextToken ();
358 InitReduce (LRC_EXTENSIONCHAR1);
362 LocalUserError (nextToken, "expected only one character");
370 InitReduce (SINGCHARS1);
372 while (ltoken_getCode (nextToken) != LST_EOL)
375 InitReduce (SINGCHARS2);
383 InitReduce (WHITECHARS1);
385 while (ltoken_getCode (nextToken) != LST_EOL)
388 InitReduce (WHITECHARS2);
393 EndCommentChar (void)
395 if (ltoken_isChar (nextToken))
397 LSLGenShiftOnly (nextToken);
398 nextToken = LSLScanNextToken ();
399 InitReduce (LRC_ENDCOMMENTCHAR1);
403 LocalUserError (nextToken, "expected only one character");
410 if (hasFirstChar (nextToken))
412 LSLGenShiftOnly (nextToken);
413 nextToken = LSLScanNextToken ();
414 InitReduce (IDCHAR1);
418 LocalUserError (nextToken, "character is already defined, cannot redefine");
425 if (hasFirstChar (nextToken))
427 LSLGenShiftOnly (nextToken);
428 nextToken = LSLScanNextToken ();
429 InitReduce (OPCHAR1);
433 LocalUserError (nextToken, "character is already defined, cannot redefine");
440 if (hasFirstChar (nextToken))
442 LSLGenShiftOnly (nextToken);
443 nextToken = LSLScanNextToken ();
444 InitReduce (SINGCHAR1);
448 LocalUserError (nextToken, "character is already defined, cannot redefine");
455 if (hasFirstChar (nextToken))
457 LSLGenShiftOnly (nextToken);
458 nextToken = LSLScanNextToken ();
459 InitReduce (WHITECHAR1);
463 LocalUserError (nextToken, "character is already defined, cannot redefine");
470 ltoken tokenClassToken;
472 tokenClassToken = nextToken;
474 nextToken = LSLScanNextToken ();
476 if (ltoken_getRawText (tokenClassToken) == ltoken_getText (quantifierSymToken))
478 QuantifierSymToks ();
479 InitReduce (TOKENCLASS1);
481 else if (ltoken_getRawText (tokenClassToken) == ltoken_getText (logicalOpToken))
484 InitReduce (TOKENCLASS2);
486 else if (ltoken_getRawText (tokenClassToken) == ltoken_getText (eqOpToken))
489 InitReduce (TOKENCLASS3);
491 else if (ltoken_getRawText (tokenClassToken)
492 == ltoken_getText (equationSymToken))
495 InitReduce (TOKENCLASS4);
497 else if (ltoken_getRawText (tokenClassToken) == ltoken_getText (eqSepSymToken))
500 InitReduce (TOKENCLASS5);
502 else if (ltoken_getRawText (tokenClassToken) == ltoken_getText (selectSymToken))
505 InitReduce (TOKENCLASS6);
507 else if (ltoken_getRawText (tokenClassToken) == ltoken_getText (openSymToken))
510 InitReduce (TOKENCLASS7);
512 else if (ltoken_getRawText (tokenClassToken) == ltoken_getText (sepSymToken))
515 InitReduce (TOKENCLASS8);
517 else if (ltoken_getRawText (tokenClassToken) == ltoken_getText (closeSymToken))
520 InitReduce (TOKENCLASS9);
522 else if (ltoken_getRawText (tokenClassToken) == ltoken_getText (simpleIdToken))
525 InitReduce (TOKENCLASS10);
527 else if (ltoken_getRawText (tokenClassToken) == ltoken_getText (mapSymToken))
530 InitReduce (TOKENCLASS11);
532 else if (ltoken_getRawText (tokenClassToken) == ltoken_getText (markerSymToken))
535 InitReduce (TOKENCLASS12);
537 else if (ltoken_getRawText (tokenClassToken)
538 == ltoken_getText (commentSymToken))
541 InitReduce (TOKENCLASS13);
545 LocalUserError (nextToken, "expected token classification");
548 ltoken_free (tokenClassToken);
552 QuantifierSymToks (void)
555 InitReduce (QUANTIFIERSYMTOKS1);
557 while (ltoken_getCode (nextToken) != LST_EOL)
560 InitReduce (QUANTIFIERSYMTOKS2);
568 InitReduce (LOGICALOPTOKS1);
570 while (ltoken_getCode (nextToken) != LST_EOL)
573 InitReduce (LOGICALOPTOKS2);
581 InitReduce (LRC_EQOPTOKS1);
583 while (ltoken_getCode (nextToken) != LST_EOL)
586 InitReduce (LRC_EQOPTOKS2);
591 EquationSymToks (void)
594 InitReduce (LRC_EQUATIONSYMTOKS1);
596 while (ltoken_getCode (nextToken) != LST_EOL)
599 InitReduce (LRC_EQUATIONSYMTOKS2);
607 InitReduce (LRC_EQSEPSYMTOKS1);
609 while (ltoken_getCode (nextToken) != LST_EOL)
612 InitReduce (LRC_EQSEPSYMTOKS2);
620 InitReduce (SELECTSYMTOKS1);
622 while (ltoken_getCode (nextToken) != LST_EOL)
625 InitReduce (SELECTSYMTOKS2);
633 InitReduce (OPENSYMTOKS1);
635 while (ltoken_getCode (nextToken) != LST_EOL)
638 InitReduce (OPENSYMTOKS2);
646 InitReduce (SEPSYMTOKS1);
648 while (ltoken_getCode (nextToken) != LST_EOL)
651 InitReduce (SEPSYMTOKS2);
659 InitReduce (CLOSESYMTOKS1);
661 while (ltoken_getCode (nextToken) != LST_EOL)
664 InitReduce (CLOSESYMTOKS2);
672 InitReduce (SIMPLEIDTOKS1);
674 while (ltoken_getCode (nextToken) != LST_EOL)
677 InitReduce (SIMPLEIDTOKS2);
685 InitReduce (MAPSYMTOKS1);
687 while (ltoken_getCode (nextToken) != LST_EOL)
690 InitReduce (MAPSYMTOKS2);
698 InitReduce (MARKERSYMTOKS1);
700 while (ltoken_getCode (nextToken) != LST_EOL)
703 InitReduce (MARKERSYMTOKS2);
708 CommentSymToks (void)
711 InitReduce (COMMENTSYMTOKS1);
713 while (ltoken_getCode (nextToken) != LST_EOL)
716 InitReduce (COMMENTSYMTOKS2);
721 QuantifierSymTok (void)
724 InitReduce (QUANTIFIERSYMTOK1);
731 InitReduce (LOGICALOPTOK1);
738 InitReduce (LRC_EQOPTOK1);
742 EquationSymTok (void)
744 /* ### EquationSymTok (); ### */
746 InitReduce (LRC_EQUATIONSYMTOK1);
753 InitReduce (LRC_EQSEPSYMTOK1);
761 InitReduce (SELECTSYMTOK1);
768 InitReduce (OPENSYMTOK1);
775 InitReduce (SEPSYMTOK1);
782 InitReduce (CLOSESYMTOK1);
789 InitReduce (SIMPLEIDTOK1);
796 InitReduce (MAPSYMTOK1);
803 InitReduce (MARKERSYMTOK1);
811 InitReduce (COMMENTSYMTOK1);
818 if (ltoken_getRawText (nextToken) == ltoken_getText (synonymToken))
820 ltoken_free (nextToken);
821 nextToken = LSLScanNextToken ();
826 InitReduce (SYNCLASS1);
830 LocalUserError (nextToken, "expected synonym classification");
839 InitReduce (OLDTOKEN1);
847 InitReduce (NEWTOKEN1);
854 if (ltoken_getCode (nextToken) == LST_EOL
855 || ltoken_getCode (nextToken) == LEOFTOKEN)
857 LocalUserError (nextToken, "unexpected end-of-line or end-of-file");
861 LSLGenShiftOnly (nextToken);
862 nextToken = LSLScanNextToken ();
867 ** Init File Processing Routines, these routines use the shift-reduce sequence
868 ** produced by the init file parser and update the necessary tables for the
871 ** The same shift stack is used that LSL parser uses. A different reduce
872 ** procedure is used because the init file grammar is different from the LSL
878 InitReduce (LSLInitRuleCode rule)
883 LTRACE ("INITFILE1");
887 LTRACE ("INITLINES1");
891 LTRACE ("INITLINES2");
895 LTRACE ("INITLINES3");
899 LTRACE ("INITLINE1");
903 LTRACE ("INITLINE2");
906 case CLASSIFICATION1:
907 LTRACE ("CLASSIFICATION1");
910 case CLASSIFICATION2:
911 LTRACE ("CLASSIFICATION2");
914 case CLASSIFICATION3:
915 LTRACE ("CLASSIFICATION3");
919 LTRACE ("CHARCLASS1");
923 LTRACE ("CHARCLASS2");
927 LTRACE ("CHARCLASS3");
931 LTRACE ("CHARCLASS4");
935 LTRACE ("CHARCLASS5");
939 LTRACE ("CHARCLASS6");
942 case LRC_ENDCOMMENT1:
943 LTRACE ("LRC_ENDCOMMENT1");
946 case LRC_ENDCOMMENT2:
947 LTRACE ("LRC_ENDCOMMENT2");
966 case LRC_EXTENSIONCHAR1:
967 LTRACE ("LRC_EXTENSIONCHAR1");
968 ProcessExtensionChar ();
972 LTRACE ("SINGCHARS1");
976 LTRACE ("SINGCHARS2");
980 LTRACE ("WHITECHARS1");
984 LTRACE ("WHITECHARS2");
987 case LRC_ENDCOMMENTCHAR1:
988 LTRACE ("LRC_ENDCOMMENTCHAR1");
989 ProcessEndCommentChar ();
994 ProcessSingleChar (IDCHAR);
999 ProcessSingleChar (OPCHAR);
1003 LTRACE ("SINGCHAR1");
1004 ProcessSingleChar (SINGLECHAR);
1009 ProcessSingleChar (WHITECHAR);
1013 LTRACE ("TOKENCLASS1");
1017 LTRACE ("TOKENCLASS2");
1021 LTRACE ("TOKENCLASS3");
1025 LTRACE ("TOKENCLASS4");
1029 LTRACE ("TOKENCLASS5");
1033 LTRACE ("TOKENCLASS6");
1037 LTRACE ("TOKENCLASS7");
1041 LTRACE ("TOKENCLASS8");
1045 LTRACE ("TOKENCLASS9");
1049 LTRACE ("TOKENCLASS10");
1053 LTRACE ("TOKENCLASS11");
1057 LTRACE ("TOKENCLASS12");
1061 LTRACE ("TOKENCLASS13");
1064 case QUANTIFIERSYMTOKS1:
1065 LTRACE ("QUALIFERSYMTOKS1");
1068 case QUANTIFIERSYMTOKS2:
1069 LTRACE ("QUANTIFIERSYMTOKS2");
1072 case LOGICALOPTOKS1:
1073 LTRACE ("LOGICALOPTOKS1");
1076 case LOGICALOPTOKS2:
1077 LTRACE ("LOGICALOPTOKS2");
1081 LTRACE ("LRC_EQOPTOKS1");
1085 LTRACE ("LRC_EQOPTOKS2");
1088 case LRC_EQUATIONSYMTOKS1:
1089 LTRACE ("LRC_EQUATIONSYMTOKS1");
1092 case LRC_EQUATIONSYMTOKS2:
1093 LTRACE ("LRC_EQUATIONSYMTOKS2");
1096 case LRC_EQSEPSYMTOKS1:
1097 LTRACE ("LRC_EQSEPSYMTOKS1");
1100 case LRC_EQSEPSYMTOKS2:
1101 LTRACE ("LRC_EQSEPSYMTOKS2");
1104 case SELECTSYMTOKS1:
1105 LTRACE ("SELECTSYMTOKS1");
1108 case SELECTSYMTOKS2:
1109 LTRACE ("SELECTSYMTOKS2");
1113 LTRACE ("OPENSYMTOKS1");
1117 LTRACE ("OPENSYMTOKS2");
1121 LTRACE ("SEPSYMTOKS1");
1125 LTRACE ("SEPSYMTOKS2");
1129 LTRACE ("CLOSESYMTOKS1");
1133 LTRACE ("CLOSESYMTOKS2");
1137 LTRACE ("SIMPLEIDTOKS1");
1141 LTRACE ("SIMPLEIDTOKS2");
1145 LTRACE ("MAPSYMTOKS1");
1149 LTRACE ("MAPSYMTOKS2");
1152 case MARKERSYMTOKS1:
1153 LTRACE ("MARKERSYMTOKS1");
1156 case MARKERSYMTOKS2:
1157 LTRACE ("MARKERSYMTOKS2");
1160 case COMMENTSYMTOKS1:
1161 LTRACE ("COMMENTSYMTOKS1");
1164 case COMMENTSYMTOKS2:
1165 LTRACE ("COMMENTSYMTOKS2");
1168 case QUANTIFIERSYMTOK1:
1169 LTRACE ("QUANTIFERSYMTOK1");
1170 ProcessToken (LST_QUANTIFIERSYM);
1174 LTRACE ("LOGICALOPTOK1");
1175 ProcessToken (LST_LOGICALOP);
1179 LTRACE ("LRC_EQOPTOK1");
1180 ProcessToken (LST_EQOP);
1183 case LRC_EQUATIONSYMTOK1:
1184 LTRACE ("LRC_EQUATIONSYMTOK1");
1185 ProcessToken (LST_EQUATIONSYM);
1188 case LRC_EQSEPSYMTOK1:
1189 LTRACE ("LRC_EQSEPSYMTOK1");
1190 ProcessToken (LST_EQSEPSYM);
1194 LTRACE ("SELECTSYMTOK1");
1195 ProcessToken (LST_SELECTSYM);
1199 LTRACE ("OPENSYMTOK1");
1200 ProcessToken (LST_OPENSYM);
1204 LTRACE ("SEPSYMTOK1");
1205 ProcessToken (LST_SEPSYM);
1209 LTRACE ("CLOSESYMTOK1");
1210 ProcessToken (LST_CLOSESYM);
1214 LTRACE ("SIMPLEIDTOK1");
1215 ProcessToken (LST_SIMPLEID);
1219 LTRACE ("MAPSYMTOK1");
1220 ProcessToken (LST_MAPSYM);
1224 LTRACE ("MARKERSYMTOK1");
1225 ProcessToken (LST_MARKERSYM);
1228 case COMMENTSYMTOK1:
1229 LTRACE ("COMMENTSYMTOK1");
1230 ProcessToken (LST_COMMENTSYM);
1234 LTRACE ("SYNCLASS1");
1239 LTRACE ("OLDTOKEN1");
1243 LTRACE ("NEWTOKEN1");
1247 llcontbuglit ("InitReduce: bad switch");
1251 } /* end InitReduce () */
1255 /* Reset the first character of the predefined extensionChar keywords when */
1256 /* the extensionChar changes. e.g. "extensionChar @" changes "forall" to */
1260 UpdateXCharKeywords (charCode xCharCode)
1262 char xChar = (char) xCharCode;
1265 str = ltoken_getTextChars (ltoken_forall);
1268 str = ltoken_getTextChars (ltoken_and);
1271 str = ltoken_getTextChars (ltoken_or);
1274 str = ltoken_getTextChars (ltoken_implies);
1277 str = ltoken_getTextChars (ltoken_eq);
1280 str = ltoken_getTextChars (ltoken_neq);
1283 str = ltoken_getTextChars (ltoken_equals);
1286 str = ltoken_getTextChars (ltoken_eqsep);
1289 str = ltoken_getTextChars (ltoken_select);
1292 str = ltoken_getTextChars (ltoken_open);
1295 str = ltoken_getTextChars (ltoken_sep);
1298 str = ltoken_getTextChars (ltoken_close);
1301 str = ltoken_getTextChars (ltoken_id);
1304 str = ltoken_getTextChars (ltoken_arrow);
1307 str = ltoken_getTextChars (ltoken_marker);
1310 str = ltoken_getTextChars (ltoken_comment);
1315 /* Different from ProcessCharClass because only allow one extension */
1316 /* character. Therefore, the present extension character must be set to a */
1320 ProcessExtensionChar (void)
1322 ltoken stackToken = LSLGenTopPopShiftStack ();
1323 char firstChar = cstring_firstChar (ltoken_unparse (stackToken));
1325 if (!defineSingleChar[(int)firstChar]
1326 && lscanCharClass (firstChar) == SINGLECHAR)
1328 /* Is a single character that has not been defined before. */
1329 /* Can only have one extension char. Release old one. */
1330 lsetCharClass (firstChar, CHC_EXTENSION);
1332 /* this is a (bogus) type bug! caught by splint */
1333 /* lsetCharClass (currentExtensionChar, SINGLECHAR); */
1335 lsetCharClass ((char) currentExtensionChar, SINGLECHAR);
1337 currentExtensionChar = (charCode) firstChar;
1338 UpdateXCharKeywords (currentExtensionChar);
1342 /* Already redefined. Don't allow to be redefined. */
1343 LocalUserError (stackToken, "character is already defined, cannot redefine");
1345 ltoken_free (stackToken);
1348 /* Different from ProcessSingleChar because allow any characters to be */
1349 /* endCommentChar and also set a different part of the scanner structure. */
1352 ProcessEndCommentChar (void)
1354 ltoken stackToken = LSLGenTopPopShiftStack ();
1355 char firstChar = cstring_firstChar (ltoken_unparse (stackToken));
1357 if (LSLIsEndComment (firstChar))
1359 LocalUserError (stackToken,
1360 "already defined as a endCommentChar, cannot redefine");
1364 lsetEndCommentChar (firstChar, TRUE);
1366 ltoken_free (stackToken);
1370 ProcessSingleChar (charCode code)
1372 ltoken stackToken = LSLGenTopPopShiftStack ();
1373 char firstChar = cstring_firstChar (ltoken_unparse (stackToken));
1375 if (!defineSingleChar[(int)firstChar]
1376 && lscanCharClass (firstChar) == SINGLECHAR)
1378 /* Is a single character that has not been defined before. */
1379 /* It's OK to redefine once. */
1380 lsetCharClass (firstChar, code);
1381 /* OK to mark as a defined singleChar even if not. Only check */
1382 /* defineSingleChar[] if defining a singleChar. */
1383 defineSingleChar[(int)firstChar] = TRUE;
1387 LocalUserError (stackToken, "character is already defined, cannot redefine");
1389 ltoken_free (stackToken);
1393 ProcessToken (ltokenCode code)
1395 ltoken stackToken, temp;
1398 stackToken = LSLGenTopPopShiftStack ();
1399 sym = ltoken_getText (stackToken);
1403 LocalUserError (stackToken,
1404 "already defined as a synonym, cannot redefine");
1407 /* Get the token from the token table, so can check if the token */
1408 /* was updated by a previous token. */
1409 temp = LSLGetToken (sym);
1411 if (ltoken_isStateDefined (temp))
1413 if ((code == LST_OPENSYM && sym == lsymbol_fromChars ("[")) ||
1414 (code == LST_CLOSESYM && sym == lsymbol_fromChars ("]")))
1416 /* ignore "openSym [" and "closeSym ]" TokenClass */
1417 ltoken_free (stackToken);
1422 LocalUserError (stackToken, "already defined, cannot redefine");
1427 LSLUpdateToken (code, ltoken_getText (stackToken), TRUE);
1428 ltoken_free (stackToken);
1433 ProcessSynonym (void)
1438 newtok = LSLGenTopPopShiftStack ();
1439 oldtok = LSLGenTopPopShiftStack ();
1441 if (ltoken_wasSyn (newtok))
1443 /* The token has a synonym. This means that the synonym was in the */
1444 /* init file, so complain about redefining as a synonym again */
1445 LocalUserError (newtok, "newtok already is a synonym, cannot redefine");
1448 if (ltoken_hasSyn (newtok))
1451 ** newtok already has a synonym defined for it. Do not allow
1452 ** synonyms to be chained.
1455 LocalUserError (newtok,
1456 "newtok already has a synonym, cannot chain synonyms");
1459 if (ltoken_isStateDefined (newtok))
1461 LocalUserError (newtok, "newtok already defined, cannot redefine");
1464 LSLAddSyn (ltoken_getText (newtok), ltoken_getText (oldtok));
1465 ltoken_free (oldtok);
1466 ltoken_free (newtok);
1471 * Utilities, in alphabetical order
1475 LocalUserError (ltoken t, /*@temp@*/ char *msg)
1477 lldiagmsg (message ("%s %s in the LSL init file:",
1478 ltoken_unparse (t), cstring_fromChars (msg)));
1480 ltoken_free (nextToken);
1481 nextToken = LSLScanNextToken ();
1483 while (ltoken_getCode (nextToken) != LST_EOL)
1485 ltoken_free (nextToken);
1486 nextToken = LSLScanNextToken ();
1491 ** Required initialization and cleanup routines
1494 static /*@exposed@*/ ltoken insertSimpleToken (char *text)
1495 /*@modifies internalState@*/
1497 return (LSLInsertToken (LST_SIMPLEID, lsymbol_fromChars (text), 0, FALSE));
1501 lslinit_initProcessInitFile (void)
1505 LSLGenInit (TRUE); /* parsing LSLinit not LCLinit */
1508 ** Insert the init file keywords into the token table as undefined
1509 ** SIMPLEIDs. They are defined as simpleIds since they must be treated
1510 ** that way if they do not appear as the first token on a line, and
1511 ** they must be treated that way for the actual LSL parsing. Save the
1512 ** tokens so can recognize as init file keywords when necessary.
1515 endCommentCharToken = insertSimpleToken ("endCommentChar");
1516 idCharToken = insertSimpleToken ("idChar");
1517 opCharToken = insertSimpleToken ("opChar");
1518 extensionCharToken = insertSimpleToken ("extensionChar");
1519 singleCharToken = insertSimpleToken ("singleChar");
1520 whiteCharToken = insertSimpleToken ("whiteChar");
1522 quantifierSymToken = insertSimpleToken ("quantifierSym");
1523 logicalOpToken = insertSimpleToken ("logicalOp");
1524 eqOpToken = insertSimpleToken ("eqOp");
1525 equationSymToken = insertSimpleToken ("equationSym");
1526 eqSepSymToken = insertSimpleToken ("eqSepSym");
1527 selectSymToken = insertSimpleToken ("selectSym");
1528 openSymToken = insertSimpleToken ("openSym");
1529 sepSymToken = insertSimpleToken ("sepSym");
1530 closeSymToken = insertSimpleToken ("closeSym");
1531 simpleIdToken = insertSimpleToken ("simpleId");
1532 mapSymToken = insertSimpleToken ("mapSym");
1533 markerSymToken = insertSimpleToken ("markerSym");
1534 commentSymToken = insertSimpleToken ("commentSym");
1535 synonymToken = insertSimpleToken ("synonym");
1537 for (i = 0; i <= LASTCHAR; i++)
1539 defineSingleChar[i] = FALSE;
1543 ** Record the current extension character so can redefine back to
1544 ** singleChar if a new extension character is redefined.
1547 currentExtensionChar = (charCode) CHAREXTENDER;
1549 LSLReportEolTokens (TRUE);
1550 ltoken_free (nextToken);
1551 nextToken = LSLScanNextToken ();
1554 void lslinit_process (void)
1555 /*@globals undef g_symtab; @*/
1556 /*@modifies g_symtab, internalState, fileSystem; @*/
1559 ** Open init file provided by user, or use the default LCL init file
1562 cstring larchpath = context_getLarchPath ();
1563 inputStream initstream = inputStream_undefined;
1567 if (inputStream_isUndefined (s_initFile))
1569 s_initFile = inputStream_create (cstring_makeLiteral (INITFILENAME),
1570 cstring_makeLiteralTemp (LCLINIT_SUFFIX),
1573 if (!inputStream_getPath (larchpath, s_initFile))
1575 lldiagmsg (message ("Continuing without LCL init file: %s",
1576 inputStream_fileName (s_initFile)));
1580 if (!inputStream_open (s_initFile))
1582 lldiagmsg (message ("Continuing without LCL init file: %s",
1583 inputStream_fileName (s_initFile)));
1589 if (!inputStream_open (s_initFile))
1591 lldiagmsg (message ("Continuing without LCL init file: %s",
1592 inputStream_fileName (s_initFile)));
1596 /* Initialize checker */
1603 LCLSynTableReset ();
1604 LCLTokenTableInit ();
1610 LCLScanLineReset ();
1616 /* need this to initialize LCL checker */
1618 llassert (inputStream_isDefined (s_initFile));
1619 if (inputStream_isOpen (s_initFile))
1623 LCLScanReset (s_initFile);
1632 check (inputStream_close (s_initFile));
1635 /* Initialize LSL init files, for parsing LSL signatures from LSL */
1637 initstream = inputStream_create (cstring_makeLiteral ("lslinit.lsi"),
1638 cstring_makeLiteralTemp (".lsi"),
1641 if (!inputStream_getPath (larchpath, initstream))
1643 lldiagmsg (message ("Continuing without LSL init file: %s",
1644 inputStream_fileName (initstream)));
1648 if (!inputStream_open (initstream))
1650 lldiagmsg (message ("Continuing without LSL init file: %s",
1651 inputStream_fileName (initstream)));
1667 if (inputStream_isOpen (initstream))
1670 LSLScanReset (initstream);
1671 lslinit_initProcessInitFile ();
1672 lslinit_processInitFile ();
1673 check (inputStream_close (initstream));
1676 inputStream_free (initstream);
1681 (cstring_makeLiteral ("LSL init file error. Attempting to continue."));
1685 g_symtab = symtable_new ();
1688 ** sort_init must come after symtab has been initialized
1695 ** Equivalent to importing old spec_csupport.lcl
1696 ** define immutable LCL type "bool" and bool constants TRUE and FALSE
1697 ** and initialized them to be equal to LSL's "true" and "false".
1699 ** Reads in CTrait.syms (derived from CTrait.lsl) on LARCH_PATH.
1703 LCLReportEolTokens (FALSE);