Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
629 changes: 629 additions & 0 deletions ajcore.20250618.100528.040.txt

Large diffs are not rendered by default.

7 changes: 7 additions & 0 deletions eo-parser/src/main/antlr4/org/eolang/parser/Eo.g4
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,13 @@ object
// Ends on the next line
bound
: commentOptional (application | ((method | just) oname) EOL)
| errorBound
;

// Error production to handle malformed bound objects
// This specifically targets malformed attribute syntax like [x] +++ bad
errorBound
: commentOptional LSQ NAME* RSQ SPACE PLUS PLUS (~EOL)* EOL innersOrEol?
;

subMaster
Expand Down
2 changes: 1 addition & 1 deletion eo-parser/src/main/java/org/eolang/parser/DrProgram.java
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ public Iterator<Directive> iterator() {
.add("object")
.attr(
"noNamespaceSchemaLocation xsi http://www.w3.org/2001/XMLSchema-instance",
DrProgram.schema()
schema()
)
.attr("version", Manifests.read("EO-Version"))
.attr("revision", Manifests.read("EO-Revision"))
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
/*
* SPDX-FileCopyrightText: Copyright (c) 2016-2025 Objectionary.com
* SPDX-License-Identifier: MIT
*/
package org.eolang.parser;

import org.antlr.v4.runtime.DefaultErrorStrategy;
import org.antlr.v4.runtime.Parser;
import org.antlr.v4.runtime.RecognitionException;
import org.antlr.v4.runtime.Token;
import org.antlr.v4.runtime.TokenStream;

/**
* Custom error recovery strategy for EO parser.
* When encountering errors in object declarations, skip to the next
* object at the same indentation level to allow parsing to continue.
*
* @since 0.1
*/
final class EoErrorRecoveryStrategy extends DefaultErrorStrategy {

@Override
public void recover(
final Parser recognizer,
final RecognitionException exc
) {
final String rule = recognizer.getRuleInvocationStack().get(0);
final String[] names = recognizer.getRuleNames();
if (names[EoParser.RULE_bound].equals(rule)
|| names[EoParser.RULE_object].equals(rule)) {
skipToNextObjectAtSameLevel(recognizer);
} else {
super.recover(recognizer, exc);
}
}

/**
* Skip tokens until we find the start of the next object
* at the same indentation level.
* @param recognizer The parser
*/
private static void skipToNextObjectAtSameLevel(final Parser recognizer) {
final TokenStream tokens = recognizer.getInputStream();
int index = recognizer.getCurrentToken().getTokenIndex();
while (index < tokens.size()) {
final Token token = tokens.get(index);
if (token.getType() == Token.EOF) {
break;
}
if (token.getType() == EoParser.UNTAB) {
break;
}
if (token.getType() == EoParser.EOL && index + 1 < tokens.size()) {
final Token next = tokens.get(index + 1);
if (next.getType() == EoParser.LSQ) {
recognizer.getInputStream().seek(index);
return;
}
}
index = index + 1;
}
if (index < tokens.size()) {
recognizer.getInputStream().seek(index);
}
}
}
4 changes: 2 additions & 2 deletions eo-parser/src/main/java/org/eolang/parser/EoParserErrors.java
Original file line number Diff line number Diff line change
Expand Up @@ -70,10 +70,10 @@ public void syntaxError(
final String result;
final String underlined;
if (error instanceof NoViableAltException) {
result = EoParserErrors.impasse((Parser) recognizer);
result = impasse((Parser) recognizer);
underlined = this.underlined(symbol, line, position);
} else if (error instanceof InputMismatchException) {
result = EoParserErrors.mismatch((Parser) recognizer, msg);
result = mismatch((Parser) recognizer, msg);
underlined = this.underlined(symbol, line, position);
} else {
result = msg;
Expand Down
2 changes: 1 addition & 1 deletion eo-parser/src/main/java/org/eolang/parser/EoSyntax.java
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ public EoSyntax(final String ipt, final Train<Shift> transform) {
* @param ipt The EO program to parse
*/
public EoSyntax(final Input ipt) {
this(ipt, EoSyntax.CANONICAL);
this(ipt, CANONICAL);
}

/**
Expand Down
6 changes: 3 additions & 3 deletions eo-parser/src/main/java/org/eolang/parser/MsgUnderlined.java
Original file line number Diff line number Diff line change
Expand Up @@ -72,12 +72,12 @@ private String underline() {
if (this.origin.isEmpty() || this.length <= 0 || this.from >= this.origin.length()) {
result = "";
} else if (this.from < 0) {
result = MsgUnderlined.repeat("^", this.origin.length());
result = repeat("^", this.origin.length());
} else {
result = String.format(
"%s%s",
MsgUnderlined.repeat(" ", this.from),
MsgUnderlined.repeat("^", Math.min(this.length, this.origin.length()))
repeat(" ", this.from),
repeat("^", Math.min(this.length, this.origin.length()))
);
}
return result;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ final class ParsingError extends RuntimeException {
msg
).formatted(),
new MsgUnderlined(
ParsingError.line(ctx),
line(ctx),
ctx.getStart().getCharPositionInLine(),
ctx.getText().length()
).formatted()
Expand Down
2 changes: 1 addition & 1 deletion eo-parser/src/main/java/org/eolang/parser/PhiSyntax.java
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ public PhiSyntax(final Text input) {
* @param extra Extra directives to append
*/
public PhiSyntax(final Text inpt, final Iterable<Directive> extra) {
this(inpt, extra, PhiSyntax.CANONICAL);
this(inpt, extra, CANONICAL);
}

/**
Expand Down
18 changes: 9 additions & 9 deletions eo-parser/src/main/java/org/eolang/parser/StUnhex.java
Original file line number Diff line number Diff line change
Expand Up @@ -31,32 +31,32 @@ final class StUnhex extends StEnvelope {
static final Shift XNAV = new StSequence(
StUnhex.class.getSimpleName(),
new StXnav(
StUnhex.BYTES,
BYTES,
xnav -> xnav.node().setTextContent(
xnav.element("o").text().orElse("")
)
),
new StXnav(
StUnhex.elements("number"),
elements("number"),
xnav -> {
final double number = StUnhex.buffer(
StUnhex.undash(xnav.element("o").text().orElse(""))
final double number = buffer(
undash(xnav.element("o").text().orElse(""))
).getDouble();
final Node node = xnav.node();
if (!Double.isNaN(number) && !Double.isInfinite(number)) {
node.setTextContent(StUnhex.number(number));
node.setTextContent(number(number));
}
}
),
new StXnav(
StUnhex.elements("string"),
elements("string"),
xnav -> xnav.node().setTextContent(
String.format(
"\"%s\"",
StringEscapeUtils.escapeJava(
new String(
StUnhex.buffer(
StUnhex.undash(xnav.element("o").text().orElse(""))
buffer(
undash(xnav.element("o").text().orElse(""))
).array(),
StandardCharsets.UTF_8
)
Expand All @@ -70,7 +70,7 @@ final class StUnhex extends StEnvelope {
* Ctor.
*/
StUnhex() {
this(StUnhex.XNAV);
this(XNAV);
}

/**
Expand Down
10 changes: 5 additions & 5 deletions eo-parser/src/main/java/org/eolang/parser/StrictXmir.java
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ public StrictXmir(final XML before, final Path tmp) {
new Synced<>(
new Sticky<>(
() -> new StrictXML(
StrictXmir.reset(before, tmp)
reset(before, tmp)
)
)
)
Expand Down Expand Up @@ -158,7 +158,7 @@ private static XML reset(final XML xml, final Path tmp) {
if (before.startsWith("http")) {
after = String.format(
"file:///%s",
StrictXmir.fetch(
fetch(
before,
tmp.resolve(
before.substring(before.lastIndexOf('/') + 1)
Expand Down Expand Up @@ -190,10 +190,10 @@ private static XML reset(final XML xml, final Path tmp) {
*/
private static File fetch(final String uri, final Path path, final Path tmp) {
final File ret;
if (StrictXmir.MINE.equals(uri)) {
ret = StrictXmir.copied(uri, path, tmp);
if (MINE.equals(uri)) {
ret = copied(uri, path, tmp);
} else {
ret = StrictXmir.downloaded(uri, path, tmp);
ret = downloaded(uri, path, tmp);
}
return ret;
}
Expand Down
2 changes: 1 addition & 1 deletion eo-parser/src/main/java/org/eolang/parser/TrStepped.java
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ final class TrStepped extends TrEnvelope {
* @param train Original train
*/
TrStepped(final Train<Shift> train) {
this(train, TrStepped.STEPPED);
this(train, STEPPED);
}

/**
Expand Down
12 changes: 11 additions & 1 deletion eo-parser/src/main/java/org/eolang/parser/XeEoListener.java
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,16 @@ public void exitBound(final EoParser.BoundContext ctx) {
// Nothing here
}

@Override
public void enterErrorBound(final EoParser.ErrorBoundContext ctx) {
// Nothing here
}

@Override
public void exitErrorBound(final EoParser.ErrorBoundContext ctx) {
// Nothing here
}

@Override
public void enterSubMaster(final EoParser.SubMasterContext ctx) {
// Nothing here
Expand Down Expand Up @@ -954,7 +964,7 @@ public void enterData(final EoParser.DataContext ctx) {
final int indent = ctx.getStart().getCharPositionInLine();
data = new BytesToHex(
StringEscapeUtils.unescapeJava(
XeEoListener.trimMargin(text, indent)
trimMargin(text, indent)
).getBytes(StandardCharsets.UTF_8)
);
}
Expand Down
14 changes: 7 additions & 7 deletions eo-parser/src/main/java/org/eolang/parser/XePhiListener.java
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ public void enterFormation(final PhiParser.FormationContext ctx) {
@Override
public void exitFormation(final PhiParser.FormationContext ctx) {
this.properties.pop();
if (!this.properties.empty() && !XePhiListener.hasLambdaPackage(ctx.bindings())) {
if (!this.properties.empty() && !hasLambdaPackage(ctx.bindings())) {
this.objects().leave();
}
}
Expand Down Expand Up @@ -202,15 +202,15 @@ public void exitScoped(final PhiParser.ScopedContext ctx) {
@Override
public void enterBindings(final PhiParser.BindingsContext ctx) {
this.anames.push(new HashSet<>());
if (XePhiListener.hasLambdaPackage(ctx)) {
if (hasLambdaPackage(ctx)) {
this.packages.add(this.attributes.peek());
this.objs.add(new Objects());
}
}

@Override
public void exitBindings(final PhiParser.BindingsContext ctx) {
if (XePhiListener.hasLambdaPackage(ctx)) {
if (hasLambdaPackage(ctx)) {
this.objs.poll();
}
this.anames.pop();
Expand Down Expand Up @@ -303,7 +303,7 @@ public void exitAttribute(final PhiParser.AttributeContext ctx) {
public void enterFullAttribute(final PhiParser.FullAttributeContext ctx) {
if (ctx.attribute() == null) {
this.attributes.push(
String.format("%s%s", XePhiListener.ALPHA, ctx.getText().substring(1))
String.format("%s%s", ALPHA, ctx.getText().substring(1))
);
}
}
Expand Down Expand Up @@ -346,7 +346,7 @@ public void exitDeltaBinding(final PhiParser.DeltaBindingContext ctx) {

@Override
public void enterLambdaBinding(final PhiParser.LambdaBindingContext ctx) {
if (!XePhiListener.LAMBDA_PACKAGE.equals(ctx.FUNCTION().getText())) {
if (!LAMBDA_PACKAGE.equals(ctx.FUNCTION().getText())) {
this.objects().start(ctx).prop("name", "λ").leave();
this.checkDuplicates(ctx, "λ");
}
Expand Down Expand Up @@ -395,7 +395,7 @@ public void enterJustObject(final PhiParser.JustObjectContext ctx) {
final int index = this.alphas.peek();
this.alphas.pop();
this.alphas.push(index + 1);
this.attributes.push(String.format("%s%d", XePhiListener.ALPHA, index));
this.attributes.push(String.format("%s%d", ALPHA, index));
}

@Override
Expand Down Expand Up @@ -541,7 +541,7 @@ private static boolean hasLambdaPackage(final PhiParser.BindingsContext ctx) {
context -> context.lambdaBinding() != null && context.lambdaBinding()
.FUNCTION()
.getText()
.equals(XePhiListener.LAMBDA_PACKAGE)
.equals(LAMBDA_PACKAGE)
);
}

Expand Down
4 changes: 2 additions & 2 deletions eo-parser/src/main/java/org/eolang/parser/Xmir.java
Original file line number Diff line number Diff line change
Expand Up @@ -134,15 +134,15 @@ public Collection<SAXParseException> validate(final XML xsd) {
* @return EO representation as {@link String}
*/
public String toEO() {
return this.converted(Xmir.FOR_EO, "eo");
return this.converted(FOR_EO, "eo");
}

/**
* Converts XMIR to PHI.
* @return PHI representation as {@link String}
*/
public String toPhi() {
return this.converted(Xmir.FOR_PHI, "phi");
return this.converted(FOR_PHI, "phi");
}

/**
Expand Down
Loading
Loading