Browse Source

Bugfix: look for undefined constants recursively in referenced properties.

git-svn-id: https://www.prismmodelchecker.org/svn/prism/prism/trunk@4499 bbc10eb1-c90d-0410-af57-cb519fbb1720
master
Dave Parker 14 years ago
parent
commit
c7365ce0d9
  1. 25
      prism/src/parser/ast/ASTElement.java
  2. 11
      prism/src/parser/ast/PropertiesFile.java
  3. 29
      prism/src/parser/visitor/GetAllUndefinedConstantsRecursively.java

25
prism/src/parser/ast/ASTElement.java

@ -115,11 +115,11 @@ public abstract class ASTElement
*/ */
public Type getType() public Type getType()
{ {
if (type != null) return type;
if (type != null)
return type;
try { try {
typeCheck(); typeCheck();
}
catch (PrismLangException e) {
} catch (PrismLangException e) {
// Returns null (unknown) in case of error. // Returns null (unknown) in case of error.
// If you want to check for errors, use typeCheck(). // If you want to check for errors, use typeCheck().
return null; return null;
@ -258,7 +258,7 @@ public abstract class ASTElement
*/ */
public Vector<String> getAllConstants() public Vector<String> getAllConstants()
{ {
Vector<String> v= new Vector<String>();
Vector<String> v = new Vector<String>();
GetAllConstants visitor = new GetAllConstants(v); GetAllConstants visitor = new GetAllConstants(v);
try { try {
accept(visitor); accept(visitor);
@ -271,19 +271,20 @@ public abstract class ASTElement
/** /**
* Get all undefined constants used (i.e. in ExpressionConstant objects) recursively and return as a list. * Get all undefined constants used (i.e. in ExpressionConstant objects) recursively and return as a list.
* Recursive descent means that we find e.g. constants that are used within other constants, labels.
* But note that we only look at/for constants in the passed in ConstantList.
* Recursive descent means that we also find constants that are used within other constants, labels, properties.
* We only recurse into constants/labels/properties in the passed in lists.
* Any others discovered are ignored (and not descended into). * Any others discovered are ignored (and not descended into).
* ConstantList must be non-null so that we can determine which constants are undefined;
* LabelList and PropertiesFile passed in as null are ignored.
*/ */
public Vector<String> getAllUndefinedConstantsRecursively(ConstantList constantList, LabelList labelList)
public Vector<String> getAllUndefinedConstantsRecursively(ConstantList constantList, LabelList labelList, PropertiesFile propertiesFile)
{ {
Vector<String> v= new Vector<String>();
GetAllUndefinedConstantsRecursively visitor = new GetAllUndefinedConstantsRecursively(v, constantList, labelList);
Vector<String> v = new Vector<String>();
GetAllUndefinedConstantsRecursively visitor = new GetAllUndefinedConstantsRecursively(v, constantList, labelList, propertiesFile);
try { try {
accept(visitor); accept(visitor);
} catch (PrismLangException e) { } catch (PrismLangException e) {
// GetAllUndefinedConstantsRecursively can throw an exception (if a constant does not exist)
// but this would have been caught by earlier checks so we ignore.
// Should not happen; ignore.
} }
return v; return v;
} }
@ -321,7 +322,7 @@ public abstract class ASTElement
*/ */
public Vector<String> getAllVars() throws PrismLangException public Vector<String> getAllVars() throws PrismLangException
{ {
Vector<String> v =new Vector<String>();
Vector<String> v = new Vector<String>();
GetAllVars visitor = new GetAllVars(v); GetAllVars visitor = new GetAllVars(v);
accept(visitor); accept(visitor);
return v; return v;

11
prism/src/parser/ast/PropertiesFile.java

@ -366,6 +366,7 @@ public class PropertiesFile extends ASTElement
/** /**
* Get a list of undefined (properties file) constants appearing in labels of the properties file * Get a list of undefined (properties file) constants appearing in labels of the properties file
* (including those that appear in definitions of other needed constants)
* (undefined constants are those of form "const int x;" rather than "const int x = 1;") * (undefined constants are those of form "const int x;" rather than "const int x = 1;")
*/ */
public Vector<String> getUndefinedConstantsUsedInLabels() public Vector<String> getUndefinedConstantsUsedInLabels()
@ -377,7 +378,7 @@ public class PropertiesFile extends ASTElement
n = labelList.size(); n = labelList.size();
for (i = 0; i < n; i++) { for (i = 0; i < n; i++) {
expr = labelList.getLabel(i); expr = labelList.getLabel(i);
tmp = expr.getAllUndefinedConstantsRecursively(constantList, combinedLabelList);
tmp = expr.getAllUndefinedConstantsRecursively(constantList, combinedLabelList, null);
for (String s : tmp) { for (String s : tmp) {
if (!consts.contains(s)) { if (!consts.contains(s)) {
consts.add(s); consts.add(s);
@ -389,17 +390,17 @@ public class PropertiesFile extends ASTElement
/** /**
* Get a list of undefined (properties file) constants used in a property * Get a list of undefined (properties file) constants used in a property
* (including those that appear in required labels/properties)
* (including those that appear in definitions of other needed constants and labels/properties)
* (undefined constants are those of form "const int x;" rather than "const int x = 1;") * (undefined constants are those of form "const int x;" rather than "const int x = 1;")
*/ */
public Vector<String> getUndefinedConstantsUsedInProperty(Property prop) public Vector<String> getUndefinedConstantsUsedInProperty(Property prop)
{ {
return prop.getExpression().getAllUndefinedConstantsRecursively(constantList, combinedLabelList);
return prop.getExpression().getAllUndefinedConstantsRecursively(constantList, combinedLabelList, this);
} }
/** /**
* Get a list of undefined (properties file) constants used in a list of properties * Get a list of undefined (properties file) constants used in a list of properties
* (including those that appear in required labels/properties)
* (including those that appear in definitions of other needed constants and labels/properties)
* (undefined constants are those of form "const int x;" rather than "const int x = 1;") * (undefined constants are those of form "const int x;" rather than "const int x = 1;")
*/ */
public Vector<String> getUndefinedConstantsUsedInProperties(List <Property> props) public Vector<String> getUndefinedConstantsUsedInProperties(List <Property> props)
@ -407,7 +408,7 @@ public class PropertiesFile extends ASTElement
Vector<String> consts, tmp; Vector<String> consts, tmp;
consts = new Vector<String>(); consts = new Vector<String>();
for (Property prop : props) { for (Property prop : props) {
tmp = prop.getExpression().getAllUndefinedConstantsRecursively(constantList, combinedLabelList);
tmp = prop.getExpression().getAllUndefinedConstantsRecursively(constantList, combinedLabelList, this);
for (String s : tmp) { for (String s : tmp) {
if (!consts.contains(s)) { if (!consts.contains(s)) {
consts.add(s); consts.add(s);

29
prism/src/parser/visitor/GetAllUndefinedConstantsRecursively.java

@ -33,21 +33,25 @@ import prism.PrismLangException;
/** /**
* Get all undefined constants used (i.e. in ExpressionConstant objects) recursively and return as a list. * Get all undefined constants used (i.e. in ExpressionConstant objects) recursively and return as a list.
* Recursive descent means that we find e.g. constants that are used within other constants, labels.
* But note that we only look at/for constants in the passed in ConstantList.
* Recursive descent means that we also find constants that are used within other constants, labels, properties.
* We only recurse into constants/labels/properties in the passed in lists.
* Any others discovered are ignored (and not descended into). * Any others discovered are ignored (and not descended into).
* ConstantList must be non-null so that we can determine which constants are undefined;
* LabelList and PropertiesFile passed in as null are ignored.
*/ */
public class GetAllUndefinedConstantsRecursively extends ASTTraverse public class GetAllUndefinedConstantsRecursively extends ASTTraverse
{ {
private Vector<String> v; private Vector<String> v;
private ConstantList constantList; private ConstantList constantList;
private LabelList labelList; private LabelList labelList;
private PropertiesFile propertiesFile;
public GetAllUndefinedConstantsRecursively(Vector<String> v, ConstantList constantList, LabelList labelList)
public GetAllUndefinedConstantsRecursively(Vector<String> v, ConstantList constantList, LabelList labelList, PropertiesFile propertiesFile)
{ {
this.v = v; this.v = v;
this.constantList = constantList; this.constantList = constantList;
this.labelList = labelList; this.labelList = labelList;
this.propertiesFile = propertiesFile;
} }
public void visitPost(ExpressionConstant e) throws PrismLangException public void visitPost(ExpressionConstant e) throws PrismLangException
@ -76,13 +80,26 @@ public class GetAllUndefinedConstantsRecursively extends ASTTraverse
if (e.getName().equals("deadlock") || e.getName().equals("init")) { if (e.getName().equals("deadlock") || e.getName().equals("init")) {
return; return;
} }
// Look up this label in the label list
// Look up this label in the label list, if possible
if (labelList == null)
return;
int i = labelList.getLabelIndex(e.getName()); int i = labelList.getLabelIndex(e.getName());
if (i == -1) if (i == -1)
throw new PrismLangException("Unknown label \"" + e.getName() + "\"");
return;
Expression expr = labelList.getLabel(i); Expression expr = labelList.getLabel(i);
// Check label definition recursively for more undefined constants // Check label definition recursively for more undefined constants
expr.accept(this); expr.accept(this);
} }
}
public void visitPost(ExpressionProp e) throws PrismLangException
{
// Look up this property in the properties files, if possible
if (propertiesFile == null)
return;
Property prop = propertiesFile.lookUpPropertyObjectByName(e.getName());
if (prop == null)
return;
// Check property recursively for more undefined constants
prop.getExpression().accept(this);
}
}
Loading…
Cancel
Save