Search in sources :

Example 1 with Definitions

use of de.be4.classicalb.core.parser.Definitions in project probparsers by bendisposto.

the class MachineContext method caseADefinitionsMachineClause.

/**
 * Definitions
 */
@Override
public void caseADefinitionsMachineClause(ADefinitionsMachineClause node) {
    definitionMachineClause = node;
    DefinitionsSorter.sortDefinitions(node);
    List<PDefinition> copy = node.getDefinitions();
    /*
		 * The definitions are not in a predefined order. In particular
		 * definitions can depend on each other. First all definitions are added
		 * to the definitions context table. Then all definitions are visited.
		 */
    Collection<PDefinition> definitionsToRemove = new HashSet<PDefinition>();
    for (PDefinition e : copy) {
        if (e instanceof AExpressionDefinitionDefinition) {
            AExpressionDefinitionDefinition def = (AExpressionDefinitionDefinition) e;
            String name = def.getName().getText();
            if (name.startsWith("ASSERT_LTL")) {
                LTLFormulaVisitor visitor = new LTLFormulaVisitor(name, this);
                visitor.parseDefinition(def);
                this.ltlVisitors.add(visitor);
                definitionsToRemove.add(def);
            } else if (name.startsWith("ANIMATION_")) {
                definitionsToRemove.add(def);
            }
            evalDefinitionName(((AExpressionDefinitionDefinition) e).getName().getText().toString(), e);
        } else if (e instanceof APredicateDefinitionDefinition) {
            evalDefinitionName(((APredicateDefinitionDefinition) e).getName().getText().toString(), e);
        } else if (e instanceof ASubstitutionDefinitionDefinition) {
            evalDefinitionName(((ASubstitutionDefinitionDefinition) e).getName().getText().toString(), e);
        }
    }
    /*
		 * At this point all LTL definitions (ASSERT_LTL) are removed. LTL
		 * formulas are stored in the Arraylist {@value #ltlVisitors}.
		 */
    copy.removeAll(definitionsToRemove);
    this.contextTable = new ArrayList<LinkedHashMap<String, Node>>();
    ArrayList<MachineContext> list = lookupReferencedMachines();
    for (int i = 0; i < list.size(); i++) {
        MachineContext s = list.get(i);
        contextTable.add(s.getDeferredSets());
        contextTable.add(s.getEnumeratedSets());
        contextTable.add(s.getEnumValues());
        contextTable.add(s.getConstants());
        contextTable.add(s.getVariables());
        contextTable.add(s.getDefinitions());
    }
    for (PDefinition e : copy) {
        e.apply(this);
    }
}
Also used : APredicateDefinitionDefinition(de.be4.classicalb.core.parser.node.APredicateDefinitionDefinition) ASubstitutionDefinitionDefinition(de.be4.classicalb.core.parser.node.ASubstitutionDefinitionDefinition) LinkedHashMap(java.util.LinkedHashMap) PDefinition(de.be4.classicalb.core.parser.node.PDefinition) AExpressionDefinitionDefinition(de.be4.classicalb.core.parser.node.AExpressionDefinitionDefinition) HashSet(java.util.HashSet)

Example 2 with Definitions

use of de.be4.classicalb.core.parser.Definitions in project probparsers by bendisposto.

the class ASTBuilder method addToStringDefinition.

public static void addToStringDefinition(IDefinitions definitions) {
    if (definitions.containsDefinition(TO_STRING)) {
        return;
    }
    /*-
		 * TO_STRING(S) == "0"; 
		 * EXTERNAL_FUNCTION_TO_STRING(X) == X -->STRING;
		 */
    AExpressionDefinitionDefinition toStringDef = new AExpressionDefinitionDefinition();
    toStringDef.setName(new TIdentifierLiteral(TO_STRING));
    toStringDef.setParameters(createIdentifierList("S"));
    toStringDef.setRhs(new AStringExpression(new TStringLiteral("0")));
    definitions.addDefinition(toStringDef, IDefinitions.Type.Expression);
    AExpressionDefinitionDefinition toStringTypeDef = new AExpressionDefinitionDefinition();
    toStringTypeDef.setName(new TIdentifierLiteral("EXTERNAL_FUNCTION_TO_STRING"));
    toStringTypeDef.setParameters(createIdentifierList("X"));
    toStringTypeDef.setRhs(new ATotalFunctionExpression(createIdentifier("X"), new AStringSetExpression()));
    definitions.addDefinition(toStringTypeDef, IDefinitions.Type.Expression);
}
Also used : AStringSetExpression(de.be4.classicalb.core.parser.node.AStringSetExpression) AExpressionDefinitionDefinition(de.be4.classicalb.core.parser.node.AExpressionDefinitionDefinition) AStringExpression(de.be4.classicalb.core.parser.node.AStringExpression) TStringLiteral(de.be4.classicalb.core.parser.node.TStringLiteral) TIdentifierLiteral(de.be4.classicalb.core.parser.node.TIdentifierLiteral) ATotalFunctionExpression(de.be4.classicalb.core.parser.node.ATotalFunctionExpression)

Example 3 with Definitions

use of de.be4.classicalb.core.parser.Definitions 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;
    }
}
Also used : HashSet(java.util.HashSet) Set(java.util.Set) HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) Token(de.be4.classicalb.core.preparser.node.Token) PreParseException(de.be4.classicalb.core.parser.exceptions.PreParseException) HashSet(java.util.HashSet)

Example 4 with Definitions

