001/*
002 * Copyright 2020  nils.hoffmann.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *      http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016package de.isas.lipidomics.palinom.sumformula;
017
018import de.isas.lipidomics.domain.ElementTable;
019import de.isas.lipidomics.palinom.SumFormulaLexer;
020import de.isas.lipidomics.palinom.SumFormulaParser;
021import de.isas.lipidomics.palinom.SyntaxErrorListener;
022import de.isas.lipidomics.palinom.VisitorParser;
023import de.isas.lipidomics.palinom.exceptions.ParsingException;
024import lombok.extern.slf4j.Slf4j;
025import org.antlr.v4.runtime.CharStream;
026import org.antlr.v4.runtime.CharStreams;
027import org.antlr.v4.runtime.CommonTokenStream;
028import org.antlr.v4.runtime.RecognitionException;
029import org.antlr.v4.runtime.TokenStream;
030import org.antlr.v4.runtime.misc.ParseCancellationException;
031
032/**
033 * Parser implementation for the SumFormula grammar.
034 *
035 * @author nils.hoffmann
036 */
037@Slf4j
038public class SumFormulaVisitorParser implements VisitorParser<ElementTable> {
039
040    @Override
041    public ElementTable parse(String sumFormula, SyntaxErrorListener listener) throws ParsingException {
042        return parseWithGrammar(sumFormula, listener);
043    }
044
045    private ElementTable parseWithGrammar(String sumFormula, SyntaxErrorListener listener) throws ParsingException, RecognitionException {
046        CharStream charStream = CharStreams.fromString(sumFormula);
047        SumFormulaLexer lexer = new SumFormulaLexer(charStream);
048        TokenStream tokens = new CommonTokenStream(lexer);
049        log.info("Parsing sum formula: {}", sumFormula);
050        SumFormulaParser parser = new SumFormulaParser(tokens);
051        prepare(parser, lexer, listener);
052        try {
053            SumFormulaParser.MoleculeContext context = parser.molecule();
054            if (parser.getNumberOfSyntaxErrors() > 0) {
055                throw new ParsingException("Parsing of " + sumFormula + " failed with " + parser.getNumberOfSyntaxErrors() + " syntax errors!\n" + listener.getErrorString());
056            }
057            SumFormulaVisitorImpl lipidVisitor = new SumFormulaVisitorImpl();
058            return lipidVisitor.visit(context);
059        } catch (ParseCancellationException pce) {
060            throw new ParsingException("Parsing of " + sumFormula + " failed with " + parser.getNumberOfSyntaxErrors() + " syntax errors!\n" + listener.getErrorString());
061        }
062    }
063}