All Downloads are FREE. Search and download functionalities are using the official Maven repository.

edu.hm.hafner.analysis.parser.MentorParser Maven / Gradle / Ivy

package edu.hm.hafner.analysis.parser;

import java.util.Optional;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import edu.hm.hafner.analysis.Issue;
import edu.hm.hafner.analysis.IssueBuilder;
import edu.hm.hafner.analysis.LookaheadParser;
import edu.hm.hafner.util.LookaheadStream;

/**
 * Parser for Mentor Graphics Modelsim/Questa Simulator.
 *
 * @author Derrick Gibelyou
 */
public class MentorParser extends LookaheadParser {
    public static final long serialVersionUID = 1L;

    /**
     * Matches the beginning of a Modelsim/Questa message "** [priority] : [The remainder of the message]".
     */
    private static final String MSG_REGEX = "\\*\\*\\s+(?[\\w \\(\\)]+):\\s+(?.*)";

    /**
     * The first capture group captures the message type such as "vlog-###" or "vsim-###".
     * The second group matches an optional filename in the form of filename.sv(line-number).
     * The third group matches the rest of the message.
     */
    private static final Pattern VSIM_PATTERN = Pattern.compile(
            "\\((?v\\w+-\\d+)\\)(?: (?\\S*)\\((?\\d+)\\):)? (?.*)");

    /**
     * The first capture group matches the filename
     * The second group matches the line number.
     */
    private static final Pattern VLOG_FILE_PATTERN = Pattern.compile(
            "(?\\S*)\\((?\\d+)\\):");

    /**
     * The first capture group matches the warning type such as "vlog-###" or "vsim-###".
     * The second group matches the rest of the message.
     */
    private static final Pattern VLOG_TYPE_PATTERN = Pattern.compile(
            "\\((?v\\w+-\\d+)\\) (?.*)");

    /**
     * The first capture group matches the timestamp for the message on the previous line.
     * The iteration is ignored.
     * \w* matches a word such as "module" or "protected".
     * The next capture group captures the path of the module.
     * The next capture groups capture the File name and Line number.
     */
    private static final Pattern TIME_FILE_PATTERN = Pattern.compile(
            "# {4}Time: (?\\d* \\ws)(?: {2}Iteration: \\d+)? {2}\\w*: (?.\\S*)(?: File: (?\\S+))?(?: Line: (?\\d+))?.*");

    /**
     * Creates a parser for MentorGraphics Modelsim/Questa logs.
     */
    public MentorParser() {
        super(MSG_REGEX);
    }

    @Override
    protected Optional createIssue(final Matcher matcher, final LookaheadStream lookahead,
                                          final IssueBuilder builder) {
        clearBuilder(builder);

        builder.guessSeverity(matcher.group("priority"));

        String message = matcher.group("message");
        if (message.contains("while parsing file")) {
            parseLongVlogMessage(lookahead, builder);
        }
        else if (message.contains("vlog-") || message.contains("vopt-")) {
            parseVlogMessage(builder, message);
        }
        else {
            parseVsimMessage(lookahead, builder, message);
        }

        return builder.buildOptional();
    }

    private void parseLongVlogMessage(final LookaheadStream lookahead, final IssueBuilder builder) {
        while (!lookahead.peekNext().startsWith("# ** at ")) {
            lookahead.next();
        }
        parseVlogMessage(builder, lookahead.next().substring(8));
    }

    private void parseVlogMessage(final IssueBuilder builder, final String message) {
        String parsedMessage = message;
        builder.setCategory("vlog");
        // If we can refine the message, the do.
        // Else just return what we got passed.
        Matcher vlog;
        vlog = VLOG_FILE_PATTERN.matcher(message);
        if (vlog.find()) {
            builder.setFileName(vlog.group("filename"));
            builder.setLineStart(vlog.group("line"));
        }
        vlog = VLOG_TYPE_PATTERN.matcher(message);
        if (vlog.find()) {
            builder.setCategory(vlog.group("category"));
            parsedMessage = vlog.group("message");
        }
        builder.setDescription("");
        builder.setMessage(parsedMessage);
    }

    private void parseVsimMessage(final LookaheadStream lookahead, final IssueBuilder builder, final String message) {
        builder.setDescription(parseSimTime(lookahead, builder));

        String parsedMessage = message;
        // If we can refine the message, the do.
        // Else just return what we got passed.
        Matcher vsim = VSIM_PATTERN.matcher(message);
        if (vsim.matches()) {
            builder.setCategory(vsim.group("category"));
            builder.setFileName(vsim.group("filename"));
            builder.setLineStart(vsim.group("line"));
            parsedMessage = vsim.group("message");
        }
        builder.setMessage(parsedMessage);
    }

    private String parseSimTime(final LookaheadStream lookahead, final IssueBuilder builder) {
        StringBuilder description = new StringBuilder();
        String timeLine = "";
        while (lookahead.hasNext()
                && lookahead.peekNext().startsWith("# ")
                && !lookahead.peekNext().startsWith("# **")) {
            timeLine = lookahead.next();
            if (timeLine.startsWith("#    Time:")) {
                break;
            }
            description.append("
"); description.append(timeLine); } Matcher tf = TIME_FILE_PATTERN.matcher(timeLine); if (tf.matches()) { builder.setModuleName(tf.group("module")); builder.setFileName(tf.group("filename")); builder.setLineStart(tf.group("line")); } return description.toString(); } private void clearBuilder(final IssueBuilder builder) { builder.setModuleName(null); builder.setFileName(null); builder.setLineStart(null); builder.setCategory("-"); } @Override protected boolean isLineInteresting(final String line) { return line.startsWith("# ** ") || line.startsWith("** "); } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy