/*;-*-C-*-;
-** Copyright (c) Massachusetts Institute of Technology 1994-1998.
-** All Rights Reserved.
-** Unpublished rights reserved under the copyright laws of
-** the United States.
+** Splint - annotation-assisted static program checker
+** Copyright (C) 1994-2003 University of Virginia,
+** Massachusetts Institute of Technology
**
-** THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED
-** OR IMPLIED. ANY USE IS AT YOUR OWN RISK.
+** 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.
**
-** This code is distributed freely and may be used freely under the
-** following conditions:
-**
-** 1. This notice may not be removed or altered.
-**
-** 2. Works derived from this code are not distributed for
-** commercial gain without explicit permission from MIT
-** (for permission contact lclint-request@sds.lcs.mit.edu).
+** For information on splint: splint@cs.virginia.edu
+** To report a bug: splint-bug@cs.virginia.edu
+** For more information: http://www.splint.org
*/
/*
** mtgrammar.y
%{
# include "bison.reset"
-# include "lclintMacros.nf"
-# include "llbasic.h"
-# include "mtincludes.h"
+# include "splintMacros.nf"
+# include "basic.h"
+
+# ifndef S_SPLINT_S
+extern ctype mtscanner_lookupType (mttok p_tok) /*@modifies p_tok@*/ ;
+# endif
+
+ /*@i523@*/ /* can't include these here
+ # include "mtgrammar.h"
+ # include "mtscanner.h"
+ */
-static /*@exits@*/ void mterror (char *);
+static /*@noreturn@*/ void mterror (char *);
/*@-noparams@*/ /* Can't list params since YYSTYPE isn't defined yet. */
+extern int mtlex () ;
static void yyprint (/*FILE *p_file, int p_type, YYSTYPE p_value */);
/*@=noparams@*/
mtTransferAction mttransferaction;
mtLoseReferenceList mtlosereferencelist;
mtLoseReference mtlosereference;
-
+ pointers pointers;
/*@only@*/ cstringList cstringlist;
ctype ctyp;
/*@only@*/ qtype qtyp;
- int count;
+ qual qual;
+ qualList quals;
}
/* Don't forget to enter all tokens in mtscanner.c */
%token <tok> MT_ONEOF
%token <tok> MT_DEFAULTS MT_DEFAULT
-%token <tok> MT_REFERENCE MT_PARAMETER MT_CLAUSE
+%token <tok> MT_REFERENCE MT_PARAMETER MT_RESULT MT_CLAUSE MT_LITERAL MT_NULL
%token <tok> MT_ANNOTATIONS
%token <tok> MT_ARROW
%token <tok> MT_CHAR MT_INT MT_FLOAT MT_DOUBLE MT_VOID MT_ANYTYPE MT_INTEGRALTYPE MT_UNSIGNEDINTEGRALTYPE
%token <tok> MT_SIGNEDINTEGRALTYPE
-%token <tok> MT_CONST MT_VOLATILE
+%token <tok> MT_CONST MT_VOLATILE MT_RESTRICT
%token <tok> MT_STRINGLIT
%token <tok> MT_IDENT
-%type <count> pointers
+%type <pointers> pointers
%type <ctyp> optType typeSpecifier typeName abstractDecl abstractDeclBase
%type <qtyp> typeExpression
%type <qtyp> completeType completeTypeAux optCompleteType
%type <mtdecl> declarationNode
%type <mtpieces> declarationPieces
%type <tok> valueChoice
-
+%type <quals> innerModsList
+%type <qual> innerMods
%start file
file
: {}
| mtsDeclaration {}
+;
mtsDeclaration
: MT_STATE declarationNode MT_END
{ mtreader_processDeclaration ($2); }
| MT_GLOBAL MT_STATE declarationNode MT_END
{ mtreader_processGlobalDeclaration ($3); }
+;
declarationNode
: MT_IDENT declarationPieces
{ $$ = mtDeclarationNode_create ($1, $2); }
+;
declarationPieces
: { $$ = mtDeclarationPieces_create (); }
| declarationPiece declarationPieces
{ $$ = mtDeclarationPieces_append ($2, $1); }
+;
declarationPiece
: contextDeclaration { $$ = mtDeclarationPiece_createContext ($1); }
| preconditionsDeclaration { $$ = mtDeclarationPiece_createPreconditions ($1); }
| postconditionsDeclaration { $$ = mtDeclarationPiece_createPostconditions ($1); }
| loseReferenceDeclaration { $$ = mtDeclarationPiece_createLosers ($1); }
+;
contextDeclaration
: MT_CONTEXT contextSelection { $$ = $2; }
/* ??? should it be a list? */
+;
optContextSelection
: /* empty */ { $$ = mtContextNode_createAny (); }
| contextSelection
+;
contextSelection
: MT_PARAMETER optType { $$ = mtContextNode_createParameter ($2); }
| MT_REFERENCE optType { $$ = mtContextNode_createReference ($2); }
+| MT_RESULT optType { $$ = mtContextNode_createResult ($2); }
| MT_CLAUSE optType { $$ = mtContextNode_createClause ($2); }
+| MT_LITERAL optType { $$ = mtContextNode_createLiteral ($2); }
+| MT_NULL optType { $$ = mtContextNode_createNull ($2); }
+;
/*
** Wish I could share the C grammar here...cut-and-paste instead.
optType
: /* empty */ { $$ = ctype_unknown; }
| typeExpression { DPRINTF (("Type: %s", qtype_unparse ($1))); $$ = qtype_getType ($1); }
+;
typeExpression
: completeType
| completeType abstractDecl { $$ = qtype_newBase ($1, $2); }
+;
completeType
: completeTypeAux { $$ = $1; }
| completeType MT_BAR typeExpression
{ $$ = qtype_mergeAlt ($1, $3); }
+;
completeTypeAux
: typeSpecifier optCompleteType { $$ = qtype_combine ($2, $1); }
+;
optCompleteType
: /* empty */ { $$ = qtype_unknown (); }
| completeType { $$ = $1; }
-
+;
abstractDecl
: pointers { $$ = ctype_adjustPointers ($1, ctype_unknown); }
| abstractDeclBase
| pointers abstractDeclBase { $$ = ctype_adjustPointers ($1, $2); }
+;
pointers
- : MT_STAR { $$ = 1; }
- | MT_STAR innerModsList { $$ = 1; }
- | MT_STAR pointers { $$ = 1 + $2; }
- | MT_STAR innerModsList pointers { $$ = 1 + $3; }
+ : MT_STAR { $$ = pointers_createMt ($1); }
+ | MT_STAR innerModsList { $$ = pointers_createModsMt ($1, $2); }
+ | MT_STAR pointers { $$ = pointers_extend (pointers_createMt ($1), $2); }
+ | MT_STAR innerModsList pointers { $$ = pointers_extend (pointers_createModsMt ($1, $2), $3); }
+;
innerMods
- : MT_CONST { /* ignored for now */; }
- | MT_VOLATILE { ; }
+ : MT_CONST { $$ = qual_createConst (); }
+ | MT_VOLATILE { $$ = qual_createVolatile (); }
+ | MT_RESTRICT { $$ = qual_createRestrict (); }
+;
innerModsList
- : innerMods { ; }
- | innerModsList innerMods { ; }
+ : innerMods { $$ = qualList_single ($1); }
+ | innerModsList innerMods { $$ = qualList_add ($1, $2); }
+;
abstractDeclBase
: MT_LPAREN abstractDecl MT_RPAREN { $$ = ctype_expectFunction ($2); }
| abstractDeclBase MT_LBRACKET constantExpr MT_RBRACKET
{ $$ = ctype_makeFixedArray ($1, exprNode_getLongValue ($3)); }
*/
+;
typeSpecifier
: MT_CHAR { $$ = ctype_char; }
/* | suSpc
| enumSpc
| typeModifier NotType { $$ = ctype_fromQual ($1); } */
+;
typeName
: MT_IDENT { $$ = mtscanner_lookupType ($1); }
+;
valuesDeclaration
: MT_ONEOF valuesList { $$ = mtValuesNode_create ($2); }
+;
valuesList
: MT_IDENT { $$ = cstringList_single (mttok_getText ($1)); }
| MT_IDENT MT_COMMA valuesList
{ $$ = cstringList_prepend ($3, mttok_getText ($1)); }
+;
defaultNode
: MT_DEFAULT valueChoice { $$ = $2; }
+;
defaultsDeclaration
: MT_DEFAULTS defaultDeclarationList { $$ = mtDefaultsNode_create ($1, $2); }
+;
defaultDeclarationList
: contextSelection MT_ARROW valueChoice
{ $$ = mtDefaultsDeclList_single (mtDefaultsDecl_create ($1, $3)); }
| contextSelection MT_ARROW valueChoice defaultDeclarationList
{ $$ = mtDefaultsDeclList_prepend ($4, mtDefaultsDecl_create ($1, $3)); }
+;
annotationsDeclaration
: MT_ANNOTATIONS annotationsDeclarationList { $$ = mtAnnotationsNode_create ($2); }
+;
annotationsDeclarationList
: annotationDeclaration { $$ = mtAnnotationList_single ($1); }
| annotationDeclaration annotationsDeclarationList
{ $$ = mtAnnotationList_prepend ($2, $1); }
+;
annotationDeclaration
: MT_IDENT optContextSelection MT_ARROW valueChoice
{ $$ = mtAnnotationDecl_create ($1, $2, $4); }
+;
mergeDeclaration
: MT_MERGE mergeClauses { $$ = mtMergeNode_create ($2); }
+;
mergeClauses
: mergeClause { $$ = mtMergeClauseList_single ($1); }
| mergeClause mergeClauses { $$ = mtMergeClauseList_prepend ($2, $1); }
+;
mergeClause
: mergeItem MT_PLUS mergeItem MT_ARROW transferAction
{ $$ = mtMergeClause_create ($1, $3, $5); }
+;
mergeItem
: valueChoice { $$ = mtMergeItem_createValue ($1); }
| MT_STAR { $$ = mtMergeItem_createStar ($1); }
+;
preconditionsDeclaration
: MT_PRECONDITIONS transferClauses { $$ = $2; }
+;
postconditionsDeclaration
: MT_POSTCONDITIONS transferClauses { $$ = $2; }
+;
transfersDeclaration
: MT_TRANSFERS transferClauses { $$ = $2; }
+;
loseReferenceDeclaration
: MT_LOSEREFERENCE lostClauses { $$ = $2; }
+;
lostClauses
: lostClause { $$ = mtLoseReferenceList_single ($1); }
| lostClause lostClauses { $$ = mtLoseReferenceList_prepend ($2, $1); }
+;
lostClause
: valueChoice MT_ARROW errorAction { $$ = mtLoseReference_create ($1, $3); }
+;
transferClauses
: transferClause { $$ = mtTransferClauseList_single ($1); }
| transferClause transferClauses { $$ = mtTransferClauseList_prepend ($2, $1); }
+;
transferClause
: valueChoice MT_AS valueChoice MT_ARROW transferAction
{ $$ = mtTransferClause_create ($1, $3, $5); }
+;
transferAction
: valueChoice { $$ = mtTransferAction_createValue ($1); }
| errorAction { $$ = $1; }
+;
errorAction
: MT_ERROR { $$ = mtTransferAction_createError ($1); }
| MT_ERROR MT_STRINGLIT { $$ = mtTransferAction_createErrorMessage ($2); }
+;
valueChoice
- : MT_IDENT { $$ = $1; }
+ : MT_IDENT
+;
%%
static void mterror (char *s)
{
- llfatalbug
- (cstring_makeLiteral
- ("There has been a problem in the .mts parser."));
+
+ if (s != NULL)
+ {
+ llparseerror
+ (message ("Parse error in meta-state file: %s", cstring_fromChars (s)));
+ }
+ else
+ {
+ llparseerror
+ (message ("Parse error in meta-state file"));
+ }
+
}
static void yyprint (FILE *file, int type, YYSTYPE value)