use of de.be4.classicalb.core.parser.Definitions 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());
}
Also used : ParserException(de.be4.classicalb.core.preparser.parser.ParserException) Start(de.be4.classicalb.core.preparser.node.Start) Token(de.be4.classicalb.core.preparser.node.Token) DefinitionPreCollector(de.be4.classicalb.core.parser.analysis.checking.DefinitionPreCollector) Parser(de.be4.classicalb.core.preparser.parser.Parser) PreParseException(de.be4.classicalb.core.parser.exceptions.PreParseException) BLexerException(de.be4.classicalb.core.parser.exceptions.BLexerException) LexerException(de.be4.classicalb.core.preparser.lexer.LexerException)

Example 5 with Definitions

use of de.be4.classicalb.core.parser.Definitions in project probparsers by bendisposto.

the class RecursiveMachineLoader method recursivlyLoadMachine.

private void recursivlyLoadMachine(final File machineFile, final Start currentAst, final List<String> ancestors, final boolean isMain, File directory, final IDefinitions definitions) throws BCompoundException {
    // make a copy of the referencing machines
    List<String> newAncestors = new ArrayList<>(ancestors);
    ReferencedMachines refMachines = new ReferencedMachines(machineFile, currentAst, parsingBehaviour.isMachineNameMustMatchFileName());
    try {
        refMachines.findReferencedMachines();
    } catch (BException e) {
        throw new BCompoundException(e);
    }
    final String name = refMachines.getName();
    if (name == null) {
        /*
			 * the parsed file is a definition file, hence the name of the
			 * machine is null
			 */
        throw new BCompoundException(new BException(machineFile.getName(), "Expecting a B machine but was a definition file in file: '" + machineFile.getName() + "\'", null));
    }
    machineFilesLoaded.add(machineFile);
    final int fileNumber = machineFilesLoaded.indexOf(machineFile) + 1;
    getNodeIdMapping().assignIdentifiers(fileNumber, currentAst);
    definitions.assignIdsToNodes(getNodeIdMapping(), machineFilesLoaded);
    injectDefinitions(currentAst, definitions);
    getParsedMachines().put(name, currentAst);
    parsedFiles.put(name, machineFile);
    if (name != null) {
        newAncestors.add(name);
    }
    if (isMain) {
        main = name;
    }
    final Set<String> referencesSet = refMachines.getSetOfReferencedMachines();
    try {
        checkForCycles(newAncestors, referencesSet);
    } catch (BException e) {
        throw new BCompoundException(e);
    }
    final List<MachineReference> references = refMachines.getReferences();
    for (final MachineReference refMachine : references) {
        try {
            final String filePragma = refMachine.getPath();
            File file = null;
            if (filePragma == null) {
                file = lookupFile(directory, refMachine, newAncestors, refMachines.getPathList());
            } else {
                File p = new File(filePragma);
                if (p.isAbsolute()) {
                    file = p;
                } else {
                    file = new File(directory, filePragma);
                }
            }
            if (file.exists() && parsedFiles.containsKey(refMachine.getName()) && !parsedFiles.get(refMachine.getName()).getCanonicalPath().equals(file.getCanonicalPath())) {
                final String message = "Two files with the same name are referenced:\n" + parsedFiles.get(refMachine.getName()).getCanonicalPath() + "\n" + file.getCanonicalPath();
                throw new BException(machineFile.getCanonicalPath(), new CheckException(message, refMachine.getNode()));
            }
            if (!getParsedMachines().containsKey(refMachine.getName())) {
                try {
                    loadMachine(newAncestors, file);
                } catch (IOException e) {
                    throw new BException(machineFile.getCanonicalPath(), new CheckException(e.getMessage(), refMachine.getNode(), e));
                }
            }
        } catch (final BException e) {
            // we do not longer wrap a B Exception in a B Exception
            throw new BCompoundException(e);
        } catch (final IOException e) {
            throw new BCompoundException(new BException(machineFile.getAbsolutePath(), e));
        } catch (final CheckException e) {
            throw new BCompoundException(new BException(machineFile.getAbsolutePath(), e));
        }
    }
}
Also used : CheckException(de.be4.classicalb.core.parser.exceptions.CheckException) ArrayList(java.util.ArrayList) IOException(java.io.IOException) BException(de.be4.classicalb.core.parser.exceptions.BException) File(java.io.File) BCompoundException(de.be4.classicalb.core.parser.exceptions.BCompoundException)

Aggregations

Test (org.junit.Test)19 Ast2String (util.Ast2String)17 BCompoundException (de.be4.classicalb.core.parser.exceptions.BCompoundException)16 BParser (de.be4.classicalb.core.parser.BParser)6 Token (de.be4.classicalb.core.preparser.node.Token)6 PreParseException (de.be4.classicalb.core.parser.exceptions.PreParseException)5 AExpressionDefinitionDefinition (de.be4.classicalb.core.parser.node.AExpressionDefinitionDefinition)5 IDefinitions (de.be4.classicalb.core.parser.IDefinitions)4 BLexerException (de.be4.classicalb.core.parser.exceptions.BLexerException)4 HashSet (java.util.HashSet)4 Definitions (de.be4.classicalb.core.parser.Definitions)3 Start (de.be4.classicalb.core.parser.node.Start)3 TIdentifierLiteral (de.be4.classicalb.core.parser.node.TIdentifierLiteral)3 File (java.io.File)3 IOException (java.io.IOException)3 ArrayList (java.util.ArrayList)3 CheckException (de.be4.classicalb.core.parser.exceptions.CheckException)2 AIdentifierExpression (de.be4.classicalb.core.parser.node.AIdentifierExpression)2 APredicateDefinitionDefinition (de.be4.classicalb.core.parser.node.APredicateDefinitionDefinition)2 ASubstitutionDefinitionDefinition (de.be4.classicalb.core.parser.node.ASubstitutionDefinitionDefinition)2