Search in sources :

Example 1 with ParseOptions

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

the class BParser method parse.

/**
 * Parses the input string.
 *
 * @param input
 *            The {@link String} to be parsed
 * @param debugOutput
 *            output debug messages on standard out?
 * @param contentProvider
 *            A {@link IFileContentProvider} that is able to load content of
 *            referenced files during the parsing process. The content
 *            provider is used for referenced definition files for example.
 * @return the root node of the AST
 * @throws BCompoundException
 *             The {@link BCompoundException} class stores all
 *             {@link BException}s occurred during the parsing process. The
 *             {@link BException} class stores the actual exception as
 *             delegate and forwards all method calls to it. So it is save
 *             for tools to just use this exception if they want to extract
 *             an error message. If the tools needs to extract additional
 *             information, such as a source code position or involved
 *             tokens respectively nodes, it needs to retrieve the delegate
 *             exception. The {@link BException} class offers a
 *             {@link BException#getCause()} method for this, which returns
 *             the delegate exception.
 *             <p>
 *             Internal exceptions:
 *             <ul>
 *             <li>{@link PreParseException}: This exception contains errors
 *             that occur during the preparsing. If possible it supplies a
 *             token, where the error occurred.</li>
 *             <li>{@link BLexerException}: If any error occurs in the
 *             generated or customized lexer a {@link LexerException} is
 *             thrown. Usually the lexer classes just throw a
 *             {@link LexerException}. But this class unfortunately does not
 *             contain any explicit information about the source code
 *             position where the error occurred. Using aspect-oriented
 *             programming we intercept the throwing of these exceptions to
 *             replace them by our own exception. In our own exception we
 *             provide the source code position of the last characters that
 *             were read from the input.</li>
 *             <li>{@link BParseException}: This exception is thrown in two
 *             situations. On the one hand if the parser throws a
 *             {@link ParserException} we convert it into a
 *             {@link BParseException}. On the other hand it can be thrown
 *             if any error is found during the AST transformations after
 *             the parser has finished.</li>
 *             <li>{@link CheckException}: If any problem occurs while
 *             performing semantic checks, a {@link CheckException} is
 *             thrown. We provide one or more nodes that are involved in the
 *             problem. For example, if we find duplicate machine clauses,
 *             we will list all occurrences in the exception.</li>
 *             </ul>
 */
