diff --git a/prism/src/parser/PrismParser.jj b/prism/src/parser/PrismParser.jj index 4ec460e9..96ca0351 100644 --- a/prism/src/parser/PrismParser.jj +++ b/prism/src/parser/PrismParser.jj @@ -1590,7 +1590,10 @@ Expression ExpressionProb(boolean prop, boolean pathprop) : |( begin = { relOp = "min="; isBool = false; } ) |( begin = { relOp = "max="; isBool = false; } )) // Path formula, optional filter - expr = Expression(prop, true) (filter = Filter())? + + expr = PathSpecification(prop) + (filter = Filter())? + { ret.setModifier(modifier == null ? null : modifier.getName()); ret.setRelOp(relOp); @@ -1610,6 +1613,64 @@ Expression ExpressionProb(boolean prop, boolean pathprop) : } } +// A path specification: +// Currently, can be +// - an LTL formula, i.e., Expression() +// - a (possibly negated) HOA: ... automaton specification +Expression PathSpecification(boolean prop) : +{ + Expression result; + ExpressionIdent kind = null; +} +{ + ( + // HOA: .... + ( LOOKAHEAD( { getToken(1).kind==REG_IDENT + && getToken(1).image.equals("HOA") + && getToken(2).kind==COLON } ) + kind = IdentifierExpression() result = PathSpecificationHOA(prop) + ) + | + // ! HOA: .... + ( LOOKAHEAD( { getToken(1).kind==NOT + && getToken(2).kind==REG_IDENT + && getToken(2).image.equals("HOA") + && getToken(3).kind==COLON } ) + + kind = IdentifierExpression() result = PathSpecificationHOA(prop) + {result = Expression.Not(result);} + ) + | + ( LOOKAHEAD( { getToken(1).kind==REG_IDENT + && getToken(2).kind==COLON } ) + kind = IdentifierExpression() + { throw new ParseException("Unknown path type '"+kind.getName()+"'"); } + ) + | + (result = Expression(prop, true)) + ) + {return result;} +} + + +// The inner part of a HOA: { "automatonfile", "ap" <- state-expression, ... } specification +ExpressionHOA PathSpecificationHOA(boolean prop) : +{ + QuotedString hoaAutomatonFile; + ExpressionHOA result = null; + Expression stateExpression = null; + String ap, label; +} +{ + hoaAutomatonFile = QuotedString() + { result = new ExpressionHOA(hoaAutomatonFile); } + ( ap = QuotedIdentifier() stateExpression = Expression(prop, false) {result.addRename(ap, stateExpression);} )* + + {return result;} +} + + + // Filter for a P/S/R operator Filter Filter() :