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"
33 # include "lslgrammar.h"
35 # include "lslscanline.h"
36 # include "lsltokentable.h"
37 # include "lslsyntable.h"
42 # include "lclscanline.h"
43 # include "lclsyntable.h"
44 # include "lcltokentable.h"
46 /* needed to parse init files */
52 # define LTRACE(rule) printf ("Reducing: %s\n", rule)
58 static void LocalUserError (ltoken p_t
, /*@temp@*/ char *p_msg
)
59 /*@modifies *g_warningstream@*/;
61 static /*@only@*/ ltoken nextToken
;
63 static /*@only@*/ /*@null@*/ inputStream s_initFile
= inputStream_undefined
;
65 static void InitFile (void) /*@modifies nextToken@*/ ;
66 static void InitLines (void) /*@modifies nextToken@*/ ;
67 static void InitLine (void) /*@modifies nextToken@*/ ;
68 static void Classification (void) /*@modifies nextToken@*/ ;
69 static void CharClass (void) /*@modifies nextToken@*/ ;
71 static void EndCommentChars (void) /*@modifies nextToken@*/ ;
72 static void IdChars (void) /*@modifies nextToken@*/ ;
73 static void OpChars (void) /*@modifies nextToken@*/ ;
74 static void ExtensionChar (void) /*@modifies nextToken@*/ ;
75 static void SingChars (void) /*@modifies nextToken@*/ ;
76 static void WhiteChars (void) /*@modifies nextToken@*/ ;
77 static void EndCommentChar (void) /*@modifies nextToken@*/ ;
78 static void IdChar (void) /*@modifies nextToken@*/ ;
79 static void OpChar (void) /*@modifies nextToken@*/ ;
80 static void SingChar (void) /*@modifies nextToken@*/ ;
81 static void WhiteChar (void) /*@modifies nextToken@*/ ;
83 static void TokenClass (void) /*@modifies nextToken@*/ ;
84 static void QuantifierSymToks (void) /*@modifies nextToken@*/ ;
85 static void LogicalOpToks (void) /*@modifies nextToken@*/ ;
86 static void EqOpToks (void) /*@modifies nextToken@*/ ;
87 static void EquationSymToks (void) /*@modifies nextToken@*/ ;
88 static void EqSepSymToks (void) /*@modifies nextToken@*/ ;
89 static void SelectSymToks (void) /*@modifies nextToken@*/ ;
90 static void OpenSymToks (void) /*@modifies nextToken@*/ ;
91 static void SepSymToks (void) /*@modifies nextToken@*/ ;
92 static void CloseSymToks (void) /*@modifies nextToken@*/ ;
93 static void SimpleIdToks (void) /*@modifies nextToken@*/ ;
94 static void MapSymToks (void) /*@modifies nextToken@*/ ;
95 static void MarkerSymToks (void) /*@modifies nextToken@*/ ;
96 static void CommentSymToks (void) /*@modifies nextToken@*/ ;
97 static void QuantifierSymTok (void) /*@modifies nextToken@*/ ;
98 static void LogicalOpTok (void) /*@modifies nextToken@*/ ;
99 static void EqOpTok (void) /*@modifies nextToken@*/ ;
100 static void EquationSymTok (void) /*@modifies nextToken@*/ ;
101 static void EqSepSymTok (void) /*@modifies nextToken@*/ ;
102 static void SelectSymTok (void) /*@modifies nextToken@*/ ;
103 static void OpenSymTok (void) /*@modifies nextToken@*/ ;
104 static void SepSymTok (void) /*@modifies nextToken@*/ ;
105 static void CloseSymTok (void) /*@modifies nextToken@*/ ;
106 static void SimpleIdTok (void) /*@modifies nextToken@*/ ;
107 static void MapSymTok (void) /*@modifies nextToken@*/ ;
108 static void MarkerSymTok (void) /*@modifies nextToken@*/ ;
109 static void CommentSymTok (void) /*@modifies nextToken@*/ ;
110 static void SynClass (void) /*@modifies nextToken@*/ ;
111 static void OldToken (void) /*@modifies nextToken@*/ ;
112 static void NewToken (void) /*@modifies nextToken@*/ ;
113 static void Token (void) /*@modifies nextToken@*/ ;
115 static void InitReduce (LSLInitRuleCode p_rule
) /*@modifies nextToken@*/ ;
116 static void UpdateXCharKeywords (charCode
) /*@modifies nextToken@*/ ;
117 static void ProcessExtensionChar (void) /*@modifies nextToken@*/ ;
118 static void ProcessEndCommentChar (void) /*@modifies nextToken@*/ ;
119 static void ProcessSingleChar (charCode p_code
) /*@modifies nextToken@*/ ;
120 static void ProcessToken (ltokenCode p_code
) /*@modifies nextToken@*/ ;
121 static void ProcessSynonym (void) /*@modifies nextToken@*/ ;
123 /* If TRUE character has been redefined as a singleChar. */
124 static bool defineSingleChar
[LASTCHAR
+ 1];
126 static charCode currentExtensionChar
;
128 /* LSL init file keyword tokens. */
130 static /*@dependent@*/ ltoken endCommentCharToken
;
131 static /*@dependent@*/ ltoken idCharToken
;
132 static /*@dependent@*/ ltoken opCharToken
;
133 static /*@dependent@*/ ltoken extensionCharToken
;
134 static /*@dependent@*/ ltoken singleCharToken
;
135 static /*@dependent@*/ ltoken whiteCharToken
;
136 static /*@dependent@*/ ltoken quantifierSymToken
;
137 static /*@dependent@*/ ltoken logicalOpToken
;
138 static /*@dependent@*/ ltoken eqOpToken
;
139 static /*@dependent@*/ ltoken equationSymToken
;
140 static /*@dependent@*/ ltoken eqSepSymToken
;
141 static /*@dependent@*/ ltoken selectSymToken
;
142 static /*@dependent@*/ ltoken openSymToken
;
143 static /*@dependent@*/ ltoken sepSymToken
;
144 static /*@dependent@*/ ltoken closeSymToken
;
145 static /*@dependent@*/ ltoken simpleIdToken
;
146 static /*@dependent@*/ ltoken mapSymToken
;
147 static /*@dependent@*/ ltoken markerSymToken
;
148 static /*@dependent@*/ ltoken commentSymToken
;
149 static /*@dependent@*/ ltoken synonymToken
;
152 hasFirstChar (ltoken tok
)
154 return (ltoken_isChar (tok
)
155 && lscanCharClass (cstring_firstChar (ltoken_unparse (tok
))) == SINGLECHAR
);
159 lslinit_setInitFile (inputStream s
)
161 llassert (inputStream_isUndefined (s_initFile
));
167 ** Parsing functions for init file processing, in the same order as the
168 ** grammar file lslinit.cfg. This is top-down order, as much as possible.
172 static void lslinit_processInitFile (void)
175 InitReduce (INITFILE1
);
177 if (ltoken_getCode (nextToken
) != LEOFTOKEN
)
179 LocalUserError (nextToken
, "unexpected tokens after end-of-file");
186 InitReduce (INITLINES1
);
188 if (ltoken_getCode (nextToken
) != LEOFTOKEN
)
191 InitReduce (INITLINES2
);
194 while (ltoken_getCode (nextToken
) != LEOFTOKEN
)
197 InitReduce (INITLINES3
);
205 if (ltoken_getCode (nextToken
) == LST_EOL
)
207 /* Nothing on line. */
208 InitReduce (INITLINE1
);
213 InitReduce (INITLINE2
);
216 if (ltoken_getCode (nextToken
) != LST_EOL
)
218 LocalUserError (nextToken
, "Unexpected tokens on line");
221 ltoken_free (nextToken
);
222 nextToken
= LSLScanNextToken ();
226 Classification (void)
228 if (ltoken_getRawText (nextToken
) == ltoken_getText (endCommentCharToken
)
229 || ltoken_getRawText (nextToken
) == ltoken_getText (idCharToken
)
230 || ltoken_getRawText (nextToken
) == ltoken_getText (opCharToken
)
231 || ltoken_getRawText (nextToken
) == ltoken_getText (extensionCharToken
)
232 || ltoken_getRawText (nextToken
) == ltoken_getText (singleCharToken
)
233 || ltoken_getRawText (nextToken
) == ltoken_getText (whiteCharToken
))
236 InitReduce (CLASSIFICATION1
);
238 else if (ltoken_getRawText (nextToken
) == ltoken_getText (quantifierSymToken
)
239 || ltoken_getRawText (nextToken
) == ltoken_getText (logicalOpToken
)
240 || ltoken_getRawText (nextToken
) == ltoken_getText (eqOpToken
)
241 || ltoken_getRawText (nextToken
) == ltoken_getText (equationSymToken
)
242 || ltoken_getRawText (nextToken
) == ltoken_getText (eqSepSymToken
)
243 || ltoken_getRawText (nextToken
) == ltoken_getText (selectSymToken
)
244 || ltoken_getRawText (nextToken
) == ltoken_getText (openSymToken
)
245 || ltoken_getRawText (nextToken
) == ltoken_getText (sepSymToken
)
246 || ltoken_getRawText (nextToken
) == ltoken_getText (closeSymToken
)
247 || ltoken_getRawText (nextToken
) == ltoken_getText (simpleIdToken
)
248 || ltoken_getRawText (nextToken
) == ltoken_getText (mapSymToken
)
249 || ltoken_getRawText (nextToken
) == ltoken_getText (markerSymToken
)
250 || ltoken_getRawText (nextToken
) == ltoken_getText (commentSymToken
))
253 InitReduce (CLASSIFICATION2
);
255 else if (ltoken_getRawText (nextToken
) == ltoken_getText (synonymToken
))
258 InitReduce (CLASSIFICATION3
);
262 LocalUserError (nextToken
,
263 "expected character, token, or synonym classification");
270 ltoken charClassToken
;
272 charClassToken
= nextToken
;
274 nextToken
= LSLScanNextToken (); /* Discard char class keyword. */
276 if (ltoken_getRawText (charClassToken
) == ltoken_getText (endCommentCharToken
))
279 InitReduce (CHARCLASS1
);
281 else if (ltoken_getRawText (charClassToken
) == ltoken_getText (idCharToken
))
284 InitReduce (CHARCLASS2
);
286 else if (ltoken_getRawText (charClassToken
) == ltoken_getText (opCharToken
))
289 InitReduce (CHARCLASS3
);
291 else if (ltoken_getRawText (charClassToken
)
292 == ltoken_getText (extensionCharToken
))
295 InitReduce (CHARCLASS4
);
297 else if (ltoken_getRawText (charClassToken
) == ltoken_getText (singleCharToken
))
300 InitReduce (CHARCLASS5
);
302 else if (ltoken_getRawText (charClassToken
) == ltoken_getText (whiteCharToken
))
305 InitReduce (CHARCLASS6
);
309 LocalUserError (nextToken
, "expected character classification");
312 ltoken_free (charClassToken
);
316 EndCommentChars (void)
319 InitReduce (LRC_ENDCOMMENT1
);
321 while (ltoken_getCode (nextToken
) != LST_EOL
)
324 InitReduce (LRC_ENDCOMMENT2
);
333 InitReduce (IDCHARS1
);
335 while (ltoken_getCode (nextToken
) != LST_EOL
)
338 InitReduce (IDCHARS2
);
346 InitReduce (OPCHARS1
);
348 while (ltoken_getCode (nextToken
) != LST_EOL
)
351 InitReduce (OPCHARS2
);
358 if (ltoken_isChar (nextToken
)
359 && lscanCharClass (cstring_firstChar (ltoken_unparse (nextToken
))) == SINGLECHAR
)
361 LSLGenShiftOnly (nextToken
);
362 nextToken
= LSLScanNextToken ();
363 InitReduce (LRC_EXTENSIONCHAR1
);
367 LocalUserError (nextToken
, "expected only one character");
375 InitReduce (SINGCHARS1
);
377 while (ltoken_getCode (nextToken
) != LST_EOL
)
380 InitReduce (SINGCHARS2
);
388 InitReduce (WHITECHARS1
);
390 while (ltoken_getCode (nextToken
) != LST_EOL
)
393 InitReduce (WHITECHARS2
);
398 EndCommentChar (void)
400 if (ltoken_isChar (nextToken
))
402 LSLGenShiftOnly (nextToken
);
403 nextToken
= LSLScanNextToken ();
404 InitReduce (LRC_ENDCOMMENTCHAR1
);
408 LocalUserError (nextToken
, "expected only one character");
415 if (hasFirstChar (nextToken
))
417 LSLGenShiftOnly (nextToken
);
418 nextToken
= LSLScanNextToken ();
419 InitReduce (IDCHAR1
);
423 LocalUserError (nextToken
, "character is already defined, cannot redefine");
430 if (hasFirstChar (nextToken
))
432 LSLGenShiftOnly (nextToken
);
433 nextToken
= LSLScanNextToken ();
434 InitReduce (OPCHAR1
);
438 LocalUserError (nextToken
, "character is already defined, cannot redefine");
445 if (hasFirstChar (nextToken
))
447 LSLGenShiftOnly (nextToken
);
448 nextToken
= LSLScanNextToken ();
449 InitReduce (SINGCHAR1
);
453 LocalUserError (nextToken
, "character is already defined, cannot redefine");
460 if (hasFirstChar (nextToken
))
462 LSLGenShiftOnly (nextToken
);
463 nextToken
= LSLScanNextToken ();
464 InitReduce (WHITECHAR1
);
468 LocalUserError (nextToken
, "character is already defined, cannot redefine");
475 ltoken tokenClassToken
;
477 tokenClassToken
= nextToken
;
479 nextToken
= LSLScanNextToken ();
481 if (ltoken_getRawText (tokenClassToken
) == ltoken_getText (quantifierSymToken
))
483 QuantifierSymToks ();
484 InitReduce (TOKENCLASS1
);
486 else if (ltoken_getRawText (tokenClassToken
) == ltoken_getText (logicalOpToken
))
489 InitReduce (TOKENCLASS2
);
491 else if (ltoken_getRawText (tokenClassToken
) == ltoken_getText (eqOpToken
))
494 InitReduce (TOKENCLASS3
);
496 else if (ltoken_getRawText (tokenClassToken
)
497 == ltoken_getText (equationSymToken
))
500 InitReduce (TOKENCLASS4
);
502 else if (ltoken_getRawText (tokenClassToken
) == ltoken_getText (eqSepSymToken
))
505 InitReduce (TOKENCLASS5
);
507 else if (ltoken_getRawText (tokenClassToken
) == ltoken_getText (selectSymToken
))
510 InitReduce (TOKENCLASS6
);
512 else if (ltoken_getRawText (tokenClassToken
) == ltoken_getText (openSymToken
))
515 InitReduce (TOKENCLASS7
);
517 else if (ltoken_getRawText (tokenClassToken
) == ltoken_getText (sepSymToken
))
520 InitReduce (TOKENCLASS8
);
522 else if (ltoken_getRawText (tokenClassToken
) == ltoken_getText (closeSymToken
))
525 InitReduce (TOKENCLASS9
);
527 else if (ltoken_getRawText (tokenClassToken
) == ltoken_getText (simpleIdToken
))
530 InitReduce (TOKENCLASS10
);
532 else if (ltoken_getRawText (tokenClassToken
) == ltoken_getText (mapSymToken
))
535 InitReduce (TOKENCLASS11
);
537 else if (ltoken_getRawText (tokenClassToken
) == ltoken_getText (markerSymToken
))
540 InitReduce (TOKENCLASS12
);
542 else if (ltoken_getRawText (tokenClassToken
)
543 == ltoken_getText (commentSymToken
))
546 InitReduce (TOKENCLASS13
);
550 LocalUserError (nextToken
, "expected token classification");
553 ltoken_free (tokenClassToken
);
557 QuantifierSymToks (void)
560 InitReduce (QUANTIFIERSYMTOKS1
);
562 while (ltoken_getCode (nextToken
) != LST_EOL
)
565 InitReduce (QUANTIFIERSYMTOKS2
);
573 InitReduce (LOGICALOPTOKS1
);
575 while (ltoken_getCode (nextToken
) != LST_EOL
)
578 InitReduce (LOGICALOPTOKS2
);
586 InitReduce (LRC_EQOPTOKS1
);
588 while (ltoken_getCode (nextToken
) != LST_EOL
)
591 InitReduce (LRC_EQOPTOKS2
);
596 EquationSymToks (void)
599 InitReduce (LRC_EQUATIONSYMTOKS1
);
601 while (ltoken_getCode (nextToken
) != LST_EOL
)
604 InitReduce (LRC_EQUATIONSYMTOKS2
);
612 InitReduce (LRC_EQSEPSYMTOKS1
);
614 while (ltoken_getCode (nextToken
) != LST_EOL
)
617 InitReduce (LRC_EQSEPSYMTOKS2
);
625 InitReduce (SELECTSYMTOKS1
);
627 while (ltoken_getCode (nextToken
) != LST_EOL
)
630 InitReduce (SELECTSYMTOKS2
);
638 InitReduce (OPENSYMTOKS1
);
640 while (ltoken_getCode (nextToken
) != LST_EOL
)
643 InitReduce (OPENSYMTOKS2
);
651 InitReduce (SEPSYMTOKS1
);
653 while (ltoken_getCode (nextToken
) != LST_EOL
)
656 InitReduce (SEPSYMTOKS2
);
664 InitReduce (CLOSESYMTOKS1
);
666 while (ltoken_getCode (nextToken
) != LST_EOL
)
669 InitReduce (CLOSESYMTOKS2
);
677 InitReduce (SIMPLEIDTOKS1
);
679 while (ltoken_getCode (nextToken
) != LST_EOL
)
682 InitReduce (SIMPLEIDTOKS2
);
690 InitReduce (MAPSYMTOKS1
);
692 while (ltoken_getCode (nextToken
) != LST_EOL
)
695 InitReduce (MAPSYMTOKS2
);
703 InitReduce (MARKERSYMTOKS1
);
705 while (ltoken_getCode (nextToken
) != LST_EOL
)
708 InitReduce (MARKERSYMTOKS2
);
713 CommentSymToks (void)
716 InitReduce (COMMENTSYMTOKS1
);
718 while (ltoken_getCode (nextToken
) != LST_EOL
)
721 InitReduce (COMMENTSYMTOKS2
);
726 QuantifierSymTok (void)
729 InitReduce (QUANTIFIERSYMTOK1
);
736 InitReduce (LOGICALOPTOK1
);
743 InitReduce (LRC_EQOPTOK1
);
747 EquationSymTok (void)
749 /* ### EquationSymTok (); ### */
751 InitReduce (LRC_EQUATIONSYMTOK1
);
758 InitReduce (LRC_EQSEPSYMTOK1
);
766 InitReduce (SELECTSYMTOK1
);
773 InitReduce (OPENSYMTOK1
);
780 InitReduce (SEPSYMTOK1
);
787 InitReduce (CLOSESYMTOK1
);
794 InitReduce (SIMPLEIDTOK1
);
801 InitReduce (MAPSYMTOK1
);
808 InitReduce (MARKERSYMTOK1
);
816 InitReduce (COMMENTSYMTOK1
);
823 if (ltoken_getRawText (nextToken
) == ltoken_getText (synonymToken
))
825 ltoken_free (nextToken
);
826 nextToken
= LSLScanNextToken ();
831 InitReduce (SYNCLASS1
);
835 LocalUserError (nextToken
, "expected synonym classification");
844 InitReduce (OLDTOKEN1
);
852 InitReduce (NEWTOKEN1
);
859 if (ltoken_getCode (nextToken
) == LST_EOL
860 || ltoken_getCode (nextToken
) == LEOFTOKEN
)
862 LocalUserError (nextToken
, "unexpected end-of-line or end-of-file");
866 LSLGenShiftOnly (nextToken
);
867 nextToken
= LSLScanNextToken ();
872 ** Init File Processing Routines, these routines use the shift-reduce sequence
873 ** produced by the init file parser and update the necessary tables for the
876 ** The same shift stack is used that LSL parser uses. A different reduce
877 ** procedure is used because the init file grammar is different from the LSL
883 InitReduce (LSLInitRuleCode rule
)
888 LTRACE ("INITFILE1");
892 LTRACE ("INITLINES1");
896 LTRACE ("INITLINES2");
900 LTRACE ("INITLINES3");
904 LTRACE ("INITLINE1");
908 LTRACE ("INITLINE2");
911 case CLASSIFICATION1
:
912 LTRACE ("CLASSIFICATION1");
915 case CLASSIFICATION2
:
916 LTRACE ("CLASSIFICATION2");
919 case CLASSIFICATION3
:
920 LTRACE ("CLASSIFICATION3");
924 LTRACE ("CHARCLASS1");
928 LTRACE ("CHARCLASS2");
932 LTRACE ("CHARCLASS3");
936 LTRACE ("CHARCLASS4");
940 LTRACE ("CHARCLASS5");
944 LTRACE ("CHARCLASS6");
947 case LRC_ENDCOMMENT1
:
948 LTRACE ("LRC_ENDCOMMENT1");
951 case LRC_ENDCOMMENT2
:
952 LTRACE ("LRC_ENDCOMMENT2");
971 case LRC_EXTENSIONCHAR1
:
972 LTRACE ("LRC_EXTENSIONCHAR1");
973 ProcessExtensionChar ();
977 LTRACE ("SINGCHARS1");
981 LTRACE ("SINGCHARS2");
985 LTRACE ("WHITECHARS1");
989 LTRACE ("WHITECHARS2");
992 case LRC_ENDCOMMENTCHAR1
:
993 LTRACE ("LRC_ENDCOMMENTCHAR1");
994 ProcessEndCommentChar ();
999 ProcessSingleChar (IDCHAR
);
1004 ProcessSingleChar (OPCHAR
);
1008 LTRACE ("SINGCHAR1");
1009 ProcessSingleChar (SINGLECHAR
);
1014 ProcessSingleChar (WHITECHAR
);
1018 LTRACE ("TOKENCLASS1");
1022 LTRACE ("TOKENCLASS2");
1026 LTRACE ("TOKENCLASS3");
1030 LTRACE ("TOKENCLASS4");
1034 LTRACE ("TOKENCLASS5");
1038 LTRACE ("TOKENCLASS6");
1042 LTRACE ("TOKENCLASS7");
1046 LTRACE ("TOKENCLASS8");
1050 LTRACE ("TOKENCLASS9");
1054 LTRACE ("TOKENCLASS10");
1058 LTRACE ("TOKENCLASS11");
1062 LTRACE ("TOKENCLASS12");
1066 LTRACE ("TOKENCLASS13");
1069 case QUANTIFIERSYMTOKS1
:
1070 LTRACE ("QUALIFERSYMTOKS1");
1073 case QUANTIFIERSYMTOKS2
:
1074 LTRACE ("QUANTIFIERSYMTOKS2");
1077 case LOGICALOPTOKS1
:
1078 LTRACE ("LOGICALOPTOKS1");
1081 case LOGICALOPTOKS2
:
1082 LTRACE ("LOGICALOPTOKS2");
1086 LTRACE ("LRC_EQOPTOKS1");
1090 LTRACE ("LRC_EQOPTOKS2");
1093 case LRC_EQUATIONSYMTOKS1
:
1094 LTRACE ("LRC_EQUATIONSYMTOKS1");
1097 case LRC_EQUATIONSYMTOKS2
:
1098 LTRACE ("LRC_EQUATIONSYMTOKS2");
1101 case LRC_EQSEPSYMTOKS1
:
1102 LTRACE ("LRC_EQSEPSYMTOKS1");
1105 case LRC_EQSEPSYMTOKS2
:
1106 LTRACE ("LRC_EQSEPSYMTOKS2");
1109 case SELECTSYMTOKS1
:
1110 LTRACE ("SELECTSYMTOKS1");
1113 case SELECTSYMTOKS2
:
1114 LTRACE ("SELECTSYMTOKS2");
1118 LTRACE ("OPENSYMTOKS1");
1122 LTRACE ("OPENSYMTOKS2");
1126 LTRACE ("SEPSYMTOKS1");
1130 LTRACE ("SEPSYMTOKS2");
1134 LTRACE ("CLOSESYMTOKS1");
1138 LTRACE ("CLOSESYMTOKS2");
1142 LTRACE ("SIMPLEIDTOKS1");
1146 LTRACE ("SIMPLEIDTOKS2");
1150 LTRACE ("MAPSYMTOKS1");
1154 LTRACE ("MAPSYMTOKS2");
1157 case MARKERSYMTOKS1
:
1158 LTRACE ("MARKERSYMTOKS1");
1161 case MARKERSYMTOKS2
:
1162 LTRACE ("MARKERSYMTOKS2");
1165 case COMMENTSYMTOKS1
:
1166 LTRACE ("COMMENTSYMTOKS1");
1169 case COMMENTSYMTOKS2
:
1170 LTRACE ("COMMENTSYMTOKS2");
1173 case QUANTIFIERSYMTOK1
:
1174 LTRACE ("QUANTIFERSYMTOK1");
1175 ProcessToken (LST_QUANTIFIERSYM
);
1179 LTRACE ("LOGICALOPTOK1");
1180 ProcessToken (LST_LOGICALOP
);
1184 LTRACE ("LRC_EQOPTOK1");
1185 ProcessToken (LST_EQOP
);
1188 case LRC_EQUATIONSYMTOK1
:
1189 LTRACE ("LRC_EQUATIONSYMTOK1");
1190 ProcessToken (LST_EQUATIONSYM
);
1193 case LRC_EQSEPSYMTOK1
:
1194 LTRACE ("LRC_EQSEPSYMTOK1");
1195 ProcessToken (LST_EQSEPSYM
);
1199 LTRACE ("SELECTSYMTOK1");
1200 ProcessToken (LST_SELECTSYM
);
1204 LTRACE ("OPENSYMTOK1");
1205 ProcessToken (LST_OPENSYM
);
1209 LTRACE ("SEPSYMTOK1");
1210 ProcessToken (LST_SEPSYM
);
1214 LTRACE ("CLOSESYMTOK1");
1215 ProcessToken (LST_CLOSESYM
);
1219 LTRACE ("SIMPLEIDTOK1");
1220 ProcessToken (LST_SIMPLEID
);
1224 LTRACE ("MAPSYMTOK1");
1225 ProcessToken (LST_MAPSYM
);
1229 LTRACE ("MARKERSYMTOK1");
1230 ProcessToken (LST_MARKERSYM
);
1233 case COMMENTSYMTOK1
:
1234 LTRACE ("COMMENTSYMTOK1");
1235 ProcessToken (LST_COMMENTSYM
);
1239 LTRACE ("SYNCLASS1");
1244 LTRACE ("OLDTOKEN1");
1248 LTRACE ("NEWTOKEN1");
1252 llcontbuglit ("InitReduce: bad switch");
1256 } /* end InitReduce () */
1260 /* Reset the first character of the predefined extensionChar keywords when */
1261 /* the extensionChar changes. e.g. "extensionChar @" changes "forall" to */
1265 UpdateXCharKeywords (charCode xCharCode
)
1267 char xChar
= (char) xCharCode
;
1270 str
= ltoken_getTextChars (ltoken_forall
);
1273 str
= ltoken_getTextChars (ltoken_and
);
1276 str
= ltoken_getTextChars (ltoken_or
);
1279 str
= ltoken_getTextChars (ltoken_implies
);
1282 str
= ltoken_getTextChars (ltoken_eq
);
1285 str
= ltoken_getTextChars (ltoken_neq
);
1288 str
= ltoken_getTextChars (ltoken_equals
);
1291 str
= ltoken_getTextChars (ltoken_eqsep
);
1294 str
= ltoken_getTextChars (ltoken_select
);
1297 str
= ltoken_getTextChars (ltoken_open
);
1300 str
= ltoken_getTextChars (ltoken_sep
);
1303 str
= ltoken_getTextChars (ltoken_close
);
1306 str
= ltoken_getTextChars (ltoken_id
);
1309 str
= ltoken_getTextChars (ltoken_arrow
);
1312 str
= ltoken_getTextChars (ltoken_marker
);
1315 str
= ltoken_getTextChars (ltoken_comment
);
1320 /* Different from ProcessCharClass because only allow one extension */
1321 /* character. Therefore, the present extension character must be set to a */
1325 ProcessExtensionChar (void)
1327 ltoken stackToken
= LSLGenTopPopShiftStack ();
1328 char firstChar
= cstring_firstChar (ltoken_unparse (stackToken
));
1330 if (!defineSingleChar
[(int)firstChar
]
1331 && lscanCharClass (firstChar
) == SINGLECHAR
)
1333 /* Is a single character that has not been defined before. */
1334 /* Can only have one extension char. Release old one. */
1335 lsetCharClass (firstChar
, CHC_EXTENSION
);
1337 /* this is a (bogus) type bug! caught by splint */
1338 /* lsetCharClass (currentExtensionChar, SINGLECHAR); */
1340 lsetCharClass ((char) currentExtensionChar
, SINGLECHAR
);
1342 currentExtensionChar
= (charCode
) firstChar
;
1343 UpdateXCharKeywords (currentExtensionChar
);
1347 /* Already redefined. Don't allow to be redefined. */
1348 LocalUserError (stackToken
, "character is already defined, cannot redefine");
1350 ltoken_free (stackToken
);
1353 /* Different from ProcessSingleChar because allow any characters to be */
1354 /* endCommentChar and also set a different part of the scanner structure. */
1357 ProcessEndCommentChar (void)
1359 ltoken stackToken
= LSLGenTopPopShiftStack ();
1360 char firstChar
= cstring_firstChar (ltoken_unparse (stackToken
));
1362 if (LSLIsEndComment (firstChar
))
1364 LocalUserError (stackToken
,
1365 "already defined as a endCommentChar, cannot redefine");
1369 lsetEndCommentChar (firstChar
, TRUE
);
1371 ltoken_free (stackToken
);
1375 ProcessSingleChar (charCode code
)
1377 ltoken stackToken
= LSLGenTopPopShiftStack ();
1378 char firstChar
= cstring_firstChar (ltoken_unparse (stackToken
));
1380 if (!defineSingleChar
[(int)firstChar
]
1381 && lscanCharClass (firstChar
) == SINGLECHAR
)
1383 /* Is a single character that has not been defined before. */
1384 /* It's OK to redefine once. */
1385 lsetCharClass (firstChar
, code
);
1386 /* OK to mark as a defined singleChar even if not. Only check */
1387 /* defineSingleChar[] if defining a singleChar. */
1388 defineSingleChar
[(int)firstChar
] = TRUE
;
1392 LocalUserError (stackToken
, "character is already defined, cannot redefine");
1394 ltoken_free (stackToken
);
1398 PrintToken (ltoken tok
)
1402 switch (ltoken_getCode (tok
))
1404 case NOTTOKEN
: codStr
= "*** NOTTOKEN ***"; break;
1405 case LST_QUANTIFIERSYM
: codStr
= "QUANTIFIERSYM"; break;
1406 case LST_LOGICALOP
: codStr
= "LOGICALOP: "; break;
1407 case LST_SELECTSYM
: codStr
= "LST_SELECTSYM"; break;
1408 case LST_OPENSYM
: codStr
= "LST_OPENSYM"; break;
1409 case LST_SEPSYM
: codStr
= "SEPSYM"; break;
1410 case LST_CLOSESYM
: codStr
= "LST_CLOSESYM"; break;
1411 case LST_SIMPLEID
: codStr
= "LST_SIMPLEID"; break;
1412 case LST_MAPSYM
: codStr
= "MAPSYM"; break;
1413 case LST_MARKERSYM
: codStr
= "LST_MARKERSYM"; break;
1414 case LST_COMMENTSYM
: codStr
= "COMMENTSYM"; break;
1415 case LST_SIMPLEOP
: codStr
= "SIMPLEOP"; break;
1416 case LST_COLON
: codStr
= "LST_COLON"; break;
1417 case LST_COMMA
: codStr
= "COMMA"; break;
1418 case LST_LBRACKET
: codStr
= "LST_LBRACKET"; break;
1419 case LST_LPAR
: codStr
= "LST_LPAR"; break;
1420 case LST_RBRACKET
: codStr
= "LST_RBRACKET"; break;
1421 case LST_RPAR
: codStr
= "LST_RPAR"; break;
1422 case LST_EQOP
: codStr
= "LST_EQOP"; break;
1423 case LST_WHITESPACE
: codStr
= "WHITESPACE,"; break;
1424 case LST_EOL
: codStr
= "LST_EOL"; break;
1425 case LST_elseTOKEN
: codStr
= "elseTOKEN"; break;
1426 case LST_ifTOKEN
: codStr
= "ifTOKEN"; break;
1427 case LST_thenTOKEN
: codStr
= "thenTOKEN"; break;
1428 case LST_BADTOKEN
: codStr
= "*** BADTOKEN ***"; break;
1429 case LEOFTOKEN
: /* can't reach LEOFTOKEN easily */
1430 codStr
= "LEOFTOKEN"; break;
1432 codStr
= "*** invalid token code ***";
1436 /* only used for debugging */
1437 printf ("%u:%u: Token Code (%u): %s",
1438 ltoken_getLine (tok
), ltoken_getCol (tok
),
1439 ltoken_getCode (tok
), codStr
);
1440 if (ltoken_getRawText (tok
) != 0)
1442 printf (", Token String (%lu): %s\n",
1443 ltoken_getRawText (tok
), ltoken_getRawTextChars (tok
));
1449 ProcessToken (ltokenCode code
)
1451 ltoken stackToken
, temp
;
1454 stackToken
= LSLGenTopPopShiftStack ();
1455 sym
= ltoken_getText (stackToken
);
1459 LocalUserError (stackToken
,
1460 "already defined as a synonym, cannot redefine");
1463 /* Get the token from the token table, so can check if the token */
1464 /* was updated by a previous token. */
1465 temp
= LSLGetToken (sym
);
1467 if (ltoken_isStateDefined (temp
))
1469 if ((code
== LST_OPENSYM
&& sym
== lsymbol_fromChars ("[")) ||
1470 (code
== LST_CLOSESYM
&& sym
== lsymbol_fromChars ("]")))
1472 /* ignore "openSym [" and "closeSym ]" TokenClass */
1473 ltoken_free (stackToken
);
1478 LocalUserError (stackToken
, "already defined, cannot redefine");
1483 LSLUpdateToken (code
, ltoken_getText (stackToken
), TRUE
);
1484 ltoken_free (stackToken
);
1489 ProcessSynonym (void)
1494 newtok
= LSLGenTopPopShiftStack ();
1495 oldtok
= LSLGenTopPopShiftStack ();
1497 if (ltoken_wasSyn (newtok
))
1499 /* The token has a synonym. This means that the synonym was in the */
1500 /* init file, so complain about redefining as a synonym again */
1501 LocalUserError (newtok
, "newtok already is a synonym, cannot redefine");
1504 if (ltoken_hasSyn (newtok
))
1507 ** newtok already has a synonym defined for it. Do not allow
1508 ** synonyms to be chained.
1511 LocalUserError (newtok
,
1512 "newtok already has a synonym, cannot chain synonyms");
1515 if (ltoken_isStateDefined (newtok
))
1517 LocalUserError (newtok
, "newtok already defined, cannot redefine");
1520 LSLAddSyn (ltoken_getText (newtok
), ltoken_getText (oldtok
));
1521 ltoken_free (oldtok
);
1522 ltoken_free (newtok
);
1527 * Utilities, in alphabetical order
1531 LocalUserError (ltoken t
, /*@temp@*/ char *msg
)
1533 lldiagmsg (message ("%s %s in the LSL init file:",
1534 ltoken_unparse (t
), cstring_fromChars (msg
)));
1536 ltoken_free (nextToken
);
1537 nextToken
= LSLScanNextToken ();
1539 while (ltoken_getCode (nextToken
) != LST_EOL
)
1541 ltoken_free (nextToken
);
1542 nextToken
= LSLScanNextToken ();
1547 ** Required initialization and cleanup routines
1550 static /*@exposed@*/ ltoken
insertSimpleToken (char *text
)
1551 /*@modifies internalState@*/
1553 return (LSLInsertToken (LST_SIMPLEID
, lsymbol_fromChars (text
), 0, FALSE
));
1557 lslinit_initProcessInitFile (void)
1561 LSLGenInit (TRUE
); /* parsing LSLinit not LCLinit */
1564 ** Insert the init file keywords into the token table as undefined
1565 ** SIMPLEIDs. They are defined as simpleIds since they must be treated
1566 ** that way if they do not appear as the first token on a line, and
1567 ** they must be treated that way for the actual LSL parsing. Save the
1568 ** tokens so can recognize as init file keywords when necessary.
1571 endCommentCharToken
= insertSimpleToken ("endCommentChar");
1572 idCharToken
= insertSimpleToken ("idChar");
1573 opCharToken
= insertSimpleToken ("opChar");
1574 extensionCharToken
= insertSimpleToken ("extensionChar");
1575 singleCharToken
= insertSimpleToken ("singleChar");
1576 whiteCharToken
= insertSimpleToken ("whiteChar");
1578 quantifierSymToken
= insertSimpleToken ("quantifierSym");
1579 logicalOpToken
= insertSimpleToken ("logicalOp");
1580 eqOpToken
= insertSimpleToken ("eqOp");
1581 equationSymToken
= insertSimpleToken ("equationSym");
1582 eqSepSymToken
= insertSimpleToken ("eqSepSym");
1583 selectSymToken
= insertSimpleToken ("selectSym");
1584 openSymToken
= insertSimpleToken ("openSym");
1585 sepSymToken
= insertSimpleToken ("sepSym");
1586 closeSymToken
= insertSimpleToken ("closeSym");
1587 simpleIdToken
= insertSimpleToken ("simpleId");
1588 mapSymToken
= insertSimpleToken ("mapSym");
1589 markerSymToken
= insertSimpleToken ("markerSym");
1590 commentSymToken
= insertSimpleToken ("commentSym");
1591 synonymToken
= insertSimpleToken ("synonym");
1593 for (i
= 0; i
<= LASTCHAR
; i
++)
1595 defineSingleChar
[i
] = FALSE
;
1599 ** Record the current extension character so can redefine back to
1600 ** singleChar if a new extension character is redefined.
1603 currentExtensionChar
= (charCode
) CHAREXTENDER
;
1605 LSLReportEolTokens (TRUE
);
1606 ltoken_free (nextToken
);
1607 nextToken
= LSLScanNextToken ();
1610 void lslinit_process (void)
1611 /*@globals undef g_symtab; @*/
1612 /*@modifies g_symtab, internalState, fileSystem; @*/
1615 ** Open init file provided by user, or use the default LCL init file
1618 cstring larchpath
= context_getLarchPath ();
1619 inputStream initstream
= inputStream_undefined
;
1623 if (inputStream_isUndefined (s_initFile
))
1625 s_initFile
= inputStream_create (cstring_makeLiteral (INITFILENAME
),
1626 cstring_makeLiteralTemp (LCLINIT_SUFFIX
),
1629 if (!inputStream_getPath (larchpath
, s_initFile
))
1631 lldiagmsg (message ("Continuing without LCL init file: %s",
1632 inputStream_fileName (s_initFile
)));
1636 if (!inputStream_open (s_initFile
))
1638 lldiagmsg (message ("Continuing without LCL init file: %s",
1639 inputStream_fileName (s_initFile
)));
1645 if (!inputStream_open (s_initFile
))
1647 lldiagmsg (message ("Continuing without LCL init file: %s",
1648 inputStream_fileName (s_initFile
)));
1652 /* Initialize checker */
1659 LCLSynTableReset ();
1660 LCLTokenTableInit ();
1666 LCLScanLineReset ();
1672 /* need this to initialize LCL checker */
1674 llassert (inputStream_isDefined (s_initFile
));
1675 if (inputStream_isOpen (s_initFile
))
1679 LCLScanReset (s_initFile
);
1688 check (inputStream_close (s_initFile
));
1691 /* Initialize LSL init files, for parsing LSL signatures from LSL */
1693 initstream
= inputStream_create (cstring_makeLiteral ("lslinit.lsi"),
1694 cstring_makeLiteralTemp (".lsi"),
1697 if (!inputStream_getPath (larchpath
, initstream
))
1699 lldiagmsg (message ("Continuing without LSL init file: %s",
1700 inputStream_fileName (initstream
)));
1704 if (!inputStream_open (initstream
))
1706 lldiagmsg (message ("Continuing without LSL init file: %s",
1707 inputStream_fileName (initstream
)));
1723 if (inputStream_isOpen (initstream
))
1726 LSLScanReset (initstream
);
1727 lslinit_initProcessInitFile ();
1728 lslinit_processInitFile ();
1729 check (inputStream_close (initstream
));
1732 inputStream_free (initstream
);
1737 (cstring_makeLiteral ("LSL init file error. Attempting to continue."));
1741 g_symtab
= symtable_new ();
1744 ** sort_init must come after symtab has been initialized
1751 ** Equivalent to importing old spec_csupport.lcl
1752 ** define immutable LCL type "bool" and bool constants TRUE and FALSE
1753 ** and initialized them to be equal to LSL's "true" and "false".
1755 ** Reads in CTrait.syms (derived from CTrait.lsl) on LARCH_PATH.
1759 LCLReportEolTokens (FALSE
);