H.2  Specification Language

// ----------------------------------------------------------------------  
// specifications  
// ----------------------------------------------------------------------  
 
// a unit specification  
unitspec:  
  imports ’theory’ ( ’uses’ names )? ’{’ declarations ’}’ EOF ;  
 
// a class specification  
classspec: ( ’invariant’ formula ’;’ )? EOF ;  
 
// a method specification  
methodspec:  
  ( ’helper’ ’;’ )?  
  ( ’requires’ formula ’;’ )?  
  ( ’assignable’ names ’;’ )?  
  ( ’signals’ names ’;’ )?  
  ( ’ensures’ formula ’;’ )?  
  ( ’diverges’ formula ’;’ )?  
  ( ’decreases’ term ( ’,’ term )* ’;’ )?  
  EOF ;  
 
// a loop annotation  
loopspec:  
  ( ’invariant’ formula ’;’ )?  
  ( ’decreases’ term ( ’,’ term )* ’;’ )?  
  EOF ;  
 
// a command pre-state annotation  
statementspec: ( ’assert’ formula ’;’ )? ;  
 
// a theory declaration  
theorydecl:  
  ( ’package’ name ’;’ )? imports  
  ( ’public’ )* ’theory’ IDENT ( ’uses’ names )?  
  ’{’ ( ( declaration )? ’;’ )* ’}’ EOF ;  
 
imports: ( ’import’ name ( ’.’ ’*’ )? ’;’ )* ;  
 
declarations: ( ( declaration )? ’;’ )* ;  
 
declaration:  
  IDENT ’:’  
  ( ’TYPE’  
  | ’TYPE’ ’=’ typeExp  
  | ’FORMULA’ formula  
  | ’AXIOM’ formula  
  | typeExp ( ’=’ term |  
              ’=’ ’PRED’ paramList ’:’ formula |  
              ’<=>’ formula )?  
  ) ;  
 
typeExp:  
( typeExpBase ’->’ typeExp  
| ’(’ typeExp ( ’,’  typeExp )+  ’)’ ’->’ typeExp  
| ’ARRAY’ typeExpBase ’OF’ typeExp  
| typeExpBase  
) ;  
 
typeExpBase:  
( name  
| ’BOOLEAN’  
| ’LOGICAL’  
| ’BIT’  
| ’INT’  
| ’NAT’  
| ’REAL’  
| ’STRING’  
| ’STATE’ ( ’(’ typeExp ’)’ )?  
| ’[’ typeExp ( ’,’  typeExp )+  ’]’  
| ’[’ typeExp ’]’  
| ’[#’ IDENT ’:’ typeExp ( ’,’ IDENT ’:’ typeExp )* ’#]’  
| ’SUBTYPE’ ’(’ term ’)’  
| ’[’ term ’..’ term ’]’  
| ’PREDICATE’ ( ’(’ typeExp ( ’,’  typeExp )*  ’)’ )?  
| ’(’ typeExp ’)’ ) ;  
 
// ----------------------------------------------------------------------  
// formulas  
// ----------------------------------------------------------------------  
 
// quantifiers bind weakest  
formula:  
( ’FORALL’ paramList ’:’ formula  
| ’EXISTS’ paramList ’:’ formula  
| formula10  
) ;  
 
// lets  
formula10:  
( ’LET’ vdefinition ( ’,’ vdefinition )* ’IN’ formula10  
| formula20  
) ;  
 
// implications, equivalences, exclusive ors (= non-equivalences)  
formula20:  
( formula30 ’=>’ formula20  
| formula30 ( ’<=>’ formula30 | ’XOR’ formula30 )?  
) ;  
 
// disjunctions  
formula30: formula40 ( ’OR’ formula40 )* ;  
 
// conjunctions  
formula40: formula50 ( ’AND’ formula50 )* ;  
 
// logical negations  
formula50: ’NOT’ formula50 | formula60 ;  
 
// equality and inequality and relations  
formula60:  
  term  
  ( ’=’ term | ’/=’ term | ’<’ term | ’<=’ term | ’>’ term | ’>=’ term )  
| formula70 ;  
 
// atomic predicates  
formula70:  
  name ’(’ term ( ’,’ term )* ’)’  
| ’EXECUTES’ ’@’ statearg | ’CONTINUES’ ’@’ statearg  
| ’BREAKS’ ’@’ statearg | ’RETURNS’ ’@’ statearg  
| ’THROWS’ ’@’ statearg | ’THROWS’ ’(’ name ’)’ ’@’ statearg  
| formula100 ;  
 
// argument to state predicate  
statearg: ’NOW’ | ’NEXT’ | name ;  
 
// atoms  
formula100:  
  ( name | ’(’ ’OLD’ name ’)’ | ’(’ ’VAR’ name ’)’ )  
  ( ’.’ ( NUMBER | IDENT ) | ’[’ term ’]’ )*  
| ’TRUE’ | ’FALSE’  
| ’IF’ formula ’THEN’ formula  
   ( ’ELSIF’ formula ’THEN’ formula )* ’ELSE’ formula ’ENDIF’  
| ’WRITESONLY’ names | ’READSONLY’  
| ’(’ formula ’)’  
;  
 
// ----------------------------------------------------------------------  
// terms  
// ----------------------------------------------------------------------  
 
// quantifiers bind weakest  
term: ’LAMBDA’ paramList ’:’ term | ’ARRAY’ paramList ’:’ term | term10 ;  
 
// lets  
term10: ’LET’ vdefinition ( ’,’ vdefinition )* ’IN’ term10 | term20 ;  
 
// sums and differences  
term20: term30 ( ’+’ term30 | ’-’ term30 | ’|’ term30 )* ;  
 
// products and quotients  
term30: term40 ( ’*’ term40 | ’/’ term40 | ’&’ term40 )* ;  
 
// power terms  
term40: term50 ( ’^’ term50 )* ;  
 
// unary arithmetic operators  
term50: ’+’ term50 | ’-’ term50 | ’~’ term50 | term60 ;  
 
// updates  
term60:  
  term70  
  ( ’WITH’ ( ’.’ ( NUMBER | IDENT ) | ’[’ term ’]’ )+ ’:=’ term70 )* ;  
 
// selections  
term70: term80 ( ’.’ ( NUMBER | IDENT ) | ’[’ term ’]’ )* ;  
 
// applications  
term80:  
  ’VALUE’ ’@’ term100 | ’MESSAGE’ ’@’ term100  
| term100 ( ’(’ term ( ’,’ term )* ’)’ )* ;  
 
// atoms  
term100:  
  name | NUMBER | STRING | ’TRUE’ | ’FALSE’  
| ’LOGICALTRUE’ | ’LOGICALFALSE’ | ’BITTRUE’ | ’BITFALSE’  
| ’OLD’ name | ’VAR’ name | ’NOW’ | ’NEXT’  
| ’(’ term ( ’,’  term )* ’)’  
| ’(#’ IDENT ’:=’ term ( ’,’ IDENT ’:=’ term )* ’#)’  
| ’IF’ formula ’THEN’ term  
  ( ’ELSIF’ formula ’THEN’ term )* ’ELSE’ term ’ENDIF’ ;  
 
// ----------------------------------------------------------------------  
// auxiliaries  
// ----------------------------------------------------------------------  
 
paramList: ’(’ param[params] ( ’,’ param[params] )* ’)’ ;  
 
param: IDENT ( ’,’ IDENT )* ’:’ typeExp ;  
 
// value definition  
vdefinition: IDENT ’:’ typeExp  ’=’ term | IDENT ’=’ term ;  
 
// a name  
name: IDENT ( ’.’ IDENT )* ;  
 
// a sequence of names  
names: name ( ’,’ name )* ;  
 
// ----------------------------------------------------------------------  
// lexical syntax  
// ----------------------------------------------------------------------  
 
IDENT: REALLETTER (LETTER | DIGIT)* ;  
NUMBER: DIGIT (DIGIT)* ;  
STRING : ’~’ (~(’~’ | ’\\’ | EOL) | ESCAPED )* ’~’ ;  
REALLETTER: (’a’..’z’ | ’A’..’Z’ );  
LETTER: ( REALLETTER | ’_’);  
DIGIT: (’0’..’9’);  
WS: (’ ’ | ’\t’ | EOL | COMMENT) { $channel=HIDDEN; };  
EOL: (’\n’ | ’\r’ | ’\f’);  
COMMENT : ’//’ .* EOL | ’/*’ .* ’*/’ ;  
ESCAPED : ’\\’  
  ( ’\\’ | ’~’ | ’\’’ | ’n’ | ’t’ | ’b’ | ’f’ | ’r’ |  
    (’u’ HEX HEX HEX HEX) ) ;  
HEX : ’0’..’9’ | ’a’..’f’ | ’A’..’F’ ;