public Start parse(final String input, final boolean debugOutput, final IFileContentProvider contentProvider) throws BCompoundException {
    final Reader reader = new StringReader(input);
    try {
        // PreParsing
        final DefinitionTypes defTypes = preParsing(debugOutput, reader, contentProvider, directory);
        /*
			 * The definition types are used in the lexer in order to replace an
			 * identifier token by a definition call token. This is required if
			 * the definition is a predicate because an identifier can not be
			 * parsed as a predicate. For example "... SELECT def THEN ... "
			 * would yield to a parse error. The lexer will replace the
			 * identifier token "def" by a TDefLiteralPredicate which will be
			 * excepted by the parser
			 * 
			 */
        defTypes.addAll(definitions.getTypes());
        /*
			 * Main parser
			 */
        final BLexer lexer = new BLexer(new PushbackReader(reader, BLexer.PUSHBACK_BUFFER_SIZE), defTypes);
        lexer.setParseOptions(parseOptions);
        SabbleCCBParser parser = new SabbleCCBParser(lexer);
        final Start rootNode = parser.parse();
        final List<BException> bExceptionList = new ArrayList<>();
        /*
			 * Collect available definition declarations. Needs to be done now
			 * cause they are needed by the following transformations.
			 */
        final DefinitionCollector collector = new DefinitionCollector(defTypes, this.definitions);
        collector.collectDefinitions(rootNode);
        List<CheckException> definitionsCollectorExceptions = collector.getExceptions();
        for (CheckException checkException : definitionsCollectorExceptions) {
            bExceptionList.add(new BException(getFileName(), checkException));
        }
        // perfom AST transformations that can't be done by SableCC
        try {
            applyAstTransformations(rootNode);
        } catch (CheckException e) {
            throw new BCompoundException(new BException(getFileName(), e));
        }
        // perform some semantic checks which are not done in the parser
        List<CheckException> checkExceptions = performSemanticChecks(rootNode);
        for (CheckException checkException : checkExceptions) {
            bExceptionList.add(new BException(getFileName(), checkException));
        }
        if (!bExceptionList.isEmpty()) {
            throw new BCompoundException(bExceptionList);
        }
        return rootNode;
    } catch (final LexerException e) {
        throw new BCompoundException(new BException(getFileName(), e));
    } catch (final BParseException e) {
        throw new BCompoundException(new BException(getFileName(), e));
    } catch (final IOException e) {
        throw new BCompoundException(new BException(getFileName(), e));
    } catch (final PreParseException e) {
        throw new BCompoundException(new BException(getFileName(), e));
    } catch (final ParserException e) {
        final Token token = e.getToken();
        String msg = getImprovedErrorMessageBasedOnTheErrorToken(token);
        if (msg == null) {
            msg = e.getLocalizedMessage();
        }
        final String realMsg = e.getRealMsg();
        throw new BCompoundException(new BException(getFileName(), new BParseException(token, msg, realMsg, e)));
    } catch (BException e) {
        throw new BCompoundException(e);
    }
}
Also used : DefinitionCollector(de.be4.classicalb.core.parser.analysis.checking.DefinitionCollector) ParserException(de.be4.classicalb.core.parser.parser.ParserException) Start(de.be4.classicalb.core.parser.node.Start) ArrayList(java.util.ArrayList) Reader(java.io.Reader) StringReader(java.io.StringReader) PushbackReader(java.io.PushbackReader) Token(de.be4.classicalb.core.parser.node.Token) IOException(java.io.IOException) PushbackReader(java.io.PushbackReader) StringReader(java.io.StringReader) LexerException(de.be4.classicalb.core.parser.lexer.LexerException)

Example 2 with ParseOptions

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

the class BParser method performSemanticChecks.

private List<CheckException> performSemanticChecks(final Start rootNode) {
    final List<CheckException> list = new ArrayList<>();
    final SemanticCheck[] checks = { new ClausesCheck(), new SemicolonCheck(), new IdentListCheck(), new DefinitionUsageCheck(getDefinitions()), new PrimedIdentifierCheck(), new ProverExpressionsCheck() };
    for (SemanticCheck check : checks) {
        check.setOptions(parseOptions);
        check.runChecks(rootNode);
        list.addAll(check.getCheckExceptions());
    }
    return list;
}
Also used : SemicolonCheck(de.be4.classicalb.core.parser.analysis.checking.SemicolonCheck) IdentListCheck(de.be4.classicalb.core.parser.analysis.checking.IdentListCheck) SemanticCheck(de.be4.classicalb.core.parser.analysis.checking.SemanticCheck) ArrayList(java.util.ArrayList) ProverExpressionsCheck(de.be4.classicalb.core.parser.analysis.checking.ProverExpressionsCheck) ClausesCheck(de.be4.classicalb.core.parser.analysis.checking.ClausesCheck) PrimedIdentifierCheck(de.be4.classicalb.core.parser.analysis.checking.PrimedIdentifierCheck) DefinitionUsageCheck(de.be4.classicalb.core.parser.analysis.checking.DefinitionUsageCheck)

Example 3 with ParseOptions

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

the class RulesParseUnit method parse.

