//============================================================================== // // Copyright (c) 2002- // Authors: // * Dave Parker (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 : { } // skip (but store) comments SPECIAL_TOKEN : { } // 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: "."(["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() )* ) } // properties file void PropertiesFile() : {} { ( ( /*FormulaDef() |*/ LabelDef() | ConstantDef() | PCTLFormula() { getToken(0).image += ";"; } )* ) } // a single expression void SingleExpression() : {} { ( Expression() ) } //----------------------------------------------------------------------------------- // modules file stuff //----------------------------------------------------------------------------------- // keyword denoting module type (nondeterministic, probabilistic, ...) void ModulesFileType() : {} { ( | | | | | ) } // formula definition void FormulaDef() : {} { ( Identifier() Expression() ) } // label definition void LabelDef() : {} { (