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 /* needed to parse init files */
45 # define LTRACE(rule) printf ("Reducing: %s\n", rule)
51 static void LocalUserError (ltoken p_t, /*@temp@*/ char *p_msg)
52 /*@modifies *g_warningstream@*/;
54 static /*@only@*/ ltoken nextToken;
56 static /*@only@*/ /*@null@*/ inputStream s_initFile = inputStream_undefined;
58 static void InitFile (void) /*@modifies nextToken@*/ ;
59 static void InitLines (void) /*@modifies nextToken@*/ ;
60 static void InitLine (void) /*@modifies nextToken@*/ ;
61 static void Classification (void) /*@modifies nextToken@*/ ;
62 static void CharClass (void) /*@modifies nextToken@*/ ;
64 static void EndCommentChars (void) /*@modifies nextToken@*/ ;
65 static void IdChars (void) /*@modifies nextToken@*/ ;
66 static void OpChars (void) /*@modifies nextToken@*/ ;
67 static void ExtensionChar (void) /*@modifies nextToken@*/ ;
68 static void SingChars (void) /*@modifies nextToken@*/ ;
69 static void WhiteChars (void) /*@modifies nextToken@*/ ;
70 static void EndCommentChar (void) /*@modifies nextToken@*/ ;
71 static void IdChar (void) /*@modifies nextToken@*/ ;
72 static void OpChar (void) /*@modifies nextToken@*/ ;
73 static void SingChar (void) /*@modifies nextToken@*/ ;
74 static void WhiteChar (void) /*@modifies nextToken@*/ ;
76 static void TokenClass (void) /*@modifies nextToken@*/ ;
77 static void QuantifierSymToks (void) /*@modifies nextToken@*/ ;
78 static void LogicalOpToks (void) /*@modifies nextToken@*/ ;
79 static void EqOpToks (void) /*@modifies nextToken@*/ ;
80 static void EquationSymToks (void) /*@modifies nextToken@*/ ;
81 static void EqSepSymToks (void) /*@modifies nextToken@*/ ;
82 static void SelectSymToks (void) /*@modifies nextToken@*/ ;
83 static void OpenSymToks (void) /*@modifies nextToken@*/ ;
84 static void SepSymToks (void) /*@modifies nextToken@*/ ;
85 static void CloseSymToks (void) /*@modifies nextToken@*/ ;
86 static void SimpleIdToks (void) /*@modifies nextToken@*/ ;
87 static void MapSymToks (void) /*@modifies nextToken@*/ ;
88 static void MarkerSymToks (void) /*@modifies nextToken@*/ ;
89 static void CommentSymToks (void) /*@modifies nextToken@*/ ;
90 static void QuantifierSymTok (void) /*@modifies nextToken@*/ ;
91 static void LogicalOpTok (void) /*@modifies nextToken@*/ ;
92 static void EqOpTok (void) /*@modifies nextToken@*/ ;
93 static void EquationSymTok (void) /*@modifies nextToken@*/ ;
94 static void EqSepSymTok (void) /*@modifies nextToken@*/ ;
95 static void SelectSymTok (void) /*@modifies nextToken@*/ ;
96 static void OpenSymTok (void) /*@modifies nextToken@*/ ;
97 static void SepSymTok (void) /*@modifies nextToken@*/ ;
98 static void CloseSymTok (void) /*@modifies nextToken@*/ ;
99 static void SimpleIdTok (void) /*@modifies nextToken@*/ ;
100 static void MapSymTok (void) /*@modifies nextToken@*/ ;
101 static void MarkerSymTok (void) /*@modifies nextToken@*/ ;
102 static void CommentSymTok (void) /*@modifies nextToken@*/ ;
103 static void SynClass (void) /*@modifies nextToken@*/ ;
104 static void OldToken (void) /*@modifies nextToken@*/ ;
105 static void NewToken (void) /*@modifies nextToken@*/ ;
106 static void Token (void) /*@modifies nextToken@*/ ;
108 static void InitReduce (LSLInitRuleCode p_rule) /*@modifies nextToken@*/ ;
109 static void UpdateXCharKeywords (charCode) /*@modifies nextToken@*/ ;
110 static void ProcessExtensionChar (void) /*@modifies nextToken@*/ ;
111 static void ProcessEndCommentChar (void) /*@modifies nextToken@*/ ;
112 static void ProcessSingleChar (charCode p_code) /*@modifies nextToken@*/ ;
113 static void ProcessToken (ltokenCode p_code) /*@modifies nextToken@*/ ;
114 static void ProcessSynonym (void) /*@modifies nextToken@*/ ;
116 /* If TRUE character has been redefined as a singleChar. */
117 static bool defineSingleChar[LASTCHAR + 1];
119 static charCode currentExtensionChar;
121 /* LSL init file keyword tokens. */
123 static /*@dependent@*/ ltoken endCommentCharToken;
124 static /*@dependent@*/ ltoken idCharToken;
125 static /*@dependent@*/ ltoken opCharToken;
126 static /*@dependent@*/ ltoken extensionCharToken;
127 static /*@dependent@*/ ltoken singleCharToken;
128 static /*@dependent@*/ ltoken whiteCharToken;
129 static /*@dependent@*/ ltoken quantifierSymToken;
130 static /*@dependent@*/ ltoken logicalOpToken;
131 static /*@dependent@*/ ltoken eqOpToken;
132 static /*@dependent@*/ ltoken equationSymToken;
133 static /*@dependent@*/ ltoken eqSepSymToken;
134 static /*@dependent@*/ ltoken selectSymToken;
135 static /*@dependent@*/ ltoken openSymToken;
136 static /*@dependent@*/ ltoken sepSymToken;
137 static /*@dependent@*/ ltoken closeSymToken;
138 static /*@dependent@*/ ltoken simpleIdToken;
139 static /*@dependent@*/ ltoken mapSymToken;
140 static /*@dependent@*/ ltoken markerSymToken;
141 static /*@dependent@*/ ltoken commentSymToken;
142 static /*@dependent@*/ ltoken synonymToken;
145 hasFirstChar (ltoken tok)
147 return (ltoken_isChar (tok)
148 && lscanCharClass (cstring_firstChar (ltoken_unparse (tok))) == SINGLECHAR);
152 lslinit_setInitFile (inputStream s)
154 llassert (inputStream_isUndefined (s_initFile));
160 ** Parsing functions for init file processing, in the same order as the
161 ** grammar file lslinit.cfg. This is top-down order, as much as possible.
165 static void lslinit_processInitFile (void)
168 InitReduce (INITFILE1);
170 if (ltoken_getCode (nextToken) != LEOFTOKEN)
172 LocalUserError (nextToken, "unexpected tokens after end-of-file");
179 InitReduce (INITLINES1);
181 if (ltoken_getCode (nextToken) != LEOFTOKEN)
184 InitReduce (INITLINES2);
187 while (ltoken_getCode (nextToken) != LEOFTOKEN)
190 InitReduce (INITLINES3);
198 if (ltoken_getCode (nextToken) == LST_EOL)
200 /* Nothing on line. */
201 InitReduce (INITLINE1);
206 InitReduce (INITLINE2);
209 if (ltoken_getCode (nextToken) != LST_EOL)
211 LocalUserError (nextToken, "Unexpected tokens on line");
214 ltoken_free (nextToken);
215 nextToken = LSLScanNextToken ();
219 Classification (void)
221 if (ltoken_getRawText (nextToken) == ltoken_getText (endCommentCharToken)
222 || ltoken_getRawText (nextToken) == ltoken_getText (idCharToken)
223 || ltoken_getRawText (nextToken) == ltoken_getText (opCharToken)
224 || ltoken_getRawText (nextToken) == ltoken_getText (extensionCharToken)
225 || ltoken_getRawText (nextToken) == ltoken_getText (singleCharToken)
226 || ltoken_getRawText (nextToken) == ltoken_getText (whiteCharToken))
229 InitReduce (CLASSIFICATION1);
231 else if (ltoken_getRawText (nextToken) == ltoken_getText (quantifierSymToken)
232 || ltoken_getRawText (nextToken) == ltoken_getText (logicalOpToken)
233 || ltoken_getRawText (nextToken) == ltoken_getText (eqOpToken)
234 || ltoken_getRawText (nextToken) == ltoken_getText (equationSymToken)
235 || ltoken_getRawText (nextToken) == ltoken_getText (eqSepSymToken)
236 || ltoken_getRawText (nextToken) == ltoken_getText (selectSymToken)
237 || ltoken_getRawText (nextToken) == ltoken_getText (openSymToken)
238 || ltoken_getRawText (nextToken) == ltoken_getText (sepSymToken)
239 || ltoken_getRawText (nextToken) == ltoken_getText (closeSymToken)
240 || ltoken_getRawText (nextToken) == ltoken_getText (simpleIdToken)
241 || ltoken_getRawText (nextToken) == ltoken_getText (mapSymToken)
242 || ltoken_getRawText (nextToken) == ltoken_getText (markerSymToken)
243 || ltoken_getRawText (nextToken) == ltoken_getText (commentSymToken))
246 InitReduce (CLASSIFICATION2);
248 else if (ltoken_getRawText (nextToken) == ltoken_getText (synonymToken))
251 InitReduce (CLASSIFICATION3);
255 LocalUserError (nextToken,
256 "expected character, token, or synonym classification");
263 ltoken charClassToken;
265 charClassToken = nextToken;
267 nextToken = LSLScanNextToken (); /* Discard char class keyword. */
269 if (ltoken_getRawText (charClassToken) == ltoken_getText (endCommentCharToken))
272 InitReduce (CHARCLASS1);
274 else if (ltoken_getRawText (charClassToken) == ltoken_getText (idCharToken))
277 InitReduce (CHARCLASS2);
279 else if (ltoken_getRawText (charClassToken) == ltoken_getText (opCharToken))
282 InitReduce (CHARCLASS3);
284 else if (ltoken_getRawText (charClassToken)
285 == ltoken_getText (extensionCharToken))
288 InitReduce (CHARCLASS4);
290 else if (ltoken_getRawText (charClassToken) == ltoken_getText (singleCharToken))
293 InitReduce (CHARCLASS5);
295 else if (ltoken_getRawText (charClassToken) == ltoken_getText (whiteCharToken))
298 InitReduce (CHARCLASS6);
302 LocalUserError (nextToken, "expected character classification");
305 ltoken_free (charClassToken);
309 EndCommentChars (void)
312 InitReduce (LRC_ENDCOMMENT1);
314 while (ltoken_getCode (nextToken) != LST_EOL)
317 InitReduce (LRC_ENDCOMMENT2);
326 InitReduce (IDCHARS1);
328 while (ltoken_getCode (nextToken) != LST_EOL)
331 InitReduce (IDCHARS2);
339 InitReduce (OPCHARS1);
341 while (ltoken_getCode (nextToken) != LST_EOL)
344 InitReduce (OPCHARS2);
351 if (ltoken_isChar (nextToken)
352 && lscanCharClass (cstring_firstChar (ltoken_unparse (nextToken))) == SINGLECHAR)
354 LSLGenShiftOnly (nextToken);
355 nextToken = LSLScanNextToken ();
356 InitReduce (LRC_EXTENSIONCHAR1);
360 LocalUserError (nextToken, "expected only one character");
368 InitReduce (SINGCHARS1);
370 while (ltoken_getCode (nextToken) != LST_EOL)
373 InitReduce (SINGCHARS2);
381 InitReduce (WHITECHARS1);
383 while (ltoken_getCode (nextToken) != LST_EOL)
386 InitReduce (WHITECHARS2);
391 EndCommentChar (void)
393 if (ltoken_isChar (nextToken))
395 LSLGenShiftOnly (nextToken);
396 nextToken = LSLScanNextToken ();
397 InitReduce (LRC_ENDCOMMENTCHAR1);
401 LocalUserError (nextToken, "expected only one character");
408 if (hasFirstChar (nextToken))
410 LSLGenShiftOnly (nextToken);
411 nextToken = LSLScanNextToken ();
412 InitReduce (IDCHAR1);
416 LocalUserError (nextToken, "character is already defined, cannot redefine");
423 if (hasFirstChar (nextToken))
425 LSLGenShiftOnly (nextToken);
426 nextToken = LSLScanNextToken ();
427 InitReduce (OPCHAR1);
431 LocalUserError (nextToken, "character is already defined, cannot redefine");
438 if (hasFirstChar (nextToken))
440 LSLGenShiftOnly (nextToken);
441 nextToken = LSLScanNextToken ();
442 InitReduce (SINGCHAR1);
446 LocalUserError (nextToken, "character is already defined, cannot redefine");
453 if (hasFirstChar (nextToken))
455 LSLGenShiftOnly (nextToken);
456 nextToken = LSLScanNextToken ();
457 InitReduce (WHITECHAR1);
461 LocalUserError (nextToken, "character is already defined, cannot redefine");
468 ltoken tokenClassToken;
470 tokenClassToken = nextToken;
472 nextToken = LSLScanNextToken ();
474 if (ltoken_getRawText (tokenClassToken) == ltoken_getText (quantifierSymToken))
476 QuantifierSymToks ();
477 InitReduce (TOKENCLASS1);
479 else if (ltoken_getRawText (tokenClassToken) == ltoken_getText (logicalOpToken))
482 InitReduce (TOKENCLASS2);
484 else if (ltoken_getRawText (tokenClassToken) == ltoken_getText (eqOpToken))
487 InitReduce (TOKENCLASS3);
489 else if (ltoken_getRawText (tokenClassToken)
490 == ltoken_getText (equationSymToken))
493 InitReduce (TOKENCLASS4);
495 else if (ltoken_getRawText (tokenClassToken) == ltoken_getText (eqSepSymToken))
498 InitReduce (TOKENCLASS5);
500 else if (ltoken_getRawText (tokenClassToken) == ltoken_getText (selectSymToken))
503 InitReduce (TOKENCLASS6);
505 else if (ltoken_getRawText (tokenClassToken) == ltoken_getText (openSymToken))
508 InitReduce (TOKENCLASS7);
510 else if (ltoken_getRawText (tokenClassToken) == ltoken_getText (sepSymToken))
513 InitReduce (TOKENCLASS8);
515 else if (ltoken_getRawText (tokenClassToken) == ltoken_getText (closeSymToken))
518 InitReduce (TOKENCLASS9);
520 else if (ltoken_getRawText (tokenClassToken) == ltoken_getText (simpleIdToken))
523 InitReduce (TOKENCLASS10);
525 else if (ltoken_getRawText (tokenClassToken) == ltoken_getText (mapSymToken))
528 InitReduce (TOKENCLASS11);
530 else if (ltoken_getRawText (tokenClassToken) == ltoken_getText (markerSymToken))
533 InitReduce (TOKENCLASS12);
535 else if (ltoken_getRawText (tokenClassToken)
536 == ltoken_getText (commentSymToken))
539 InitReduce (TOKENCLASS13);
543 LocalUserError (nextToken, "expected token classification");
546 ltoken_free (tokenClassToken);
550 QuantifierSymToks (void)
553 InitReduce (QUANTIFIERSYMTOKS1);
555 while (ltoken_getCode (nextToken) != LST_EOL)
558 InitReduce (QUANTIFIERSYMTOKS2);
566 InitReduce (LOGICALOPTOKS1);
568 while (ltoken_getCode (nextToken) != LST_EOL)
571 InitReduce (LOGICALOPTOKS2);
579 InitReduce (LRC_EQOPTOKS1);
581 while (ltoken_getCode (nextToken) != LST_EOL)
584 InitReduce (LRC_EQOPTOKS2);
589 EquationSymToks (void)
592 InitReduce (LRC_EQUATIONSYMTOKS1);
594 while (ltoken_getCode (nextToken) != LST_EOL)
597 InitReduce (LRC_EQUATIONSYMTOKS2);
605 InitReduce (LRC_EQSEPSYMTOKS1);
607 while (ltoken_getCode (nextToken) != LST_EOL)
610 InitReduce (LRC_EQSEPSYMTOKS2);
618 InitReduce (SELECTSYMTOKS1);
620 while (ltoken_getCode (nextToken) != LST_EOL)
623 InitReduce (SELECTSYMTOKS2);
631 InitReduce (OPENSYMTOKS1);
633 while (ltoken_getCode (nextToken) != LST_EOL)
636 InitReduce (OPENSYMTOKS2);
644 InitReduce (SEPSYMTOKS1);
646 while (ltoken_getCode (nextToken) != LST_EOL)
649 InitReduce (SEPSYMTOKS2);
657 InitReduce (CLOSESYMTOKS1);
659 while (ltoken_getCode (nextToken) != LST_EOL)
662 InitReduce (CLOSESYMTOKS2);
670 InitReduce (SIMPLEIDTOKS1);
672 while (ltoken_getCode (nextToken) != LST_EOL)
675 InitReduce (SIMPLEIDTOKS2);
683 InitReduce (MAPSYMTOKS1);
685 while (ltoken_getCode (nextToken) != LST_EOL)
688 InitReduce (MAPSYMTOKS2);
696 InitReduce (MARKERSYMTOKS1);
698 while (ltoken_getCode (nextToken) != LST_EOL)
701 InitReduce (MARKERSYMTOKS2);
706 CommentSymToks (void)
709 InitReduce (COMMENTSYMTOKS1);
711 while (ltoken_getCode (nextToken) != LST_EOL)
714 InitReduce (COMMENTSYMTOKS2);
719 QuantifierSymTok (void)
722 InitReduce (QUANTIFIERSYMTOK1);
729 InitReduce (LOGICALOPTOK1);
736 InitReduce (LRC_EQOPTOK1);
740 EquationSymTok (void)
742 /* ### EquationSymTok (); ### */
744 InitReduce (LRC_EQUATIONSYMTOK1);
751 InitReduce (LRC_EQSEPSYMTOK1);
759 InitReduce (SELECTSYMTOK1);
766 InitReduce (OPENSYMTOK1);
773 InitReduce (SEPSYMTOK1);
780 InitReduce (CLOSESYMTOK1);
787 InitReduce (SIMPLEIDTOK1);
794 InitReduce (MAPSYMTOK1);
801 InitReduce (MARKERSYMTOK1);
809 InitReduce (COMMENTSYMTOK1);
816 if (ltoken_getRawText (nextToken) == ltoken_getText (synonymToken))
818 ltoken_free (nextToken);
819 nextToken = LSLScanNextToken ();
824 InitReduce (SYNCLASS1);
828 LocalUserError (nextToken, "expected synonym classification");
837 InitReduce (OLDTOKEN1);
845 InitReduce (NEWTOKEN1);
852 if (ltoken_getCode (nextToken) == LST_EOL
853 || ltoken_getCode (nextToken) == LEOFTOKEN)
855 LocalUserError (nextToken, "unexpected end-of-line or end-of-file");
859 LSLGenShiftOnly (nextToken);
860 nextToken = LSLScanNextToken ();
865 ** Init File Processing Routines, these routines use the shift-reduce sequence
866 ** produced by the init file parser and update the necessary tables for the
869 ** The same shift stack is used that LSL parser uses. A different reduce
870 ** procedure is used because the init file grammar is different from the LSL
876 InitReduce (LSLInitRuleCode rule)
881 LTRACE ("INITFILE1");
885 LTRACE ("INITLINES1");
889 LTRACE ("INITLINES2");
893 LTRACE ("INITLINES3");
897 LTRACE ("INITLINE1");
901 LTRACE ("INITLINE2");
904 case CLASSIFICATION1:
905 LTRACE ("CLASSIFICATION1");
908 case CLASSIFICATION2:
909 LTRACE ("CLASSIFICATION2");
912 case CLASSIFICATION3:
913 LTRACE ("CLASSIFICATION3");
917 LTRACE ("CHARCLASS1");
921 LTRACE ("CHARCLASS2");
925 LTRACE ("CHARCLASS3");
929 LTRACE ("CHARCLASS4");
933 LTRACE ("CHARCLASS5");
937 LTRACE ("CHARCLASS6");
940 case LRC_ENDCOMMENT1:
941 LTRACE ("LRC_ENDCOMMENT1");
944 case LRC_ENDCOMMENT2:
945 LTRACE ("LRC_ENDCOMMENT2");
964 case LRC_EXTENSIONCHAR1:
965 LTRACE ("LRC_EXTENSIONCHAR1");
966 ProcessExtensionChar ();
970 LTRACE ("SINGCHARS1");
974 LTRACE ("SINGCHARS2");
978 LTRACE ("WHITECHARS1");
982 LTRACE ("WHITECHARS2");
985 case LRC_ENDCOMMENTCHAR1:
986 LTRACE ("LRC_ENDCOMMENTCHAR1");
987 ProcessEndCommentChar ();
992 ProcessSingleChar (IDCHAR);
997 ProcessSingleChar (OPCHAR);
1001 LTRACE ("SINGCHAR1");
1002 ProcessSingleChar (SINGLECHAR);
1007 ProcessSingleChar (WHITECHAR);
1011 LTRACE ("TOKENCLASS1");
1015 LTRACE ("TOKENCLASS2");
1019 LTRACE ("TOKENCLASS3");
1023 LTRACE ("TOKENCLASS4");
1027 LTRACE ("TOKENCLASS5");
1031 LTRACE ("TOKENCLASS6");
1035 LTRACE ("TOKENCLASS7");
1039 LTRACE ("TOKENCLASS8");
1043 LTRACE ("TOKENCLASS9");
1047 LTRACE ("TOKENCLASS10");
1051 LTRACE ("TOKENCLASS11");
1055 LTRACE ("TOKENCLASS12");
1059 LTRACE ("TOKENCLASS13");
1062 case QUANTIFIERSYMTOKS1:
1063 LTRACE ("QUALIFERSYMTOKS1");
1066 case QUANTIFIERSYMTOKS2:
1067 LTRACE ("QUANTIFIERSYMTOKS2");
1070 case LOGICALOPTOKS1:
1071 LTRACE ("LOGICALOPTOKS1");
1074 case LOGICALOPTOKS2:
1075 LTRACE ("LOGICALOPTOKS2");
1079 LTRACE ("LRC_EQOPTOKS1");
1083 LTRACE ("LRC_EQOPTOKS2");
1086 case LRC_EQUATIONSYMTOKS1:
1087 LTRACE ("LRC_EQUATIONSYMTOKS1");
1090 case LRC_EQUATIONSYMTOKS2:
1091 LTRACE ("LRC_EQUATIONSYMTOKS2");
1094 case LRC_EQSEPSYMTOKS1:
1095 LTRACE ("LRC_EQSEPSYMTOKS1");
1098 case LRC_EQSEPSYMTOKS2:
1099 LTRACE ("LRC_EQSEPSYMTOKS2");
1102 case SELECTSYMTOKS1:
1103 LTRACE ("SELECTSYMTOKS1");
1106 case SELECTSYMTOKS2:
1107 LTRACE ("SELECTSYMTOKS2");
1111 LTRACE ("OPENSYMTOKS1");
1115 LTRACE ("OPENSYMTOKS2");
1119 LTRACE ("SEPSYMTOKS1");
1123 LTRACE ("SEPSYMTOKS2");
1127 LTRACE ("CLOSESYMTOKS1");
1131 LTRACE ("CLOSESYMTOKS2");
1135 LTRACE ("SIMPLEIDTOKS1");
1139 LTRACE ("SIMPLEIDTOKS2");
1143 LTRACE ("MAPSYMTOKS1");
1147 LTRACE ("MAPSYMTOKS2");
1150 case MARKERSYMTOKS1:
1151 LTRACE ("MARKERSYMTOKS1");
1154 case MARKERSYMTOKS2:
1155 LTRACE ("MARKERSYMTOKS2");
1158 case COMMENTSYMTOKS1:
1159 LTRACE ("COMMENTSYMTOKS1");
1162 case COMMENTSYMTOKS2:
1163 LTRACE ("COMMENTSYMTOKS2");
1166 case QUANTIFIERSYMTOK1:
1167 LTRACE ("QUANTIFERSYMTOK1");
1168 ProcessToken (LST_QUANTIFIERSYM);
1172 LTRACE ("LOGICALOPTOK1");
1173 ProcessToken (LST_LOGICALOP);
1177 LTRACE ("LRC_EQOPTOK1");
1178 ProcessToken (LST_EQOP);
1181 case LRC_EQUATIONSYMTOK1:
1182 LTRACE ("LRC_EQUATIONSYMTOK1");
1183 ProcessToken (LST_EQUATIONSYM);
1186 case LRC_EQSEPSYMTOK1:
1187 LTRACE ("LRC_EQSEPSYMTOK1");
1188 ProcessToken (LST_EQSEPSYM);
1192 LTRACE ("SELECTSYMTOK1");
1193 ProcessToken (LST_SELECTSYM);
1197 LTRACE ("OPENSYMTOK1");
1198 ProcessToken (LST_OPENSYM);
1202 LTRACE ("SEPSYMTOK1");
1203 ProcessToken (LST_SEPSYM);
1207 LTRACE ("CLOSESYMTOK1");
1208 ProcessToken (LST_CLOSESYM);
1212 LTRACE ("SIMPLEIDTOK1");
1213 ProcessToken (LST_SIMPLEID);
1217 LTRACE ("MAPSYMTOK1");
1218 ProcessToken (LST_MAPSYM);
1222 LTRACE ("MARKERSYMTOK1");
1223 ProcessToken (LST_MARKERSYM);
1226 case COMMENTSYMTOK1:
1227 LTRACE ("COMMENTSYMTOK1");
1228 ProcessToken (LST_COMMENTSYM);
1232 LTRACE ("SYNCLASS1");
1237 LTRACE ("OLDTOKEN1");
1241 LTRACE ("NEWTOKEN1");
1245 llcontbuglit ("InitReduce: bad switch");
1249 } /* end InitReduce () */
1253 /* Reset the first character of the predefined extensionChar keywords when */
1254 /* the extensionChar changes. e.g. "extensionChar @" changes "forall" to */
1258 UpdateXCharKeywords (charCode xCharCode)
1260 char xChar = (char) xCharCode;
1263 str = ltoken_getTextChars (ltoken_forall);
1266 str = ltoken_getTextChars (ltoken_and);
1269 str = ltoken_getTextChars (ltoken_or);
1272 str = ltoken_getTextChars (ltoken_implies);
1275 str = ltoken_getTextChars (ltoken_eq);
1278 str = ltoken_getTextChars (ltoken_neq);
1281 str = ltoken_getTextChars (ltoken_equals);
1284 str = ltoken_getTextChars (ltoken_eqsep);
1287 str = ltoken_getTextChars (ltoken_select);
1290 str = ltoken_getTextChars (ltoken_open);
1293 str = ltoken_getTextChars (ltoken_sep);
1296 str = ltoken_getTextChars (ltoken_close);
1299 str = ltoken_getTextChars (ltoken_id);
1302 str = ltoken_getTextChars (ltoken_arrow);
1305 str = ltoken_getTextChars (ltoken_marker);
1308 str = ltoken_getTextChars (ltoken_comment);
1313 /* Different from ProcessCharClass because only allow one extension */
1314 /* character. Therefore, the present extension character must be set to a */
1318 ProcessExtensionChar (void)
1320 ltoken stackToken = LSLGenTopPopShiftStack ();
1321 char firstChar = cstring_firstChar (ltoken_unparse (stackToken));
1323 if (!defineSingleChar[(int)firstChar]
1324 && lscanCharClass (firstChar) == SINGLECHAR)
1326 /* Is a single character that has not been defined before. */
1327 /* Can only have one extension char. Release old one. */
1328 lsetCharClass (firstChar, CHC_EXTENSION);
1330 /* this is a (bogus) type bug! caught by splint */
1331 /* lsetCharClass (currentExtensionChar, SINGLECHAR); */
1333 lsetCharClass ((char) currentExtensionChar, SINGLECHAR);
1335 currentExtensionChar = (charCode) firstChar;
1336 UpdateXCharKeywords (currentExtensionChar);
1340 /* Already redefined. Don't allow to be redefined. */
1341 LocalUserError (stackToken, "character is already defined, cannot redefine");
1343 ltoken_free (stackToken);
1346 /* Different from ProcessSingleChar because allow any characters to be */
1347 /* endCommentChar and also set a different part of the scanner structure. */
1350 ProcessEndCommentChar (void)
1352 ltoken stackToken = LSLGenTopPopShiftStack ();
1353 char firstChar = cstring_firstChar (ltoken_unparse (stackToken));
1355 if (LSLIsEndComment (firstChar))
1357 LocalUserError (stackToken,
1358 "already defined as a endCommentChar, cannot redefine");
1362 lsetEndCommentChar (firstChar, TRUE);
1364 ltoken_free (stackToken);
1368 ProcessSingleChar (charCode code)
1370 ltoken stackToken = LSLGenTopPopShiftStack ();
1371 char firstChar = cstring_firstChar (ltoken_unparse (stackToken));
1373 if (!defineSingleChar[(int)firstChar]
1374 && lscanCharClass (firstChar) == SINGLECHAR)
1376 /* Is a single character that has not been defined before. */
1377 /* It's OK to redefine once. */
1378 lsetCharClass (firstChar, code);
1379 /* OK to mark as a defined singleChar even if not. Only check */
1380 /* defineSingleChar[] if defining a singleChar. */
1381 defineSingleChar[(int)firstChar] = TRUE;
1385 LocalUserError (stackToken, "character is already defined, cannot redefine");
1387 ltoken_free (stackToken);
1391 ProcessToken (ltokenCode code)
1393 ltoken stackToken, temp;
1396 stackToken = LSLGenTopPopShiftStack ();
1397 sym = ltoken_getText (stackToken);
1401 LocalUserError (stackToken,
1402 "already defined as a synonym, cannot redefine");
1405 /* Get the token from the token table, so can check if the token */
1406 /* was updated by a previous token. */
1407 temp = LSLGetToken (sym);
1409 if (ltoken_isStateDefined (temp))
1411 if ((code == LST_OPENSYM && sym == lsymbol_fromChars ("[")) ||
1412 (code == LST_CLOSESYM && sym == lsymbol_fromChars ("]")))
1414 /* ignore "openSym [" and "closeSym ]" TokenClass */
1415 ltoken_free (stackToken);
1420 LocalUserError (stackToken, "already defined, cannot redefine");
1425 LSLUpdateToken (code, ltoken_getText (stackToken), TRUE);
1426 ltoken_free (stackToken);
1431 ProcessSynonym (void)
1436 newtok = LSLGenTopPopShiftStack ();
1437 oldtok = LSLGenTopPopShiftStack ();
1439 if (ltoken_wasSyn (newtok))
1441 /* The token has a synonym. This means that the synonym was in the */
1442 /* init file, so complain about redefining as a synonym again */
1443 LocalUserError (newtok, "newtok already is a synonym, cannot redefine");
1446 if (ltoken_hasSyn (newtok))
1449 ** newtok already has a synonym defined for it. Do not allow
1450 ** synonyms to be chained.
1453 LocalUserError (newtok,
1454 "newtok already has a synonym, cannot chain synonyms");
1457 if (ltoken_isStateDefined (newtok))
1459 LocalUserError (newtok, "newtok already defined, cannot redefine");
1462 LSLAddSyn (ltoken_getText (newtok), ltoken_getText (oldtok));
1463 ltoken_free (oldtok);
1464 ltoken_free (newtok);
1469 * Utilities, in alphabetical order
1473 LocalUserError (ltoken t, /*@temp@*/ char *msg)
1475 lldiagmsg (message ("%s %s in the LSL init file:",
1476 ltoken_unparse (t), cstring_fromChars (msg)));
1478 ltoken_free (nextToken);
1479 nextToken = LSLScanNextToken ();
1481 while (ltoken_getCode (nextToken) != LST_EOL)
1483 ltoken_free (nextToken);
1484 nextToken = LSLScanNextToken ();
1489 ** Required initialization and cleanup routines
1492 static /*@exposed@*/ ltoken insertSimpleToken (char *text)
1493 /*@modifies internalState@*/
1495 return (LSLInsertToken (LST_SIMPLEID, lsymbol_fromChars (text), 0, FALSE));
1499 lslinit_initProcessInitFile (void)
1503 LSLGenInit (TRUE); /* parsing LSLinit not LCLinit */
1506 ** Insert the init file keywords into the token table as undefined
1507 ** SIMPLEIDs. They are defined as simpleIds since they must be treated
1508 ** that way if they do not appear as the first token on a line, and
1509 ** they must be treated that way for the actual LSL parsing. Save the
1510 ** tokens so can recognize as init file keywords when necessary.
1513 endCommentCharToken = insertSimpleToken ("endCommentChar");
1514 idCharToken = insertSimpleToken ("idChar");
1515 opCharToken = insertSimpleToken ("opChar");
1516 extensionCharToken = insertSimpleToken ("extensionChar");
1517 singleCharToken = insertSimpleToken ("singleChar");
1518 whiteCharToken = insertSimpleToken ("whiteChar");
1520 quantifierSymToken = insertSimpleToken ("quantifierSym");
1521 logicalOpToken = insertSimpleToken ("logicalOp");
1522 eqOpToken = insertSimpleToken ("eqOp");
1523 equationSymToken = insertSimpleToken ("equationSym");
1524 eqSepSymToken = insertSimpleToken ("eqSepSym");
1525 selectSymToken = insertSimpleToken ("selectSym");
1526 openSymToken = insertSimpleToken ("openSym");
1527 sepSymToken = insertSimpleToken ("sepSym");
1528 closeSymToken = insertSimpleToken ("closeSym");
1529 simpleIdToken = insertSimpleToken ("simpleId");
1530 mapSymToken = insertSimpleToken ("mapSym");
1531 markerSymToken = insertSimpleToken ("markerSym");
1532 commentSymToken = insertSimpleToken ("commentSym");
1533 synonymToken = insertSimpleToken ("synonym");
1535 for (i = 0; i <= LASTCHAR; i++)
1537 defineSingleChar[i] = FALSE;
1541 ** Record the current extension character so can redefine back to
1542 ** singleChar if a new extension character is redefined.
1545 currentExtensionChar = (charCode) CHAREXTENDER;
1547 LSLReportEolTokens (TRUE);
1548 ltoken_free (nextToken);
1549 nextToken = LSLScanNextToken ();
1552 void lslinit_process (void)
1553 /*@globals undef g_symtab; @*/
1554 /*@modifies g_symtab, internalState, fileSystem; @*/
1557 ** Open init file provided by user, or use the default LCL init file
1560 cstring larchpath = context_getLarchPath ();
1561 inputStream initstream = inputStream_undefined;
1565 if (inputStream_isUndefined (s_initFile))
1567 s_initFile = inputStream_create (cstring_makeLiteral (INITFILENAME),
1568 cstring_makeLiteralTemp (LCLINIT_SUFFIX),
1571 if (!inputStream_getPath (larchpath, s_initFile))
1573 lldiagmsg (message ("Continuing without LCL init file: %s",
1574 inputStream_fileName (s_initFile)));
1578 if (!inputStream_open (s_initFile))
1580 lldiagmsg (message ("Continuing without LCL init file: %s",
1581 inputStream_fileName (s_initFile)));
1587 if (!inputStream_open (s_initFile))
1589 lldiagmsg (message ("Continuing without LCL init file: %s",
1590 inputStream_fileName (s_initFile)));
1594 /* Initialize checker */
1601 LCLSynTableReset ();
1602 LCLTokenTableInit ();
1608 LCLScanLineReset ();
1614 /* need this to initialize LCL checker */
1616 llassert (inputStream_isDefined (s_initFile));
1617 if (inputStream_isOpen (s_initFile))
1621 LCLScanReset (s_initFile);
1630 check (inputStream_close (s_initFile));
1633 /* Initialize LSL init files, for parsing LSL signatures from LSL */
1635 initstream = inputStream_create (cstring_makeLiteral ("lslinit.lsi"),
1636 cstring_makeLiteralTemp (".lsi"),
1639 if (!inputStream_getPath (larchpath, initstream))
1641 lldiagmsg (message ("Continuing without LSL init file: %s",
1642 inputStream_fileName (initstream)));
1646 if (!inputStream_open (initstream))
1648 lldiagmsg (message ("Continuing without LSL init file: %s",
1649 inputStream_fileName (initstream)));
1665 if (inputStream_isOpen (initstream))
1668 LSLScanReset (initstream);
1669 lslinit_initProcessInitFile ();
1670 lslinit_processInitFile ();
1671 check (inputStream_close (initstream));
1674 inputStream_free (initstream);
1679 (cstring_makeLiteral ("LSL init file error. Attempting to continue."));
1683 g_symtab = symtable_new ();
1686 ** sort_init must come after symtab has been initialized
1693 ** Equivalent to importing old spec_csupport.lcl
1694 ** define immutable LCL type "bool" and bool constants TRUE and FALSE
1695 ** and initialized them to be equal to LSL's "true" and "false".
1697 ** Reads in CTrait.syms (derived from CTrait.lsl) on LARCH_PATH.
1701 LCLReportEolTokens (FALSE);