use of de.be4.classicalb.core.parser.exceptions.PreParseException in project probparsers by bendisposto.
the class PreParser method sortDefinitionsByTopologicalOrderAndCheckForCycles.
private List<Token> sortDefinitionsByTopologicalOrderAndCheckForCycles(Map<Token, Token> definitions) throws PreParseException {
final Set<String> definitionNames = new HashSet<>();
final Map<String, Token> definitionMap = new HashMap<>();
for (Token token : definitions.keySet()) {
final String definitionName = token.getText();
definitionNames.add(definitionName);
definitionMap.put(definitionName, token);
}
Map<String, Set<String>> dependencies = determineDependencies(definitionNames, definitions);
List<String> sortedDefinitionNames = Utils.sortByTopologicalOrder(dependencies);
if (sortedDefinitionNames.size() < definitionNames.size()) {
Set<String> remaining = new HashSet<>(definitionNames);
remaining.removeAll(sortedDefinitionNames);
List<String> cycle = Utils.determineCycle(remaining, dependencies);
StringBuilder sb = new StringBuilder();
for (Iterator<String> iterator = cycle.iterator(); iterator.hasNext(); ) {
sb.append(iterator.next());
if (iterator.hasNext()) {
sb.append(" -> ");
}
}
final Token firstDefinitionToken = definitionMap.get(cycle.get(0));
throw new PreParseException(firstDefinitionToken, "Cyclic references in definitions: " + sb.toString());
} else {
List<Token> sortedDefinitionTokens = new ArrayList<>();
for (String name : sortedDefinitionNames) {
sortedDefinitionTokens.add(definitionMap.get(name));
}
return sortedDefinitionTokens;
}
}
use of de.be4.classicalb.core.parser.exceptions.PreParseException in project probparsers by bendisposto.
the class PreParser method determineType.
private DefinitionType determineType(final Token definition, final Token rhsToken, final Set<String> untypedDefinitions) throws PreParseException {
final String definitionRhs = rhsToken.getText();
de.be4.classicalb.core.parser.node.Start start;
de.be4.classicalb.core.parser.node.Token errorToken = null;
try {
start = tryParsing(BParser.FORMULA_PREFIX, definitionRhs);
// Predicate?
PParseUnit parseunit = start.getPParseUnit();
if (parseunit instanceof APredicateParseUnit) {
return new DefinitionType(IDefinitions.Type.Predicate);
}
// Expression or Expression/Substituion (e.g. f(x))?
AExpressionParseUnit expressionParseUnit = (AExpressionParseUnit) parseunit;
PreParserIdentifierTypeVisitor visitor = new PreParserIdentifierTypeVisitor(untypedDefinitions);
expressionParseUnit.apply(visitor);
if (visitor.isKaboom()) {
return new DefinitionType();
}
PExpression expression = expressionParseUnit.getExpression();
if ((expression instanceof AIdentifierExpression) || (expression instanceof AFunctionExpression) || (expression instanceof ADefinitionExpression)) {
return new DefinitionType(IDefinitions.Type.ExprOrSubst);
}
return new DefinitionType(IDefinitions.Type.Expression);
} catch (de.be4.classicalb.core.parser.parser.ParserException e) {
errorToken = e.getToken();
try {
tryParsing(BParser.SUBSTITUTION_PREFIX, definitionRhs);
return new DefinitionType(IDefinitions.Type.Substitution, errorToken);
} catch (de.be4.classicalb.core.parser.parser.ParserException ex) {
final de.be4.classicalb.core.parser.node.Token errorToken2 = ex.getToken();
if (errorToken.getLine() > errorToken2.getLine() || (errorToken.getLine() == errorToken2.getLine() && errorToken.getPos() >= errorToken2.getPos())) {
final String newMessage = determineNewErrorMessageWithCorrectedPositionInformations(definition, rhsToken, errorToken, e.getMessage());
return new DefinitionType(newMessage, errorToken);
} else {
final String newMessage = determineNewErrorMessageWithCorrectedPositionInformations(definition, rhsToken, errorToken2, ex.getMessage());
return new DefinitionType(newMessage, errorToken2);
}
} catch (BLexerException e1) {
errorToken = e1.getLastToken();
final String newMessage = determineNewErrorMessageWithCorrectedPositionInformations(definition, rhsToken, errorToken, e.getMessage());
throw new PreParseException(newMessage);
} catch (de.be4.classicalb.core.parser.lexer.LexerException e3) {
throw new PreParseException(determineNewErrorMessageWithCorrectedPositionInformationsWithoutToken(definition, rhsToken, e3.getMessage()));
} catch (IOException e1) {
throw new PreParseException(e.getMessage());
}
} catch (BLexerException e) {
errorToken = e.getLastToken();
final String newMessage = determineNewErrorMessageWithCorrectedPositionInformations(definition, rhsToken, errorToken, e.getMessage());
throw new PreParseException(newMessage);
} catch (de.be4.classicalb.core.parser.lexer.LexerException e) {
throw new PreParseException(determineNewErrorMessageWithCorrectedPositionInformationsWithoutToken(definition, rhsToken, e.getMessage()));
} catch (IOException e) {
throw new PreParseException(e.getMessage());
}
}
use of de.be4.classicalb.core.parser.exceptions.PreParseException in project probparsers by bendisposto.
the class PreParser method parse.
public void parse() throws PreParseException, IOException, BException, BCompoundException {
final PreLexer preLexer = new PreLexer(pushbackReader);
final Parser preParser = new Parser(preLexer);
Start rootNode = null;
try {
rootNode = preParser.parse();
} catch (final ParserException e) {
if (e.getToken() instanceof de.be4.classicalb.core.preparser.node.TDefinitions) {
final Token errorToken = e.getToken();
final String message = "[" + errorToken.getLine() + "," + errorToken.getPos() + "] " + "Clause 'DEFINITIONS' is used more than once";
throw new PreParseException(e.getToken(), message);
} else {
throw new PreParseException(e.getToken(), e.getLocalizedMessage());
}
} catch (final LexerException e) {
throw new PreParseException(e.getLocalizedMessage());
}
final DefinitionPreCollector collector = new DefinitionPreCollector();
rootNode.apply(collector);
evaluateDefinitionFiles(collector.getFileDefinitions());
List<Token> sortedDefinitionList = sortDefinitionsByTopologicalOrderAndCheckForCycles(collector.getDefinitions());
evaluateTypes(sortedDefinitionList, collector.getDefinitions());
}
use of de.be4.classicalb.core.parser.exceptions.PreParseException in project probparsers by bendisposto.
the class DefinitionFilesTest method testCircleReference.
/*
* test circles references between def files
*/
@Test
public void testCircleReference() throws Exception {
final String testMachine = "MACHINE Test\nDEFINITIONS \"DefFile3\"\nEND";
final BParser parser = new BParser("testcase");
try {
parser.parse(testMachine, false, this);
fail("Expected PreParseException missing");
} catch (final BCompoundException e) {
assertTrue(e.getCause() instanceof PreParseException);
}
}
use of de.be4.classicalb.core.parser.exceptions.PreParseException in project probparsers by bendisposto.
the class StringLiteralNotClosedTest method testStringLiteralNotClosedLongString.
@Test
public void testStringLiteralNotClosedLongString() {
final String testMachine = "MACHINE Test CONSTANTS the_string PROPERTIES the_string = \"not closed" + randomString(100) + "END";
try {
getTreeAsString(testMachine);
fail("Exception did not occur");
} catch (BCompoundException e) {
System.out.println(e.getCause());
assertTrue(e.getCause() instanceof PreParseException);
assertTrue(e.getLocalizedMessage().contains("Unknown token:"));
}
}
Aggregations