public void parse() {
    if (this.bCompoundException != null) {
        return;
    }
    try {
        bParser = null;
        if (machineFile != null) {
            bParser = new BParser(machineFile.getPath());
            bParser.setDirectory(machineFile.getParentFile());
        } else {
            bParser = new BParser();
        }
        ParseOptions parseOptions = new ParseOptions();
        parseOptions.setGrammar(RulesGrammar.getInstance());
        bParser.setParseOptions(parseOptions);
        start = bParser.parse(content, debugOuput, new CachingDefinitionFileProvider());
        refFinder = new RulesReferencesFinder(machineFile, start);
        refFinder.findReferencedMachines();
        this.machineReferences = refFinder.getReferences();
        this.machineName = refFinder.getName();
        this.rulesMachineChecker = new RulesMachineChecker(machineFile, bParser.getFileName(), machineReferences, start);
        rulesMachineChecker.runChecks();
        this.operationList.addAll(rulesMachineChecker.getOperations());
    } catch (BCompoundException e) {
        // store parser exceptions
        this.bCompoundException = e;
    }
}
Also used : CachingDefinitionFileProvider(de.be4.classicalb.core.parser.CachingDefinitionFileProvider) ParseOptions(de.be4.classicalb.core.parser.ParseOptions) BParser(de.be4.classicalb.core.parser.BParser) BCompoundException(de.be4.classicalb.core.parser.exceptions.BCompoundException)

Example 4 with ParseOptions

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

the class PreParser method evaluateDefinitionFiles.

private void evaluateDefinitionFiles(final List<Token> list) throws PreParseException, BException, BCompoundException {
    IDefinitionFileProvider cache = null;
    if (contentProvider instanceof IDefinitionFileProvider) {
        cache = (IDefinitionFileProvider) contentProvider;
    }
    for (final Token fileNameToken : list) {
        final List<String> newDoneList = new ArrayList<String>(doneDefFiles);
        try {
            final String fileName = fileNameToken.getText();
            if (doneDefFiles.contains(fileName)) {
                StringBuilder sb = new StringBuilder();
                for (String string : doneDefFiles) {
                    sb.append(string).append(" -> ");
                }
                sb.append(fileName);
                throw new PreParseException(fileNameToken, "Cyclic references in definition files: " + sb.toString());
            }
            IDefinitions definitions;
            if (cache != null && cache.getDefinitions(fileName) != null) {
                definitions = cache.getDefinitions(fileName);
            } else {
                final String content = contentProvider.getFileContent(directory, fileName);
                newDoneList.add(fileName);
                final File file = contentProvider.getFile(directory, fileName);
                String filePath = fileName;
                if (file != null) {
                    filePath = file.getCanonicalPath();
                }
                final BParser parser = new BParser(filePath, parseOptions);
                parser.setDirectory(directory);
                parser.setDoneDefFiles(newDoneList);
                parser.setDefinitions(new Definitions(file));
                parser.parse(content, debugOutput, contentProvider);
                definitions = parser.getDefinitions();
                if (cache != null) {
                    cache.storeDefinition(fileName, definitions);
                }
            }
            defFileDefinitions.addDefinitions(definitions);
            definitionTypes.addAll(definitions.getTypes());
        } catch (final IOException e) {
            throw new PreParseException(fileNameToken, "Definition file cannot be read: " + e.getLocalizedMessage());
        } finally {
        }
    }
}
Also used : ArrayList(java.util.ArrayList) Token(de.be4.classicalb.core.preparser.node.Token) IOException(java.io.IOException) PreParseException(de.be4.classicalb.core.parser.exceptions.PreParseException) File(java.io.File)

Example 5 with ParseOptions

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

the class PreParser method determineDependencies.

