/*
** Splint - annotation-assisted static program checker
** Copyright (C) 1994-2003 University of Virginia,
** Massachusetts Institute of Technology
**
** This program is free software; you can redistribute it and/or modify it
** under the terms of the GNU General Public License as published by the
** Free Software Foundation; either version 2 of the License, or (at your
** option) any later version.
**
** This program is distributed in the hope that it will be useful, but
** WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
** General Public License for more details.
**
** The GNU General Public License is available from http://www.gnu.org/ or
** the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
** MA 02111-1307, USA.
**
** For information on splint: info@splint.org
** To report a bug: splint-bug@splint.org
** For more information: http://www.splint.org
*/
/*
** lslinit.c
**
** Processor for Larch Shared Language Init Files
*/
# include "splintMacros.nf"
# include "basic.h"
# include "signature.h"
# include "signature2.h"
# include "scan.h"
# include "scanline.h"
# include "tokentable.h"
# include "syntable.h"
# include "lslinit.h"
# include "lclinit.h"
# include "lclscan.h"
# include "lclscanline.h"
# include "lclsyntable.h"
# include "lcltokentable.h"
/* needed to parse init files */
# include "shift.h"
#if TRACING == 1
/*@notfunction@*/
# define LTRACE(rule) printf ("Reducing: %s\n", rule)
#else
/*@notfunction@*/
# define LTRACE(rule)
#endif
static void LocalUserError (ltoken p_t, /*@temp@*/ char *p_msg)
/*@modifies *g_warningstream@*/;
static /*@only@*/ ltoken nextToken;
static /*@only@*/ /*@null@*/ inputStream s_initFile = inputStream_undefined;
static void InitFile (void) /*@modifies nextToken@*/ ;
static void InitLines (void) /*@modifies nextToken@*/ ;
static void InitLine (void) /*@modifies nextToken@*/ ;
static void Classification (void) /*@modifies nextToken@*/ ;
static void CharClass (void) /*@modifies nextToken@*/ ;
static void EndCommentChars (void) /*@modifies nextToken@*/ ;
static void IdChars (void) /*@modifies nextToken@*/ ;
static void OpChars (void) /*@modifies nextToken@*/ ;
static void ExtensionChar (void) /*@modifies nextToken@*/ ;
static void SingChars (void) /*@modifies nextToken@*/ ;
static void WhiteChars (void) /*@modifies nextToken@*/ ;
static void EndCommentChar (void) /*@modifies nextToken@*/ ;
static void IdChar (void) /*@modifies nextToken@*/ ;
static void OpChar (void) /*@modifies nextToken@*/ ;
static void SingChar (void) /*@modifies nextToken@*/ ;
static void WhiteChar (void) /*@modifies nextToken@*/ ;
static void TokenClass (void) /*@modifies nextToken@*/ ;
static void QuantifierSymToks (void) /*@modifies nextToken@*/ ;
static void LogicalOpToks (void) /*@modifies nextToken@*/ ;
static void EqOpToks (void) /*@modifies nextToken@*/ ;
static void EquationSymToks (void) /*@modifies nextToken@*/ ;
static void EqSepSymToks (void) /*@modifies nextToken@*/ ;
static void SelectSymToks (void) /*@modifies nextToken@*/ ;
static void OpenSymToks (void) /*@modifies nextToken@*/ ;
static void SepSymToks (void) /*@modifies nextToken@*/ ;
static void CloseSymToks (void) /*@modifies nextToken@*/ ;
static void SimpleIdToks (void) /*@modifies nextToken@*/ ;
static void MapSymToks (void) /*@modifies nextToken@*/ ;
static void MarkerSymToks (void) /*@modifies nextToken@*/ ;
static void CommentSymToks (void) /*@modifies nextToken@*/ ;
static void QuantifierSymTok (void) /*@modifies nextToken@*/ ;
static void LogicalOpTok (void) /*@modifies nextToken@*/ ;
static void EqOpTok (void) /*@modifies nextToken@*/ ;
static void EquationSymTok (void) /*@modifies nextToken@*/ ;
static void EqSepSymTok (void) /*@modifies nextToken@*/ ;
static void SelectSymTok (void) /*@modifies nextToken@*/ ;
static void OpenSymTok (void) /*@modifies nextToken@*/ ;
static void SepSymTok (void) /*@modifies nextToken@*/ ;
static void CloseSymTok (void) /*@modifies nextToken@*/ ;
static void SimpleIdTok (void) /*@modifies nextToken@*/ ;
static void MapSymTok (void) /*@modifies nextToken@*/ ;
static void MarkerSymTok (void) /*@modifies nextToken@*/ ;
static void CommentSymTok (void) /*@modifies nextToken@*/ ;
static void SynClass (void) /*@modifies nextToken@*/ ;
static void OldToken (void) /*@modifies nextToken@*/ ;
static void NewToken (void) /*@modifies nextToken@*/ ;
static void Token (void) /*@modifies nextToken@*/ ;
static void InitReduce (LSLInitRuleCode p_rule) /*@modifies nextToken@*/ ;
static void UpdateXCharKeywords (charCode) /*@modifies nextToken@*/ ;
static void ProcessExtensionChar (void) /*@modifies nextToken@*/ ;
static void ProcessEndCommentChar (void) /*@modifies nextToken@*/ ;
static void ProcessSingleChar (charCode p_code) /*@modifies nextToken@*/ ;
static void ProcessToken (ltokenCode p_code) /*@modifies nextToken@*/ ;
static void ProcessSynonym (void) /*@modifies nextToken@*/ ;
/* If TRUE character has been redefined as a singleChar. */
static bool defineSingleChar[LASTCHAR + 1];
static charCode currentExtensionChar;
/* LSL init file keyword tokens. */
static /*@dependent@*/ ltoken endCommentCharToken;
static /*@dependent@*/ ltoken idCharToken;
static /*@dependent@*/ ltoken opCharToken;
static /*@dependent@*/ ltoken extensionCharToken;
static /*@dependent@*/ ltoken singleCharToken;
static /*@dependent@*/ ltoken whiteCharToken;
static /*@dependent@*/ ltoken quantifierSymToken;
static /*@dependent@*/ ltoken logicalOpToken;
static /*@dependent@*/ ltoken eqOpToken;
static /*@dependent@*/ ltoken equationSymToken;
static /*@dependent@*/ ltoken eqSepSymToken;
static /*@dependent@*/ ltoken selectSymToken;
static /*@dependent@*/ ltoken openSymToken;
static /*@dependent@*/ ltoken sepSymToken;
static /*@dependent@*/ ltoken closeSymToken;
static /*@dependent@*/ ltoken simpleIdToken;
static /*@dependent@*/ ltoken mapSymToken;
static /*@dependent@*/ ltoken markerSymToken;
static /*@dependent@*/ ltoken commentSymToken;
static /*@dependent@*/ ltoken synonymToken;
static bool
hasFirstChar (ltoken tok)
{
return (ltoken_isChar (tok)
&& lscanCharClass (cstring_firstChar (ltoken_unparse (tok))) == SINGLECHAR);
}
void
lslinit_setInitFile (inputStream s)
{
llassert (inputStream_isUndefined (s_initFile));
s_initFile = s;
}
/*
**
** Parsing functions for init file processing, in the same order as the
** grammar file lslinit.cfg. This is top-down order, as much as possible.
**
*/
static void lslinit_processInitFile (void)
{
InitLines ();
InitReduce (INITFILE1);
if (ltoken_getCode (nextToken) != LEOFTOKEN)
{
LocalUserError (nextToken, "unexpected tokens after end-of-file");
}
}
static void
InitLines (void)
{
InitReduce (INITLINES1);
if (ltoken_getCode (nextToken) != LEOFTOKEN)
{
InitLine ();
InitReduce (INITLINES2);
}
while (ltoken_getCode (nextToken) != LEOFTOKEN)
{
InitLine ();
InitReduce (INITLINES3);
}
}
static void
InitLine (void)
{
if (ltoken_getCode (nextToken) == LST_EOL)
{
/* Nothing on line. */
InitReduce (INITLINE1);
}
else
{
Classification ();
InitReduce (INITLINE2);
}
if (ltoken_getCode (nextToken) != LST_EOL)
{
LocalUserError (nextToken, "Unexpected tokens on line");
}
ltoken_free (nextToken);
nextToken = LSLScanNextToken ();
}
static void
Classification (void)
{
if (ltoken_getRawText (nextToken) == ltoken_getText (endCommentCharToken)
|| ltoken_getRawText (nextToken) == ltoken_getText (idCharToken)
|| ltoken_getRawText (nextToken) == ltoken_getText (opCharToken)
|| ltoken_getRawText (nextToken) == ltoken_getText (extensionCharToken)
|| ltoken_getRawText (nextToken) == ltoken_getText (singleCharToken)
|| ltoken_getRawText (nextToken) == ltoken_getText (whiteCharToken))
{
CharClass ();
InitReduce (CLASSIFICATION1);
}
else if (ltoken_getRawText (nextToken) == ltoken_getText (quantifierSymToken)
|| ltoken_getRawText (nextToken) == ltoken_getText (logicalOpToken)
|| ltoken_getRawText (nextToken) == ltoken_getText (eqOpToken)
|| ltoken_getRawText (nextToken) == ltoken_getText (equationSymToken)
|| ltoken_getRawText (nextToken) == ltoken_getText (eqSepSymToken)
|| ltoken_getRawText (nextToken) == ltoken_getText (selectSymToken)
|| ltoken_getRawText (nextToken) == ltoken_getText (openSymToken)
|| ltoken_getRawText (nextToken) == ltoken_getText (sepSymToken)
|| ltoken_getRawText (nextToken) == ltoken_getText (closeSymToken)
|| ltoken_getRawText (nextToken) == ltoken_getText (simpleIdToken)
|| ltoken_getRawText (nextToken) == ltoken_getText (mapSymToken)
|| ltoken_getRawText (nextToken) == ltoken_getText (markerSymToken)
|| ltoken_getRawText (nextToken) == ltoken_getText (commentSymToken))
{
TokenClass ();
InitReduce (CLASSIFICATION2);
}
else if (ltoken_getRawText (nextToken) == ltoken_getText (synonymToken))
{
SynClass ();
InitReduce (CLASSIFICATION3);
}
else
{
LocalUserError (nextToken,
"expected character, token, or synonym classification");
}
}
static void
CharClass (void)
{
ltoken charClassToken;
charClassToken = nextToken;
nextToken = LSLScanNextToken (); /* Discard char class keyword. */
if (ltoken_getRawText (charClassToken) == ltoken_getText (endCommentCharToken))
{
EndCommentChars ();
InitReduce (CHARCLASS1);
}
else if (ltoken_getRawText (charClassToken) == ltoken_getText (idCharToken))
{
IdChars ();
InitReduce (CHARCLASS2);
}
else if (ltoken_getRawText (charClassToken) == ltoken_getText (opCharToken))
{
OpChars ();
InitReduce (CHARCLASS3);
}
else if (ltoken_getRawText (charClassToken)
== ltoken_getText (extensionCharToken))
{
ExtensionChar ();
InitReduce (CHARCLASS4);
}
else if (ltoken_getRawText (charClassToken) == ltoken_getText (singleCharToken))
{
SingChars ();
InitReduce (CHARCLASS5);
}
else if (ltoken_getRawText (charClassToken) == ltoken_getText (whiteCharToken))
{
WhiteChars ();
InitReduce (CHARCLASS6);
}
else
{
LocalUserError (nextToken, "expected character classification");
}
ltoken_free (charClassToken);
}
static void
EndCommentChars (void)
{
EndCommentChar ();
InitReduce (LRC_ENDCOMMENT1);
while (ltoken_getCode (nextToken) != LST_EOL)
{
EndCommentChar ();
InitReduce (LRC_ENDCOMMENT2);
}
}
static void
IdChars (void)
{
IdChar ();
InitReduce (IDCHARS1);
while (ltoken_getCode (nextToken) != LST_EOL)
{
IdChar ();
InitReduce (IDCHARS2);
}
}
static void
OpChars (void)
{
OpChar ();
InitReduce (OPCHARS1);
while (ltoken_getCode (nextToken) != LST_EOL)
{
OpChar ();
InitReduce (OPCHARS2);
}
}
static void
ExtensionChar (void)
{
if (ltoken_isChar (nextToken)
&& lscanCharClass (cstring_firstChar (ltoken_unparse (nextToken))) == SINGLECHAR)
{
LSLGenShiftOnly (nextToken);
nextToken = LSLScanNextToken ();
InitReduce (LRC_EXTENSIONCHAR1);
}
else
{
LocalUserError (nextToken, "expected only one character");
}
}
static void
SingChars (void)
{
SingChar ();
InitReduce (SINGCHARS1);
while (ltoken_getCode (nextToken) != LST_EOL)
{
SingChar ();
InitReduce (SINGCHARS2);
}
}
static void
WhiteChars (void)
{
WhiteChar ();
InitReduce (WHITECHARS1);
while (ltoken_getCode (nextToken) != LST_EOL)
{
WhiteChar ();
InitReduce (WHITECHARS2);
}
}
static void
EndCommentChar (void)
{
if (ltoken_isChar (nextToken))
{
LSLGenShiftOnly (nextToken);
nextToken = LSLScanNextToken ();
InitReduce (LRC_ENDCOMMENTCHAR1);
}
else
{
LocalUserError (nextToken, "expected only one character");
}
}
static void
IdChar (void)
{
if (hasFirstChar (nextToken))
{
LSLGenShiftOnly (nextToken);
nextToken = LSLScanNextToken ();
InitReduce (IDCHAR1);
}
else
{
LocalUserError (nextToken, "character is already defined, cannot redefine");
}
}
static void
OpChar (void)
{
if (hasFirstChar (nextToken))
{
LSLGenShiftOnly (nextToken);
nextToken = LSLScanNextToken ();
InitReduce (OPCHAR1);
}
else
{
LocalUserError (nextToken, "character is already defined, cannot redefine");
}
}
static void
SingChar (void)
{
if (hasFirstChar (nextToken))
{
LSLGenShiftOnly (nextToken);
nextToken = LSLScanNextToken ();
InitReduce (SINGCHAR1);
}
else
{
LocalUserError (nextToken, "character is already defined, cannot redefine");
}
}
static void
WhiteChar (void)
{
if (hasFirstChar (nextToken))
{
LSLGenShiftOnly (nextToken);
nextToken = LSLScanNextToken ();
InitReduce (WHITECHAR1);
}
else
{
LocalUserError (nextToken, "character is already defined, cannot redefine");
}
}
static void
TokenClass (void)
{
ltoken tokenClassToken;
tokenClassToken = nextToken;
nextToken = LSLScanNextToken ();
if (ltoken_getRawText (tokenClassToken) == ltoken_getText (quantifierSymToken))
{
QuantifierSymToks ();
InitReduce (TOKENCLASS1);
}
else if (ltoken_getRawText (tokenClassToken) == ltoken_getText (logicalOpToken))
{
LogicalOpToks ();
InitReduce (TOKENCLASS2);
}
else if (ltoken_getRawText (tokenClassToken) == ltoken_getText (eqOpToken))
{
EqOpToks ();
InitReduce (TOKENCLASS3);
}
else if (ltoken_getRawText (tokenClassToken)
== ltoken_getText (equationSymToken))
{
EquationSymToks ();
InitReduce (TOKENCLASS4);
}
else if (ltoken_getRawText (tokenClassToken) == ltoken_getText (eqSepSymToken))
{
EqSepSymToks ();
InitReduce (TOKENCLASS5);
}
else if (ltoken_getRawText (tokenClassToken) == ltoken_getText (selectSymToken))
{
SelectSymToks ();
InitReduce (TOKENCLASS6);
}
else if (ltoken_getRawText (tokenClassToken) == ltoken_getText (openSymToken))
{
OpenSymToks ();
InitReduce (TOKENCLASS7);
}
else if (ltoken_getRawText (tokenClassToken) == ltoken_getText (sepSymToken))
{
SepSymToks ();
InitReduce (TOKENCLASS8);
}
else if (ltoken_getRawText (tokenClassToken) == ltoken_getText (closeSymToken))
{
CloseSymToks ();
InitReduce (TOKENCLASS9);
}
else if (ltoken_getRawText (tokenClassToken) == ltoken_getText (simpleIdToken))
{
SimpleIdToks ();
InitReduce (TOKENCLASS10);
}
else if (ltoken_getRawText (tokenClassToken) == ltoken_getText (mapSymToken))
{
MapSymToks ();
InitReduce (TOKENCLASS11);
}
else if (ltoken_getRawText (tokenClassToken) == ltoken_getText (markerSymToken))
{
MarkerSymToks ();
InitReduce (TOKENCLASS12);
}
else if (ltoken_getRawText (tokenClassToken)
== ltoken_getText (commentSymToken))
{
CommentSymToks ();
InitReduce (TOKENCLASS13);
}
else
{
LocalUserError (nextToken, "expected token classification");
}
ltoken_free (tokenClassToken);
}
static void
QuantifierSymToks (void)
{
QuantifierSymTok ();
InitReduce (QUANTIFIERSYMTOKS1);
while (ltoken_getCode (nextToken) != LST_EOL)
{
QuantifierSymTok ();
InitReduce (QUANTIFIERSYMTOKS2);
}
}
static void
LogicalOpToks (void)
{
LogicalOpTok ();
InitReduce (LOGICALOPTOKS1);
while (ltoken_getCode (nextToken) != LST_EOL)
{
LogicalOpTok ();
InitReduce (LOGICALOPTOKS2);
}
}
static void
EqOpToks (void)
{
EqOpTok ();
InitReduce (LRC_EQOPTOKS1);
while (ltoken_getCode (nextToken) != LST_EOL)
{
EqOpTok ();
InitReduce (LRC_EQOPTOKS2);
}
}
static void
EquationSymToks (void)
{
EquationSymTok ();
InitReduce (LRC_EQUATIONSYMTOKS1);
while (ltoken_getCode (nextToken) != LST_EOL)
{
EquationSymTok ();
InitReduce (LRC_EQUATIONSYMTOKS2);
}
}
static void
EqSepSymToks (void)
{
EqSepSymTok ();
InitReduce (LRC_EQSEPSYMTOKS1);
while (ltoken_getCode (nextToken) != LST_EOL)
{
EqSepSymTok ();
InitReduce (LRC_EQSEPSYMTOKS2);
}
}
static void
SelectSymToks (void)
{
SelectSymTok ();
InitReduce (SELECTSYMTOKS1);
while (ltoken_getCode (nextToken) != LST_EOL)
{
SelectSymTok ();
InitReduce (SELECTSYMTOKS2);
}
}
static void
OpenSymToks (void)
{
OpenSymTok ();
InitReduce (OPENSYMTOKS1);
while (ltoken_getCode (nextToken) != LST_EOL)
{
OpenSymTok ();
InitReduce (OPENSYMTOKS2);
}
}
static void
SepSymToks (void)
{
SepSymTok ();
InitReduce (SEPSYMTOKS1);
while (ltoken_getCode (nextToken) != LST_EOL)
{
SepSymTok ();
InitReduce (SEPSYMTOKS2);
}
}
static void
CloseSymToks (void)
{
CloseSymTok ();
InitReduce (CLOSESYMTOKS1);
while (ltoken_getCode (nextToken) != LST_EOL)
{
CloseSymTok ();
InitReduce (CLOSESYMTOKS2);
}
}
static void
SimpleIdToks (void)
{
SimpleIdTok ();
InitReduce (SIMPLEIDTOKS1);
while (ltoken_getCode (nextToken) != LST_EOL)
{
SimpleIdTok ();
InitReduce (SIMPLEIDTOKS2);
}
}
static void
MapSymToks (void)
{
MapSymTok ();
InitReduce (MAPSYMTOKS1);
while (ltoken_getCode (nextToken) != LST_EOL)
{
MapSymTok ();
InitReduce (MAPSYMTOKS2);
}
}
static void
MarkerSymToks (void)
{
MarkerSymTok ();
InitReduce (MARKERSYMTOKS1);
while (ltoken_getCode (nextToken) != LST_EOL)
{
MarkerSymTok ();
InitReduce (MARKERSYMTOKS2);
}
}
static void
CommentSymToks (void)
{
CommentSymTok ();
InitReduce (COMMENTSYMTOKS1);
while (ltoken_getCode (nextToken) != LST_EOL)
{
CommentSymTok ();
InitReduce (COMMENTSYMTOKS2);
}
}
static void
QuantifierSymTok (void)
{
Token ();
InitReduce (QUANTIFIERSYMTOK1);
}
static void
LogicalOpTok (void)
{
Token ();
InitReduce (LOGICALOPTOK1);
}
static void
EqOpTok (void)
{
Token ();
InitReduce (LRC_EQOPTOK1);
}
static void
EquationSymTok (void)
{
/* ### EquationSymTok (); ### */
Token ();
InitReduce (LRC_EQUATIONSYMTOK1);
}
static void
EqSepSymTok (void)
{
Token ();
InitReduce (LRC_EQSEPSYMTOK1);
}
static void
SelectSymTok (void)
{
Token ();
InitReduce (SELECTSYMTOK1);
}
static void
OpenSymTok (void)
{
Token ();
InitReduce (OPENSYMTOK1);
}
static void
SepSymTok (void)
{
Token ();
InitReduce (SEPSYMTOK1);
}
static void
CloseSymTok (void)
{
Token ();
InitReduce (CLOSESYMTOK1);
}
static void
SimpleIdTok (void)
{
Token ();
InitReduce (SIMPLEIDTOK1);
}
static void
MapSymTok (void)
{
Token ();
InitReduce (MAPSYMTOK1);
}
static void
MarkerSymTok (void)
{
Token ();
InitReduce (MARKERSYMTOK1);
}
static void
CommentSymTok (void)
{
Token ();
InitReduce (COMMENTSYMTOK1);
}
static void
SynClass (void)
{
if (ltoken_getRawText (nextToken) == ltoken_getText (synonymToken))
{
ltoken_free (nextToken);
nextToken = LSLScanNextToken ();
OldToken ();
NewToken ();
InitReduce (SYNCLASS1);
}
else
{
LocalUserError (nextToken, "expected synonym classification");
}
}
static void
OldToken (void)
{
Token ();
InitReduce (OLDTOKEN1);
}
static void
NewToken (void)
{
Token ();
InitReduce (NEWTOKEN1);
}
static void
Token (void)
{
if (ltoken_getCode (nextToken) == LST_EOL
|| ltoken_getCode (nextToken) == LEOFTOKEN)
{
LocalUserError (nextToken, "unexpected end-of-line or end-of-file");
}
else
{
LSLGenShiftOnly (nextToken);
nextToken = LSLScanNextToken ();
}
}
/*
** Init File Processing Routines, these routines use the shift-reduce sequence
** produced by the init file parser and update the necessary tables for the
** scanner.
**
** The same shift stack is used that LSL parser uses. A different reduce
** procedure is used because the init file grammar is different from the LSL
** grammar.
**
*/
static void
InitReduce (LSLInitRuleCode rule)
{
switch (rule)
{
case INITFILE1:
LTRACE ("INITFILE1");
break;
case INITLINES1:
LTRACE ("INITLINES1");
break;
case INITLINES2:
LTRACE ("INITLINES2");
break;
case INITLINES3:
LTRACE ("INITLINES3");
break;
case INITLINE1:
LTRACE ("INITLINE1");
break;
case INITLINE2:
LTRACE ("INITLINE2");
break;
case CLASSIFICATION1:
LTRACE ("CLASSIFICATION1");
break;
case CLASSIFICATION2:
LTRACE ("CLASSIFICATION2");
break;
case CLASSIFICATION3:
LTRACE ("CLASSIFICATION3");
break;
case CHARCLASS1:
LTRACE ("CHARCLASS1");
break;
case CHARCLASS2:
LTRACE ("CHARCLASS2");
break;
case CHARCLASS3:
LTRACE ("CHARCLASS3");
break;
case CHARCLASS4:
LTRACE ("CHARCLASS4");
break;
case CHARCLASS5:
LTRACE ("CHARCLASS5");
break;
case CHARCLASS6:
LTRACE ("CHARCLASS6");
break;
case LRC_ENDCOMMENT1:
LTRACE ("LRC_ENDCOMMENT1");
break;
case LRC_ENDCOMMENT2:
LTRACE ("LRC_ENDCOMMENT2");
break;
case IDCHARS1:
LTRACE ("IDCHARS1");
break;
case IDCHARS2:
LTRACE ("IDCHARS2");
break;
case OPCHARS1:
LTRACE ("OPCHARS1");
break;
case OPCHARS2:
LTRACE ("OPCHARS2");
break;
case LRC_EXTENSIONCHAR1:
LTRACE ("LRC_EXTENSIONCHAR1");
ProcessExtensionChar ();
break;
case SINGCHARS1:
LTRACE ("SINGCHARS1");
break;
case SINGCHARS2:
LTRACE ("SINGCHARS2");
break;
case WHITECHARS1:
LTRACE ("WHITECHARS1");
break;
case WHITECHARS2:
LTRACE ("WHITECHARS2");
break;
case LRC_ENDCOMMENTCHAR1:
LTRACE ("LRC_ENDCOMMENTCHAR1");
ProcessEndCommentChar ();
break;
case IDCHAR1:
LTRACE ("IDCHAR1");
ProcessSingleChar (IDCHAR);
break;
case OPCHAR1:
LTRACE ("OPCHAR1");
ProcessSingleChar (OPCHAR);
break;
case SINGCHAR1:
LTRACE ("SINGCHAR1");
ProcessSingleChar (SINGLECHAR);
break;
case WHITECHAR1:
LTRACE ("CHAR1");
ProcessSingleChar (WHITECHAR);
break;
case TOKENCLASS1:
LTRACE ("TOKENCLASS1");
break;
case TOKENCLASS2:
LTRACE ("TOKENCLASS2");
break;
case TOKENCLASS3:
LTRACE ("TOKENCLASS3");
break;
case TOKENCLASS4:
LTRACE ("TOKENCLASS4");
break;
case TOKENCLASS5:
LTRACE ("TOKENCLASS5");
break;
case TOKENCLASS6:
LTRACE ("TOKENCLASS6");
break;
case TOKENCLASS7:
LTRACE ("TOKENCLASS7");
break;
case TOKENCLASS8:
LTRACE ("TOKENCLASS8");
break;
case TOKENCLASS9:
LTRACE ("TOKENCLASS9");
break;
case TOKENCLASS10:
LTRACE ("TOKENCLASS10");
break;
case TOKENCLASS11:
LTRACE ("TOKENCLASS11");
break;
case TOKENCLASS12:
LTRACE ("TOKENCLASS12");
break;
case TOKENCLASS13:
LTRACE ("TOKENCLASS13");
break;
case QUANTIFIERSYMTOKS1:
LTRACE ("QUALIFERSYMTOKS1");
break;
case QUANTIFIERSYMTOKS2:
LTRACE ("QUANTIFIERSYMTOKS2");
break;
case LOGICALOPTOKS1:
LTRACE ("LOGICALOPTOKS1");
break;
case LOGICALOPTOKS2:
LTRACE ("LOGICALOPTOKS2");
break;
case LRC_EQOPTOKS1:
LTRACE ("LRC_EQOPTOKS1");
break;
case LRC_EQOPTOKS2:
LTRACE ("LRC_EQOPTOKS2");
break;
case LRC_EQUATIONSYMTOKS1:
LTRACE ("LRC_EQUATIONSYMTOKS1");
break;
case LRC_EQUATIONSYMTOKS2:
LTRACE ("LRC_EQUATIONSYMTOKS2");
break;
case LRC_EQSEPSYMTOKS1:
LTRACE ("LRC_EQSEPSYMTOKS1");
break;
case LRC_EQSEPSYMTOKS2:
LTRACE ("LRC_EQSEPSYMTOKS2");
break;
case SELECTSYMTOKS1:
LTRACE ("SELECTSYMTOKS1");
break;
case SELECTSYMTOKS2:
LTRACE ("SELECTSYMTOKS2");
break;
case OPENSYMTOKS1:
LTRACE ("OPENSYMTOKS1");
break;
case OPENSYMTOKS2:
LTRACE ("OPENSYMTOKS2");
break;
case SEPSYMTOKS1:
LTRACE ("SEPSYMTOKS1");
break;
case SEPSYMTOKS2:
LTRACE ("SEPSYMTOKS2");
break;
case CLOSESYMTOKS1:
LTRACE ("CLOSESYMTOKS1");
break;
case CLOSESYMTOKS2:
LTRACE ("CLOSESYMTOKS2");
break;
case SIMPLEIDTOKS1:
LTRACE ("SIMPLEIDTOKS1");
break;
case SIMPLEIDTOKS2:
LTRACE ("SIMPLEIDTOKS2");
break;
case MAPSYMTOKS1:
LTRACE ("MAPSYMTOKS1");
break;
case MAPSYMTOKS2:
LTRACE ("MAPSYMTOKS2");
break;
case MARKERSYMTOKS1:
LTRACE ("MARKERSYMTOKS1");
break;
case MARKERSYMTOKS2:
LTRACE ("MARKERSYMTOKS2");
break;
case COMMENTSYMTOKS1:
LTRACE ("COMMENTSYMTOKS1");
break;
case COMMENTSYMTOKS2:
LTRACE ("COMMENTSYMTOKS2");
break;
case QUANTIFIERSYMTOK1:
LTRACE ("QUANTIFERSYMTOK1");
ProcessToken (LST_QUANTIFIERSYM);
break;
case LOGICALOPTOK1:
LTRACE ("LOGICALOPTOK1");
ProcessToken (LST_LOGICALOP);
break;
case LRC_EQOPTOK1:
LTRACE ("LRC_EQOPTOK1");
ProcessToken (LST_EQOP);
break;
case LRC_EQUATIONSYMTOK1:
LTRACE ("LRC_EQUATIONSYMTOK1");
ProcessToken (LST_EQUATIONSYM);
break;
case LRC_EQSEPSYMTOK1:
LTRACE ("LRC_EQSEPSYMTOK1");
ProcessToken (LST_EQSEPSYM);
break;
case SELECTSYMTOK1:
LTRACE ("SELECTSYMTOK1");
ProcessToken (LST_SELECTSYM);
break;
case OPENSYMTOK1:
LTRACE ("OPENSYMTOK1");
ProcessToken (LST_OPENSYM);
break;
case SEPSYMTOK1:
LTRACE ("SEPSYMTOK1");
ProcessToken (LST_SEPSYM);
break;
case CLOSESYMTOK1:
LTRACE ("CLOSESYMTOK1");
ProcessToken (LST_CLOSESYM);
break;
case SIMPLEIDTOK1:
LTRACE ("SIMPLEIDTOK1");
ProcessToken (LST_SIMPLEID);
break;
case MAPSYMTOK1:
LTRACE ("MAPSYMTOK1");
ProcessToken (LST_MAPSYM);
break;
case MARKERSYMTOK1:
LTRACE ("MARKERSYMTOK1");
ProcessToken (LST_MARKERSYM);
break;
case COMMENTSYMTOK1:
LTRACE ("COMMENTSYMTOK1");
ProcessToken (LST_COMMENTSYM);
break;
case SYNCLASS1:
LTRACE ("SYNCLASS1");
ProcessSynonym ();
break;
case OLDTOKEN1:
LTRACE ("OLDTOKEN1");
break;
case NEWTOKEN1:
LTRACE ("NEWTOKEN1");
break;
default:
llcontbuglit ("InitReduce: bad switch");
break;
} /* end switch */
} /* end InitReduce () */
/* Reset the first character of the predefined extensionChar keywords when */
/* the extensionChar changes. e.g. "extensionChar @" changes "forall" to */
/* "@forall". */
static void
UpdateXCharKeywords (charCode xCharCode)
{
char xChar = (char) xCharCode;
char *str;
str = ltoken_getTextChars (ltoken_forall);
*str = xChar;
str = ltoken_getTextChars (ltoken_and);
*str = xChar;
str = ltoken_getTextChars (ltoken_or);
*str = xChar;
str = ltoken_getTextChars (ltoken_implies);
*str = xChar;
str = ltoken_getTextChars (ltoken_eq);
*str = xChar;
str = ltoken_getTextChars (ltoken_neq);
*str = xChar;
str = ltoken_getTextChars (ltoken_equals);
*str = xChar;
str = ltoken_getTextChars (ltoken_eqsep);
*str = xChar;
str = ltoken_getTextChars (ltoken_select);
*str = xChar;
str = ltoken_getTextChars (ltoken_open);
*str = xChar;
str = ltoken_getTextChars (ltoken_sep);
*str = xChar;
str = ltoken_getTextChars (ltoken_close);
*str = xChar;
str = ltoken_getTextChars (ltoken_id);
*str = xChar;
str = ltoken_getTextChars (ltoken_arrow);
*str = xChar;
str = ltoken_getTextChars (ltoken_marker);
*str = xChar;
str = ltoken_getTextChars (ltoken_comment);
*str = xChar;
}
/* Different from ProcessCharClass because only allow one extension */
/* character. Therefore, the present extension character must be set to a */
/* singleChar. */
static void
ProcessExtensionChar (void)
{
ltoken stackToken = LSLGenTopPopShiftStack ();
char firstChar = cstring_firstChar (ltoken_unparse (stackToken));
if (!defineSingleChar[(int)firstChar]
&& lscanCharClass (firstChar) == SINGLECHAR)
{
/* Is a single character that has not been defined before. */
/* Can only have one extension char. Release old one. */
lsetCharClass (firstChar, CHC_EXTENSION);
/* this is a (bogus) type bug! caught by splint */
/* lsetCharClass (currentExtensionChar, SINGLECHAR); */
lsetCharClass ((char) currentExtensionChar, SINGLECHAR);
currentExtensionChar = (charCode) firstChar;
UpdateXCharKeywords (currentExtensionChar);
}
else
{
/* Already redefined. Don't allow to be redefined. */
LocalUserError (stackToken, "character is already defined, cannot redefine");
}
ltoken_free (stackToken);
}
/* Different from ProcessSingleChar because allow any characters to be */
/* endCommentChar and also set a different part of the scanner structure. */
static void
ProcessEndCommentChar (void)
{
ltoken stackToken = LSLGenTopPopShiftStack ();
char firstChar = cstring_firstChar (ltoken_unparse (stackToken));
if (LSLIsEndComment (firstChar))
{
LocalUserError (stackToken,
"already defined as a endCommentChar, cannot redefine");
}
else
{
lsetEndCommentChar (firstChar, TRUE);
}
ltoken_free (stackToken);
}
static void
ProcessSingleChar (charCode code)
{
ltoken stackToken = LSLGenTopPopShiftStack ();
char firstChar = cstring_firstChar (ltoken_unparse (stackToken));
if (!defineSingleChar[(int)firstChar]
&& lscanCharClass (firstChar) == SINGLECHAR)
{
/* Is a single character that has not been defined before. */
/* It's OK to redefine once. */
lsetCharClass (firstChar, code);
/* OK to mark as a defined singleChar even if not. Only check */
/* defineSingleChar[] if defining a singleChar. */
defineSingleChar[(int)firstChar] = TRUE;
}
else
{
LocalUserError (stackToken, "character is already defined, cannot redefine");
}
ltoken_free (stackToken);
}
static void
ProcessToken (ltokenCode code)
{
ltoken stackToken, temp;
lsymbol sym;
stackToken = LSLGenTopPopShiftStack ();
sym = ltoken_getText (stackToken);
if (LSLIsSyn (sym))
{
LocalUserError (stackToken,
"already defined as a synonym, cannot redefine");
}
/* Get the token from the token table, so can check if the token */
/* was updated by a previous token. */
temp = LSLGetToken (sym);
if (ltoken_isStateDefined (temp))
{
if ((code == LST_OPENSYM && sym == lsymbol_fromChars ("[")) ||
(code == LST_CLOSESYM && sym == lsymbol_fromChars ("]")))
{
/* ignore "openSym [" and "closeSym ]" TokenClass */
ltoken_free (stackToken);
return;
}
else
{
LocalUserError (stackToken, "already defined, cannot redefine");
PrintToken (temp);
}
}
LSLUpdateToken (code, ltoken_getText (stackToken), TRUE);
ltoken_free (stackToken);
}
static void
ProcessSynonym (void)
{
ltoken newtok;
ltoken oldtok;
newtok = LSLGenTopPopShiftStack ();
oldtok = LSLGenTopPopShiftStack ();
if (ltoken_wasSyn (newtok))
{
/* The token has a synonym. This means that the synonym was in the */
/* init file, so complain about redefining as a synonym again */
LocalUserError (newtok, "newtok already is a synonym, cannot redefine");
}
if (ltoken_hasSyn (newtok))
{
/*
** newtok already has a synonym defined for it. Do not allow
** synonyms to be chained.
*/
LocalUserError (newtok,
"newtok already has a synonym, cannot chain synonyms");
}
if (ltoken_isStateDefined (newtok))
{
LocalUserError (newtok, "newtok already defined, cannot redefine");
}
LSLAddSyn (ltoken_getText (newtok), ltoken_getText (oldtok));
ltoken_free (oldtok);
ltoken_free (newtok);
}
/*
* Utilities, in alphabetical order
*/
static void
LocalUserError (ltoken t, /*@temp@*/ char *msg)
{
lldiagmsg (message ("%s %s in the LSL init file:",
ltoken_unparse (t), cstring_fromChars (msg)));
ltoken_free (nextToken);
nextToken = LSLScanNextToken ();
while (ltoken_getCode (nextToken) != LST_EOL)
{
ltoken_free (nextToken);
nextToken = LSLScanNextToken ();
}
}
/*
** Required initialization and cleanup routines
*/
static /*@exposed@*/ ltoken insertSimpleToken (char *text)
/*@modifies internalState@*/
{
return (LSLInsertToken (LST_SIMPLEID, lsymbol_fromChars (text), 0, FALSE));
}
static void
lslinit_initProcessInitFile (void)
{
int i;
LSLGenInit (TRUE); /* parsing LSLinit not LCLinit */
/*
** Insert the init file keywords into the token table as undefined
** SIMPLEIDs. They are defined as simpleIds since they must be treated
** that way if they do not appear as the first token on a line, and
** they must be treated that way for the actual LSL parsing. Save the
** tokens so can recognize as init file keywords when necessary.
*/
endCommentCharToken = insertSimpleToken ("endCommentChar");
idCharToken = insertSimpleToken ("idChar");
opCharToken = insertSimpleToken ("opChar");
extensionCharToken = insertSimpleToken ("extensionChar");
singleCharToken = insertSimpleToken ("singleChar");
whiteCharToken = insertSimpleToken ("whiteChar");
quantifierSymToken = insertSimpleToken ("quantifierSym");
logicalOpToken = insertSimpleToken ("logicalOp");
eqOpToken = insertSimpleToken ("eqOp");
equationSymToken = insertSimpleToken ("equationSym");
eqSepSymToken = insertSimpleToken ("eqSepSym");
selectSymToken = insertSimpleToken ("selectSym");
openSymToken = insertSimpleToken ("openSym");
sepSymToken = insertSimpleToken ("sepSym");
closeSymToken = insertSimpleToken ("closeSym");
simpleIdToken = insertSimpleToken ("simpleId");
mapSymToken = insertSimpleToken ("mapSym");
markerSymToken = insertSimpleToken ("markerSym");
commentSymToken = insertSimpleToken ("commentSym");
synonymToken = insertSimpleToken ("synonym");
for (i = 0; i <= LASTCHAR; i++)
{
defineSingleChar[i] = FALSE;
}
/*
** Record the current extension character so can redefine back to
** singleChar if a new extension character is redefined.
*/
currentExtensionChar = (charCode) CHAREXTENDER;
LSLReportEolTokens (TRUE);
ltoken_free (nextToken);
nextToken = LSLScanNextToken ();
}
void lslinit_process (void)
/*@globals undef g_symtab; @*/
/*@modifies g_symtab, internalState, fileSystem; @*/
{
/*
** Open init file provided by user, or use the default LCL init file
*/
cstring larchpath = context_getLarchPath ();
inputStream initstream = inputStream_undefined;
setCodePoint ();
if (inputStream_isUndefined (s_initFile))
{
s_initFile = inputStream_create (cstring_makeLiteral (INITFILENAME),
cstring_makeLiteralTemp (LCLINIT_SUFFIX),
FALSE);
if (!inputStream_getPath (larchpath, s_initFile))
{
lldiagmsg (message ("Continuing without LCL init file: %s",
inputStream_fileName (s_initFile)));
}
else
{
if (!inputStream_open (s_initFile))
{
lldiagmsg (message ("Continuing without LCL init file: %s",
inputStream_fileName (s_initFile)));
}
}
}
else
{
if (!inputStream_open (s_initFile))
{
lldiagmsg (message ("Continuing without LCL init file: %s",
inputStream_fileName (s_initFile)));
}
}
/* Initialize checker */
lsymbol_initMod ();
LCLSynTableInit ();
setCodePoint ();
LCLSynTableReset ();
LCLTokenTableInit ();
setCodePoint ();
LCLScanLineInit ();
setCodePoint ();
LCLScanLineReset ();
setCodePoint ();
LCLScanInit ();
setCodePoint ();
/* need this to initialize LCL checker */
llassert (inputStream_isDefined (s_initFile));
if (inputStream_isOpen (s_initFile))
{
setCodePoint ();
LCLScanReset (s_initFile);
lclinit_initMod ();
lclinit_reset ();
setCodePoint ();
lclinit_process ();
lclinit_cleanup ();
setCodePoint ();
check (inputStream_close (s_initFile));
}
/* Initialize LSL init files, for parsing LSL signatures from LSL */
initstream = inputStream_create (cstring_makeLiteral ("lslinit.lsi"),
cstring_makeLiteralTemp (".lsi"),
FALSE);
if (!inputStream_getPath (larchpath, initstream))
{
lldiagmsg (message ("Continuing without LSL init file: %s",
inputStream_fileName (initstream)));
}
else
{
if (!inputStream_open (initstream))
{
lldiagmsg (message ("Continuing without LSL init file: %s",
inputStream_fileName (initstream)));
}
}
setCodePoint ();
lsynTableInit ();
lsynTableReset ();
setCodePoint ();
ltokenTableInit ();
setCodePoint ();
lscanLineInit ();
lscanLineReset ();
LSLScanInit ();
if (inputStream_isOpen (initstream))
{
setCodePoint ();
LSLScanReset (initstream);
lslinit_initProcessInitFile ();
lslinit_processInitFile ();
check (inputStream_close (initstream));
}
inputStream_free (initstream);
if (lclHadError ())
{
lclplainerror
(cstring_makeLiteral ("LSL init file error. Attempting to continue."));
}
setCodePoint ();
g_symtab = symtable_new ();
/*
** sort_init must come after symtab has been initialized
*/
sort_init ();
abstract_init ();
setCodePoint ();
/*
** Equivalent to importing old spec_csupport.lcl
** define immutable LCL type "bool" and bool constants TRUE and FALSE
** and initialized them to be equal to LSL's "true" and "false".
**
** Reads in CTrait.syms (derived from CTrait.lsl) on LARCH_PATH.
*/
LCLBuiltins ();
LCLReportEolTokens (FALSE);
}
syntax highlighted by Code2HTML, v. 0.9.1