Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(#3706): Identify a Rule Where an Error Occurred #3741

Merged
merged 9 commits into from
Dec 23, 2024
41 changes: 33 additions & 8 deletions eo-parser/src/main/java/org/eolang/parser/ParsingErrors.java
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,12 @@
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import org.antlr.v4.runtime.BaseErrorListener;
import org.antlr.v4.runtime.InputMismatchException;
import org.antlr.v4.runtime.NoViableAltException;
import org.antlr.v4.runtime.Parser;
import org.antlr.v4.runtime.RecognitionException;
import org.antlr.v4.runtime.Recognizer;
import org.antlr.v4.runtime.Token;
Expand All @@ -43,6 +46,10 @@
* Accumulates all parsing errors.
*
* @since 0.30.0
* @todo #3706:30min Split {@link ParsingErrors} into two classes.
* Currently we use the same {@link ParsingErrors} class to accumulate all the parsing errors
* despite their origin. This class should be split into two classes: one for parsing errors
* {@link ParserErrors} and another for lexer errors {@link LexerErrors}.
*/
final class ParsingErrors extends BaseErrorListener implements Iterable<Directive> {

Expand Down Expand Up @@ -83,19 +90,28 @@ public void syntaxError(
final String msg,
final RecognitionException error
) {
// @checkstyle MethodBodyCommentsCheck (20 lines)
// @todo #3332:30min Add more specific error messages.
// Currently we write just "error: no viable alternative at input" for all errors.
// It's better to use 'Recognizer<?, ?> recognizer' parameter of the current method
// to retrieve more specific error messages.
if (error instanceof NoViableAltException) {
if (error instanceof NoViableAltException || error instanceof InputMismatchException) {
final Token token = (Token) symbol;
final Parser parser = (Parser) recognizer;
final String rule = parser.getRuleInvocationStack().get(0);
final String[] names = parser.getRuleNames();
final String detailed;
if (names[EoParser.RULE_objects].equals(rule)) {
detailed = "Invalid object declaration";
} else if (names[EoParser.RULE_metas].equals(rule)) {
detailed = "Invalid meta declaration";
} else if (names[EoParser.RULE_program].equals(rule)) {
detailed = "Invalid program declaration";
} else {
detailed = "no viable alternative at input";
}
this.errors.add(
new ParsingException(
String.format(
"[%d:%d] %s:%n%s",
"[%d:%d] %s: %s:%n%s",
line, position,
"error: no viable alternative at input",
"error",
detailed,
new UnderlinedMessage(
this.line(line).orElse("EOF"),
position,
Expand All @@ -106,6 +122,15 @@ public void syntaxError(
line
)
);
} else if (Objects.isNull(error)) {
this.errors.add(
new ParsingException(
String.format(
"[%d:%d] %s: %s", line, position, "error", msg
),
line
)
);
} else {
this.errors.add(
new ParsingException(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,15 @@ public final class ParsingException extends RuntimeException {
*/
private final int place;

/**
* Ctor.
* @param msg Message
* @param line The place
*/
public ParsingException(final String msg, final int line) {
this(msg, null, line);
}

/**
* Ctor.
* @param msg Message
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -264,7 +264,7 @@ void checksTypoPacks(final String yaml) {
);
Assumptions.assumeTrue(story.map().get("skip") == null);
MatcherAssert.assertThat(
EoIndentLexerTest.TO_ADD_MESSAGE,
"We expect the error with correct line number was found",
XhtmlMatchers.xhtml(story.after().toString()),
XhtmlMatchers.hasXPaths("/program/errors/error/@line")
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
---
line: 2
message: >-
[2:4] error: no viable alternative at input:
[2:4] error: Invalid object declaration:
y:^
^
input: |
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,11 @@
# SOFTWARE.
---
line: 4
# @todo #3706:30min Add exact location of the error in the message.
# This message is already quite clear, but it would be better if it included
# the exact location of the error.
message: |-
Object binding can't be negative
input: |
# No comments
[] > foo
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,10 @@
# SOFTWARE.
---
line: 2
message: |-
[2:7] error: Invalid object declaration:
[] > a [] > b [] > c [] > d hello world
^
input: |
# No comments
[] > a [] > b [] > c [] > d hello world
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,12 @@
# SOFTWARE.
---
line: 5
# @todo #3706:30min The error message doesn't highlight the exact position of the
# comment. The error message should be updated to point to the exact position
# of the comment.
message: |
[5:12] error: Invalid object declaration:
sprintwf
input: |
# No comments
[args] > app
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,12 @@
# SOFTWARE.
---
line: 4
# @todo #3706:30min Cryptic error message is returned
# Cryptic error message is returned when there are two empty lines between metas.
# The error message should be more informative and should highlight the exact location
# of the error.
message: |-
[4:0] error: extraneous input '\n' expecting {COMMENTARY, 'Q', 'QQ', '*', '$', '[', '(', '@', '^', BYTES, STRING, INT, FLOAT, HEX, NAME, TEXT}
input: |
# No comments.
[args] > one
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,10 @@
# SOFTWARE.
---
line: 1
message: |-
[1:10] error: Invalid meta declaration:
+meta with spaces
^
input: |
+meta with spaces

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,10 @@
# SOFTWARE.
---
line: 3
message: |-
[3:0] error: Invalid object declaration:
+meta other
^^^^^^^^^^
input: |
+meta smth

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,10 @@
# SOFTWARE.
---
line: 3
message: |-
[3:0] error: Invalid meta declaration:
[] > main
^
input: |
+meta smth
+meta other
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,10 @@
# SOFTWARE.
---
line: 4
message: |-
[4:-1] error: Invalid program declaration:
[] > inner
^^^^^^^^^^^^
input: |
# No comments.
[] > test /int
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,10 @@
# SOFTWARE.
---
line: 3
message: |-
[3:-1] error: Invalid program declaration:
EOF
^^^
input: |
1.add 1 > x
(1.add 1) > y
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,15 @@
# SOFTWARE.
---
line: 3
# @todo #3706:30min Unreadable error message if program declaration is invalid.
# Improve error message for the case when a program declaration is invalid.
# The error message should be more informative and should point to the exact
# place in the input where the error occurred. Moreover it should be clear
# what to do to fix the error. 'simple-application-named.yaml' has the same issue.
message: |-
[3:-1] error: Invalid program declaration:
EOF
^^^
input: |
1.add 1 > x
(1.add 1)
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
---
line: 5
message: >-
[5:2] error: no viable alternative at input:
[5:2] error: Invalid object declaration:
*
^
input: |
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,10 @@
# SOFTWARE.
---
line: 2
message: |-
[2:0] error: Invalid program declaration:
.z
^
input: |
x y
.z
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,10 @@
# SOFTWARE.
---
line: 2
message: |-
[2:0] error: Invalid program declaration:
.z
^
input: |
x.y
.z
Loading