/***************************************************************************
*
* Copyright (c) 2009 IHA
*
* Author: Kenneth Lausdahl and Augusto Ribeiro
*
* This file is part of VDMJ.
*
* VDMJ 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 3 of the License, or
* (at your option) any later version.
*
* VDMJ 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 VDMJ. If not, see <http://www.gnu.org/licenses/>.
*
**************************************************************************/
package org.overture.interpreter.runtime.validation;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Vector;
import org.overture.interpreter.messages.rtlog.RTMessage.MessageType;
import org.overture.interpreter.runtime.validation.ValueValidationExpression.BinaryOps;
public class TimingInvariantsParser
{
int counter = 1;
public List<ConjectureDefinition> parse(File file) throws IOException
{
StringBuffer contents = new StringBuffer();
BufferedReader reader = null;
boolean enabled = false;
try
{
reader = new BufferedReader(new FileReader(file));
String text = null;
// repeat until all lines is read
while ((text = reader.readLine()) != null)
{
if (text.replaceAll("\\s", " ").startsWith("/* timing invariants"))
{
enabled = true;
continue;
}
if (text.replaceAll("\\s", "").startsWith("*/"))
{
enabled = false;
}
if (enabled && text.trim().length() > 0)
{
contents.append("\n" + text);
}
}
return parse(contents.toString());
} finally
{
try
{
if (reader != null)
{
reader.close();
}
} catch (IOException e)
{
e.printStackTrace();
}
}
}
private List<ConjectureDefinition> parse(String contents)
{
List<ConjectureDefinition> defs = new Vector<ConjectureDefinition>();
try
{
int indexOfLParn = contents.indexOf('(');
while ((indexOfLParn = contents.indexOf('(')) != -1)
{
String propName = contents.substring(0, indexOfLParn).trim();
contents = contents.substring(indexOfLParn + 1);
int end = contents.indexOf(';') - 1;
String propBody = contents.substring(0, end);
contents = contents.substring(end + 2);
String[] elements = propBody.split(",");
List<String> elemsFirst = Arrays.asList(elements);
List<String> elems = null;
if (elemsFirst.size() > 3)
{
elems = new ArrayList<String>();
elems.add(elemsFirst.get(0) + "," + elemsFirst.get(1));
elems.add(elemsFirst.get(2));
elems.add(elemsFirst.get(3));
} else
{
elems = elemsFirst;
}
List<IValidationExpression> args = decodeArg(elems.get(0));
OperationValidationExpression initOp = null;
ValueValidationExpression initValue = null;
OperationValidationExpression endOp = null;
int interval = 0;
initOp = (OperationValidationExpression) args.get(0);
if (args.size() > 1)
{
initValue = (ValueValidationExpression) args.get(1);
}
args = decodeArg(elems.get(1));
endOp = (OperationValidationExpression) args.get(0);
args = decodeArg(elems.get(2));
interval = ((IntegerContainer) args.get(0)).getValue();
if (propName.equals("deadlineMet"))
{
defs.add(new DeadlineMet("C" + counter++, initOp, initValue, endOp, (int) (interval * 1E6)));
} else if (propName.equals("separate"))
{
defs.add(new Separate("C" + counter++, initOp, initValue, endOp, (int) (interval * 1E6)));
}
}
} catch (IndexOutOfBoundsException e)
{
e.printStackTrace();
}
return defs;
}
private List<IValidationExpression> decodeArg(String string)
{
List<IValidationExpression> res = new ArrayList<IValidationExpression>();
string = string.trim();
if (string.startsWith("("))
{
string = string.substring(1, string.length() - 1);
String[] dividedString = string.split(",");
for (String s : dividedString)
{
res.addAll(decodeArg(s));
}
} else if (string.startsWith("#"))
{
MessageType type = MessageType.Request;
if (string.startsWith("#req"))
{
type = MessageType.Request;
} else if (string.startsWith("#act"))
{
type = MessageType.Activate;
} else if (string.startsWith("#fin"))
{
type = MessageType.Completed;
}
string = string.substring(string.indexOf("(") + 1, string.length() - 1);
String[] name = string.split("`");
res.add(new OperationValidationExpression(name[1], name[0], type));
} else if (string.matches("\\d+\\W\\w\\w"))
{
res.add(new IntegerContainer(Integer.valueOf(string.substring(0, string.indexOf(' ')))));
} else if (string.matches("\\w+`\\w+[.\\w+]*\\W+\\w+`\\w+"))
{
ValueValidationExpression.BinaryOps binop = BinaryOps.EQ;
if (string.contains(BinaryOps.EQ.syntax))
{
binop = BinaryOps.EQ;
} else if (string.contains(BinaryOps.GREATER.syntax))
{
binop = BinaryOps.GREATER;
} else if (string.contains(BinaryOps.GREATEREQ.syntax))
{
binop = BinaryOps.GREATEREQ;
} else if (string.contains(BinaryOps.LESS.syntax))
{
binop = BinaryOps.LESS;
} else if (string.contains(BinaryOps.LESSEQ.syntax))
{
binop = BinaryOps.LESSEQ;
}
String left = string.substring(0, string.indexOf(binop.syntax));
String right = string.substring(string.indexOf(binop.syntax)
+ binop.syntax.length());
String[] leftName;
if (left.contains("`"))
{
leftName = left.split("`");
} else
{
leftName = left.split(".");
}
String[] rightName;
if (right.contains("`"))
{
rightName = right.split("`");
} else
{
rightName = right.split(".");
}
res.add(new ValueValidationExpression(leftName, binop, rightName));
}
return res;
}
}