forked from jenkinsci/analysis-model
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathMentorParser.java
163 lines (141 loc) · 5.92 KB
/
MentorParser.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
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+(?<priority>[\\w \\(\\)]+):\\s+(?<message>.*)";
/**
* 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(
"\\((?<category>v\\w+-\\d+)\\)(?: (?<filename>\\S*)\\((?<line>\\d+)\\):)? (?<message>.*)");
/**
* The first capture group matches the filename
* The second group matches the line number.
*/
private static final Pattern VLOG_FILE_PATTERN = Pattern.compile(
"(?<filename>\\S*)\\((?<line>\\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(
"\\((?<category>v\\w+-\\d+)\\) (?<message>.*)");
/**
* 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: (?<simtime>\\d* \\ws)(?: {2}Iteration: \\d+)? {2}\\w*: (?<module>.\\S*)(?: File: (?<filename>\\S+))?(?: Line: (?<line>\\d+))?.*");
/**
* Construct a parser for MentorGraphics Modelsim/Questa logs.
*/
public MentorParser() {
super(MSG_REGEX);
}
@Override
protected Optional<Issue> 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("<br>");
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("** ");
}
}