You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

806 lines
18 KiB

//==============================================================================
//
// Copyright (c) 2002-
// Authors:
// * Dave Parker <david.parker@comlab.ox.ac.uk> (University of Oxford, formerly University of Birmingham)
//
//------------------------------------------------------------------------------
//
// This file is part of PRISM.
//
// PRISM 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.
//
// PRISM 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.
//
// You should have received a copy of the GNU General Public License
// along with PRISM; if not, write to the Free Software Foundation,
// Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
//==============================================================================
// This is a very stripped down version of the PRISM version 3.x parser
// used to generate valid code for post-3.x versions of PRISM.
// It fixes 3 things:
// * appends semicolons to properties in properties files
// * ensures that updates are parenthesised
// * replaces the defunct range operator with an equivalent expression
options {
LOOKAHEAD = 2147483647; // max possible lookahead
}
PARSER_BEGIN(Prism3To4)
package parser;
import java.io.*;
@SuppressWarnings({"unused", "static-access", "serial"})
public class Prism3To4
{
public static void main(String[] args) throws ParseException
{
try {
Prism3To4 p;
if (args.length > 0) { p = new Prism3To4(new FileInputStream(args[0])); }
else { p = new Prism3To4(System.in); }
p.ModulesFileOrPropertiesFile();
}
catch (TokenMgrError e) {
System.err.println("Syntax error"+(args.length > 0?" in "+args[0]:"")+": " + e.getMessage()); System.exit(1);
}
catch (ParseException e) {
System.err.println("Error"+(args.length > 0?" in "+args[0]:"")+": " + e.getMessage()); System.exit(1);
}
catch (FileNotFoundException e) {
System.err.println(e); System.exit(1);
}
}
private static void insertTokenBeforeNext(Token t, String s)
{
Token tNew=new Token(); tNew.image=s; tNew.specialToken=t.next.specialToken; t.next.specialToken=null; tNew.next=t.next; t.next=tNew;
}
}
//-----------------------------------------------------------------------------------
PARSER_END(Prism3To4)
// skip (but store) all other white space
SPECIAL_TOKEN :
{
<WHITESPACE: (" "|"\t"|"\n"|"\r")>
}
// skip (but store) comments
SPECIAL_TOKEN :
{
<COMMENT: "//" (~["\n","\r"])* ("\n"|"\r"|"\r\n")>
}
// tokens
TOKEN :
{
// keywords
< BOOL: "bool" >
| < CONST: "const" >
| < CEIL: "ceil" >
| < CTMC: "ctmc" >
| < CUMUL: "C" >
| < DOUBLE: "double" >
| < DTMC: "dtmc" >
| < ENDINIT: "endinit" >
| < ENDMODULE: "endmodule" >
| < ENDREWARDS: "endrewards" >
| < ENDSYSTEM: "endsystem" >
| < FALSE: "false" >
| < FLOOR: "floor" >
| < FORMULA: "formula" >
| < FUNC: "func" >
| < FUTURE: "F" >
| < GLOBAL: "global" >
| < GLOB: "G" >
| < INIT: "init" >
| < INST: "I" >
| < INT: "int" >
| < LABEL: "label" >
| < MAX: "max" >
| < MDP: "mdp" >
| < MIN: "min" >
| < MODULE: "module" >
| < NEXT: "X" >
| < NONDETERMINISTIC: "nondeterministic" >
| < PMAX: "Pmax" >
| < PMIN: "Pmin" >
| < P: "P" >
| < PROBABILISTIC: "probabilistic" >
| < PROB: "prob" >
| < RATE: "rate" >
| < REWARDS: "rewards" >
| < RMAX: "Rmax" >
| < RMIN: "Rmin" >
| < R: "R" >
| < S: "S" >
| < STOCHASTIC: "stochastic" >
| < SYSTEM: "system" >
| < TRUE: "true" >
| < UNTIL: "U" >
// punctuation, etc.
// note that "NOT" must be the first item of punctuation in this list
// (PrismSyntaxHighlighter relies on this fact)
| < NOT: "!" >
| < AND: "&" >
| < OR: "|" >
| < IMPLIES: "=>" >
| < RARROW: "->" >
| < COLON: ":" >
| < SEMICOLON: ";" >
| < COMMA: "," >
| < DOTS: ".." >
| < LPARENTH: "(" >
| < RPARENTH: ")" >
| < LBRACKET: "[" >
| < RBRACKET: "]" >
| < LBRACE: "{" >
| < RBRACE: "}" >
| < EQ: "=" >
| < NE: "!=" >
| < LT: "<" >
| < GT: ">" >
| < LE: "<=" >
| < GE: ">=" >
| < PLUS: "+" >
| < MINUS: "-" >
| < TIMES: "*" >
| < DIVIDE: "/" >
| < PRIME: "'" >
| < RENAME: "<-" >
| < QMARK: "?" >
| < DQUOTE: "\"" >
// regular expressions
| < REG_INT: (["1"-"9"](["0"-"9"])*)|("0") >
//| < REG_DOUBLE: <REG_INT>"."(["0"-"9"])+ >
| < REG_DOUBLE: (["0"-"9"])*(".")?(["0"-"9"])+(["e","E"](["-","+"])?(["0"-"9"])+)? >
| < REG_IDENTPRIME: ["_","a"-"z","A"-"Z"](["_","a"-"z","A"-"Z","0"-"9"])*"'" >
| < REG_IDENT: ["_","a"-"z","A"-"Z"](["_","a"-"z","A"-"Z","0"-"9"])* >
| < PREPROC: "#"(~["#"])*"#" >
}
//-----------------------------------------------------------------------------------
// top-level stuff
//-----------------------------------------------------------------------------------
void ModulesFileOrPropertiesFile() :
{
Token t = null, ptr, ptr2;
}
{
{ t = getToken(1); }
( ModulesFile() | PropertiesFile() )
{
ptr = t;
while (ptr != null) {
if (ptr.specialToken != null) {
ptr2 = ptr;
while (ptr2.specialToken != null) ptr2 = ptr2.specialToken;
while (ptr2 != null) { System.out.print(ptr2.image); ptr2 = ptr2.next; }
}
System.out.print(ptr.image);
ptr = ptr.next;
}
}
}
// modules file
void ModulesFile() : {}
{
( ( ( ModulesFileType() ) | FormulaDef() | LabelDef() | ConstantDef() | GlobalDecl() | Module() | RenamedModule() | SystemComp() | RewardStruct() | Init() )* <EOF> )
}
// properties file
void PropertiesFile() : {}
{
( ( /*FormulaDef() |*/ LabelDef() | ConstantDef() | PCTLFormula() { getToken(0).image += ";"; }
)* <EOF> )
}
// a single expression
void SingleExpression() : {}
{
( Expression() <EOF> )
}
//-----------------------------------------------------------------------------------
// modules file stuff
//-----------------------------------------------------------------------------------
// keyword denoting module type (nondeterministic, probabilistic, ...)
void ModulesFileType() : {}
{
( <PROBABILISTIC> | <NONDETERMINISTIC> | <STOCHASTIC> | <DTMC> | <MDP> | <CTMC> )
}
// formula definition
void FormulaDef() : {}
{
( <FORMULA> Identifier() <EQ> Expression() <SEMICOLON> )
}
// label definition
void LabelDef() : {}
{
( <LABEL> <DQUOTE> Identifier() <DQUOTE> <EQ> Expression() <SEMICOLON> )
}
// constant definition
void ConstantDef() : {}
{
( <CONST> <INT> Identifier() (<EQ> Expression())? <SEMICOLON> )
| ( <CONST> <DOUBLE> Identifier() (<EQ> Expression())? <SEMICOLON> )
| ( <CONST> <BOOL> Identifier() (<EQ> Expression())? <SEMICOLON> )
| ( <CONST> Identifier() (<EQ> Expression())? <SEMICOLON> )
| ( ( <RATE> | <PROB> ) Identifier() (<EQ> Expression())? <SEMICOLON> )
}
// global variable declaration
void GlobalDecl() : {}
{
( <GLOBAL> Declaration() )
}
// module definition
void Module() : {}
{
( <MODULE> Identifier() ( Declaration() )* ( Command() )* <ENDMODULE> )
}
// variable declaration
void Declaration() : {}
{
( Identifier() <COLON> <LBRACKET> Expression() <DOTS> Expression() <RBRACKET>
( <INIT> Expression() )? <SEMICOLON> ) | ( Identifier() <COLON> <BOOL> ( <INIT> Expression() )? <SEMICOLON> )
}
// command definition
void Command() : {}
{
( <LBRACKET> ( Identifier() )? <RBRACKET> Expression() <RARROW> Updates() <SEMICOLON> )
}
void Updates() : {}
{
( Update() ) | ( ProbUpdate() ( <PLUS> ProbUpdate() )* )
}
void ProbUpdate() : {}
{
( Expression() <COLON> Update() )
}
void Update() : {}
{
( UpdateElement() ( <AND> UpdateElement() )* ) | ( <TRUE> )
}
void UpdateElement() :
{
Token t1, t2;
}
{
( <LPARENTH> IdentifierPrime() <EQ> Expression() <RPARENTH> ) | ( { t1=getToken(0); } IdentifierPrime() <EQ> Expression() { t2=getToken(0); } )
{ insertTokenBeforeNext(t1, "("); t2.image += ")"; }
}
// module definition (by renaming)
void RenamedModule() : {}
{
( <MODULE> Identifier() <EQ> Identifier() <LBRACKET> Renames() <RBRACKET> <ENDMODULE> )
}
void Renames() : {}
{
( Rename() ( <COMMA> Rename() )* )
}
void Rename() : {}
{
((( Identifier() ) | ( <MIN> ) | ( <MAX> ) | ( <FLOOR> ) | ( <CEIL> ))
<EQ>
(( Identifier() ) | ( <MIN> ) | ( <MAX> ) | ( <FLOOR> ) | ( <CEIL> )))
}
// system composition definition
void SystemComp() : {}
{
( <SYSTEM> SystemParallels() <ENDSYSTEM> )
}
// system definition component
void SystemParallels() : {}
{
( SystemFullParallel() ) | ( SystemInterleaved() ) | ( SystemParallel() ) | ( SystemHideRename() )
}
// system definition component (full parallel)
void SystemFullParallel() : {}
{
( SystemHideRename() ( <OR> <OR> SystemHideRename() )+ )
}
// system definition component (interleaved parallel)
void SystemInterleaved() : {}
{
( SystemHideRename() ( <OR> <OR> <OR> SystemHideRename() )+ )
}
// system definition component (parallel over set of actions)
void SystemParallel() : {}
{
( SystemHideRename() <OR> <LBRACKET> ( SystemAction() ( <COMMA> SystemAction() )* ) <RBRACKET> <OR> SystemHideRename() )
}
// system definition component (hiding and renaming)
void SystemHideRename() : {}
{
( SystemAtomic() ( ( ( <DIVIDE> <LBRACE> ( SystemAction() ( <COMMA> SystemAction() )* ) <RBRACE> ) |
( <LBRACE> SystemAction() <RENAME> SystemAction() ( <COMMA> SystemAction() <RENAME> SystemAction() )* <RBRACE> ) ) )* )
}
// system definition component (bottom level)
void SystemAtomic() : {}
{
( SystemModule() ) | ( SystemBrackets() )
}
// system definition component (action identifier)
void SystemAction() : {}
{
( Identifier() )
}
// system definition component (module identifier)
void SystemModule() : {}
{
( Identifier() )
}
// system definition component (brackets)
void SystemBrackets() : {}
{
( <LPARENTH> SystemParallels() <RPARENTH> )
}
// reward structure
void RewardStruct() : {}
{
( ( <REWARDS> (<DQUOTE> Identifier() <DQUOTE>)? ( RewardStructItem() )* <ENDREWARDS> ) )
}
// single line (item) of state-based rewards structure
void RewardStructItem() : {}
{
( ( <LBRACKET> ( Identifier() )? <RBRACKET> )? Expression() <COLON> Expression() <SEMICOLON> )
}
// multiple initial states
void Init() : {}
{
( ( <INIT> Expression() <ENDINIT> ) )
}
//-----------------------------------------------------------------------------------
// properties file stuff
//-----------------------------------------------------------------------------------
// pctl formula
void PCTLFormula() : {}
{
( PCTLImplies() )
}
void PCTLImplies() : {}
{
( PCTLOr() ( <IMPLIES> PCTLOr() )? )
}
void PCTLOr() : {}
{
( PCTLAnd() ( <OR> PCTLAnd() )* )
}
void PCTLAnd() : {}
{
( PCTLNot() ( <AND> PCTLNot() )* )
}
void PCTLNot() : {}
{
( (<NOT>)? PCTLProb() )
}
// pctl prob operator
void PCTLProb() : {}
{
( (
( <P> LtGt() Expression() ) |
( <P> <EQ> <QMARK> ) |
( <P> <MIN> <EQ> <QMARK> ) |
( <P> <MAX> <EQ> <QMARK> ) |
( <PMIN> <EQ> <QMARK> ) |
( <PMAX> <EQ> <QMARK> ) )
<LBRACKET>
( PCTLProbNext() | PCTLProbBoundedUntil() | PCTLProbUntil() | PCTLProbBoundedFutureGlobal() | PCTLProbFutureGlobal() )
( <LBRACE> PCTLFormula() <RBRACE>
(( <LBRACE> <MIN> <RBRACE> ) | ( <LBRACE> <MAX> <RBRACE> ))*
)? <RBRACKET> )
| ( PCTLSS() )
}
// pctl next
void PCTLProbNext() : {}
{
( <NEXT> PCTLFormula() )
}
// pctl bounded until
void PCTLProbBoundedUntil() : {}
{
( PCTLFormula() <UNTIL> ((<LE> Expression()) | (<GE> Expression()) | (<LBRACKET> Expression() <COMMA> Expression() <RBRACKET>)) PCTLFormula() )
}
// pctl until (unbounded)
void PCTLProbUntil() : {}
{
( PCTLFormula() <UNTIL> PCTLFormula() )
}
// pctl bounded future (eventually) or global
void PCTLProbBoundedFutureGlobal() : {}
{
( (<FUTURE>|<GLOB>) ((<LE> Expression()) | (<GE> Expression()) | (<LBRACKET> Expression() <COMMA> Expression() <RBRACKET>)) PCTLFormula() )
}
// pctl future (eventually) or globally
void PCTLProbFutureGlobal() : {}
{
( (<FUTURE>|<GLOB>) PCTLFormula() )
}
// pctl steady state (actually only csl - not pctl at all)
void PCTLSS() : {}
{
( ( ( ( <S> LtGt() Expression() ) | ( <S> <EQ> <QMARK> ) ) <LBRACKET> PCTLFormula() ( <LBRACE> PCTLFormula() <RBRACE> )? <RBRACKET> ) ) | ( PCTLReward() )
}
// pctl reward operator
void PCTLReward() : {}
{
( ( ( <R>
( <LBRACE> ((<DQUOTE> Identifier() <DQUOTE>) | (Expression())) <RBRACE> )?
(( LtGt() Expression() ) |
( <EQ> <QMARK> ) |
( <MIN> <EQ> <QMARK> ) |
( <MAX> <EQ> <QMARK> ))) |
( <RMIN> <EQ> <QMARK> ) |
( <RMAX> <EQ> <QMARK> ) )
<LBRACKET>
( PCTLRewardCumul() | PCTLRewardInst() | PCTLRewardReach() | PCTLRewardSS() )
( <LBRACE> PCTLFormula() <RBRACE>
(( <LBRACE> <MIN> <RBRACE> ) | ( <LBRACE> <MAX> <RBRACE> ))*
)? <RBRACKET> )
| ( PCTLInit() )
}
// cumulative reward
void PCTLRewardCumul() : {}
{
( <CUMUL> <LE> Expression() )
}
// instantaneous reward
void PCTLRewardInst() : {}
{
( <INST> <EQ> Expression() )
}
// reach reward
void PCTLRewardReach() : {}
{
( <FUTURE> PCTLFormula() )
}
// steady-state reward
void PCTLRewardSS() : {}
{
( <S> )
}
// init
void PCTLInit() : {}
{
( <DQUOTE> <INIT> <DQUOTE> ) | ( PCTLLabel() )
}
// label
void PCTLLabel() : {}
{
( <DQUOTE> Identifier() <DQUOTE> ) | ( PCTLBrackets() )
}
// brackets
void PCTLBrackets() : {}
{
( <LPARENTH> PCTLFormula() <RPARENTH> ) | ( PCTLExpression() )
}
// pctl expression
void PCTLExpression() : {}
{
( ExpressionRelOpRange() )
}
//-----------------------------------------------------------------------------------
// expression stuff
//-----------------------------------------------------------------------------------
// expression
void Expression() : {}
{
( ExpressionITE() )
}
// expression (if-then-else)
void ExpressionITE() : {}
{
( ExpressionOr() <QMARK> ExpressionOr() <COLON> ExpressionITE() ) | ( ExpressionOr() )
}
// expression (or)
void ExpressionOr() : {}
{
( ExpressionAnd() ( <OR> ExpressionOr() )? )
}
// expression (and)
void ExpressionAnd() : {}
{
( ExpressionNot() ( <AND> ExpressionNot() )* )
}
// expression (not)
void ExpressionNot() : {}
{
( (<NOT>)? ExpressionRelOpRange() )
}
// expression: relational operators/ranges
void ExpressionRelOpRange() :
{
Token t0, t1, t2, ptr;
String relOp = null;
boolean up, thisIsARange = false;
String lhs = null, s1 = null, s2 = null, newExpr = "";
}
{
( ExpressionPlusMinus() relOp=LtGt() ExpressionPlusMinus() ) | (
{ t0=getToken(0); t1=getToken(1); }
ExpressionPlusMinus()
{ t2=getToken(1); ptr = t1; lhs = ""; while (ptr != t2) { lhs += ptr.image; ptr = ptr.next; } }
relOp=EqNeq() (
{ newExpr = (relOp.equals("!="))?"!(":"("; }
{ t1=getToken(1); }
ExpressionPlusMinus()
{ t2=getToken(1); ptr = t1; s1 = ""; while (ptr != t2) { s1 += ptr.image; ptr = ptr.next; } up = false; }
( <DOTS>
{ thisIsARange = true; t1=getToken(1); }
ExpressionPlusMinus()
{ t2=getToken(1); ptr = t1; s2 = ""; while (ptr != t2) { s2 += ptr.image; ptr = ptr.next; } up = true; }
)?
{ if (up) newExpr += "("+lhs+")>=("+s1+")&("+lhs+")<=("+s2+")"; else newExpr += "("+lhs+")=("+s1+")"; }
) ( ( <COMMA>
{ thisIsARange = true; t1=getToken(1); }
ExpressionPlusMinus()
{ t2=getToken(1); ptr = t1; s1 = ""; while (ptr != t2) { s1 += ptr.image; ptr = ptr.next; } up = false; }
( <DOTS>
{ t1=getToken(1); }
ExpressionPlusMinus()
{ t2=getToken(1); ptr = t1; s2 = ""; while (ptr != t2) { s2 += ptr.image; ptr = ptr.next; } up = true; }
)?
{ if (up) newExpr += "|("+lhs+")>=("+s1+")&("+lhs+")<=("+s2+")"; else newExpr += "|("+lhs+")=("+s1+")"; }
) )*
{ newExpr += ")"; if (thisIsARange) { t0.next = getToken(1); insertTokenBeforeNext(t0, newExpr); } }
) | ( ExpressionPlusMinus() )
}
// expression: plus/minus - binary, left associative
void ExpressionPlusMinus() : {}
{
( ExpressionTimesDivide() ( ( <PLUS> | <MINUS> ) ExpressionTimesDivide() )* )
}
// expression: times/divide - binary, left associative
void ExpressionTimesDivide() : {}
{
( ExpressionUnaryMinus() ( ( <TIMES> | <DIVIDE> ) ExpressionUnaryMinus() )* )
}
// expression: unary minus (right associative)
void ExpressionUnaryMinus() : {}
{
( <MINUS> ExpressionFunc() ) | ( ExpressionFunc() )
}
// expression (function)
void ExpressionFunc() : {}
{
((((( <MIN> ) | ( <MAX> ) | ( <FLOOR> ) | ( <CEIL> )) <LPARENTH> ) | ( <FUNC> <LPARENTH> (( Identifier() ) | ( <MIN> ) | ( <MAX> ) | ( <FLOOR> ) | ( <CEIL> )) <COMMA> )) Expression() ( <COMMA> Expression() )* <RPARENTH> ) | ( ExpressionIdent() )
}
// expression (identifier)
void ExpressionIdent() : {}
{
( Identifier() ) | ( ExpressionLiteral() )
}
// expression (literal)
void ExpressionLiteral() : {}
{
( Int() ) | ( Double() ) | ( <TRUE> ) | ( <FALSE> ) | ( ExpressionBrackets() )
}
// expression (brackets)
void ExpressionBrackets() : {}
{
( <LPARENTH> Expression() <RPARENTH> )
}
//-----------------------------------------------------------------------------------
// miscellaneous stuff
//-----------------------------------------------------------------------------------
// identifier
String Identifier() :
{
}
{
<REG_IDENT>
{
return token.image;
}
}
// identifier with a prime
String IdentifierPrime() :
{
}
{
<REG_IDENTPRIME>
{
// remove prime and return
String s = token.image;
s = s.substring(0, s.length()-1);
return s;
}
}
// one of the relational operators: =, !=
String EqNeq() :
{
}
{
( <EQ> | <NE> )
{
return token.image;
}
}
// one of the relational operators: >, <, >=, <=
String LtGt() :
{
}
{
( <GT> | <LT> | <GE> | <LE> )
{
return token.image;
}
}
// integer
int Int() :
{
int i;
}
{
// basic int
<REG_INT>
{
i = Integer.parseInt(token.image);
return i;
}
}
// double
String Double() :
{
}
{
<REG_DOUBLE>
{
//return Double.valueOf(token.image).doubleValue();
return token.image;
}
}
//------------------------------------------------------------------------------