private Map<String, Set<String>> determineDependencies(Set<String> definitionNames, Map<Token, Token> definitions) throws PreParseException {
    HashMap<String, Set<String>> dependencies = new HashMap<>();
    for (Entry<Token, Token> entry : definitions.entrySet()) {
        Token nameToken = entry.getKey();
        Token rhsToken = entry.getValue();
        // The FORMULA_PREFIX is needed to switch the lexer state from
        // section to normal. Note, that we do not parse the right hand side
        // of the definition here. Hence FORMULA_PREFIX has no further
        // meaning and substitutions can also be handled by the lexer.
        final Reader reader = new StringReader(BParser.FORMULA_PREFIX + "\n" + rhsToken.getText());
        final BLexer lexer = new BLexer(new PushbackReader(reader, BLexer.PUSHBACK_BUFFER_SIZE), new DefinitionTypes());
        lexer.setParseOptions(parseOptions);
        Set<String> set = new HashSet<>();
        de.be4.classicalb.core.parser.node.Token next = null;
        try {
            next = lexer.next();
            while (!(next instanceof EOF)) {
                if (next instanceof TIdentifierLiteral) {
                    TIdentifierLiteral id = (TIdentifierLiteral) next;
                    String name = id.getText();
                    if (definitionNames.contains(name)) {
                        set.add(name);
                    }
                }
                next = lexer.next();
            }
        } catch (IOException e) {
        } catch (BLexerException e) {
            de.be4.classicalb.core.parser.node.Token errorToken = e.getLastToken();
            final String newMessage = determineNewErrorMessageWithCorrectedPositionInformations(nameToken, rhsToken, errorToken, e.getMessage());
            throw new PreParseException(newMessage);
        } catch (de.be4.classicalb.core.parser.lexer.LexerException e) {
            final String newMessage = determineNewErrorMessageWithCorrectedPositionInformationsWithoutToken(nameToken, rhsToken, e.getMessage());
            throw new PreParseException(newMessage);
        }
        dependencies.put(nameToken.getText(), set);
    }
    return dependencies;
}
Also used : HashSet(java.util.HashSet) Set(java.util.Set) HashMap(java.util.HashMap) Reader(java.io.Reader) StringReader(java.io.StringReader) PushbackReader(java.io.PushbackReader) Token(de.be4.classicalb.core.preparser.node.Token) BLexerException(de.be4.classicalb.core.parser.exceptions.BLexerException) StringReader(java.io.StringReader) PreParseException(de.be4.classicalb.core.parser.exceptions.PreParseException) EOF(de.be4.classicalb.core.parser.node.EOF) HashSet(java.util.HashSet) IOException(java.io.IOException) TIdentifierLiteral(de.be4.classicalb.core.parser.node.TIdentifierLiteral) PushbackReader(java.io.PushbackReader)

Aggregations

IOException (java.io.IOException)4 ArrayList (java.util.ArrayList)4 PushbackReader (java.io.PushbackReader)3 Reader (java.io.Reader)3 StringReader (java.io.StringReader)3 PreParseException (de.be4.classicalb.core.parser.exceptions.PreParseException)2 LexerException (de.be4.classicalb.core.parser.lexer.LexerException)2 EOF (de.be4.classicalb.core.parser.node.EOF)2 Start (de.be4.classicalb.core.parser.node.Start)2 TIdentifierLiteral (de.be4.classicalb.core.parser.node.TIdentifierLiteral)2 Token (de.be4.classicalb.core.parser.node.Token)2 ParserException (de.be4.classicalb.core.parser.parser.ParserException)2 Token (de.be4.classicalb.core.preparser.node.Token)2 BParser (de.be4.classicalb.core.parser.BParser)1 CachingDefinitionFileProvider (de.be4.classicalb.core.parser.CachingDefinitionFileProvider)1 ParseOptions (de.be4.classicalb.core.parser.ParseOptions)1 ClausesCheck (de.be4.classicalb.core.parser.analysis.checking.ClausesCheck)1 DefinitionCollector (de.be4.classicalb.core.parser.analysis.checking.DefinitionCollector)1 DefinitionUsageCheck (de.be4.classicalb.core.parser.analysis.checking.DefinitionUsageCheck)1 IdentListCheck (de.be4.classicalb.core.parser.analysis.checking.IdentListCheck)1