diff --git a/eo-maven-plugin/README.md b/eo-maven-plugin/README.md index 21301692db..1ad15c25ac 100644 --- a/eo-maven-plugin/README.md +++ b/eo-maven-plugin/README.md @@ -82,7 +82,7 @@ binary code consists of a few high-level steps, which must be done one after another: * **Parsing**. - It's done by the `org.eolang.parser.Syntax` class in the `eo-parser` module. It takes + It's done by the `org.eolang.parser.EoSyntax` class in the `eo-parser` module. It takes the source code in a plain text format and parses into XML document, using [ANTLR4](https://www.antlr.org/) and [Xembly](https://www.xembly.org). The output of the parser you can find in the `target/eo/parse` directory. diff --git a/eo-maven-plugin/src/main/java/org/eolang/maven/ParseMojo.java b/eo-maven-plugin/src/main/java/org/eolang/maven/ParseMojo.java index d932fcfe32..af19bdf09f 100644 --- a/eo-maven-plugin/src/main/java/org/eolang/maven/ParseMojo.java +++ b/eo-maven-plugin/src/main/java/org/eolang/maven/ParseMojo.java @@ -26,7 +26,6 @@ import com.jcabi.log.Logger; import com.jcabi.xml.XML; import com.jcabi.xml.XMLDocument; -import java.io.ByteArrayOutputStream; import java.io.IOException; import java.nio.file.Path; import java.util.List; @@ -38,7 +37,6 @@ import org.cactoos.Scalar; import org.cactoos.experimental.Threads; import org.cactoos.io.InputOf; -import org.cactoos.io.OutputTo; import org.cactoos.iterable.Filtered; import org.cactoos.iterable.Mapped; import org.cactoos.number.SumOf; @@ -48,7 +46,7 @@ import org.eolang.maven.footprint.FtDefault; import org.eolang.maven.tojos.ForeignTojo; import org.eolang.maven.util.Rel; -import org.eolang.parser.Syntax; +import org.eolang.parser.EoSyntax; import org.xembly.Directives; import org.xembly.Xembler; @@ -154,19 +152,18 @@ private void parse(final ForeignTojo tojo) throws IOException { name, "xmir", () -> { - final ByteArrayOutputStream baos = new ByteArrayOutputStream(); - new Syntax( - name, - new InputOf(source), - new OutputTo(baos) - ).parse(); final String parsed = new XMLDocument( new Xembler( new Directives().xpath("/program").attr( "source", source.toAbsolutePath() ) - ).applyQuietly(new XMLDocument(baos.toByteArray()).node()) + ).applyQuietly( + new EoSyntax( + name, + new InputOf(source) + ).parsed().node() + ) ).toString(); Logger.debug( this, diff --git a/eo-maven-plugin/src/main/java/org/eolang/maven/UnphiMojo.java b/eo-maven-plugin/src/main/java/org/eolang/maven/UnphiMojo.java new file mode 100644 index 0000000000..219fe01648 --- /dev/null +++ b/eo-maven-plugin/src/main/java/org/eolang/maven/UnphiMojo.java @@ -0,0 +1,108 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2016-2023 Objectionary.com + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package org.eolang.maven; + +import com.jcabi.log.Logger; +import java.io.File; +import java.nio.file.Path; +import java.nio.file.Paths; +import org.apache.maven.plugins.annotations.LifecyclePhase; +import org.apache.maven.plugins.annotations.Mojo; +import org.apache.maven.plugins.annotations.Parameter; +import org.cactoos.experimental.Threads; +import org.cactoos.iterable.Mapped; +import org.cactoos.number.SumOf; +import org.cactoos.text.TextOf; +import org.eolang.maven.util.HmBase; +import org.eolang.maven.util.Home; +import org.eolang.maven.util.Walk; +import org.eolang.parser.PhiSyntax; + +/** + * Read PHI files and parse them to the XMIR. + * @since 0.34.0 + */ +@Mojo( + name = "phi-to-xmir", + defaultPhase = LifecyclePhase.PROCESS_SOURCES, + threadSafe = true +) +public final class UnphiMojo extends SafeMojo { + /** + * The directory where to take phi files for parsing from. + * @checkstyle MemberNameCheck (10 lines) + */ + @Parameter( + property = "unphiInputDir", + required = true, + defaultValue = "${project.build.directory}/eo/phi" + ) + private File unphiInputDir; + + /** + * The directory where to save xmir files to. + * @checkstyle MemberNameCheck (10 lines) + */ + @Parameter( + property = "unphiOutputDir", + required = true, + defaultValue = "${project.build.directory}/eo/1-parse" + ) + private File unphiOutputDir; + + @Override + public void exec() { + final Home home = new HmBase(this.unphiOutputDir); + final int count = new SumOf( + new Threads<>( + Runtime.getRuntime().availableProcessors(), + new Mapped<>( + phi -> () -> { + final Path relative = Paths.get( + this.unphiInputDir.toPath().relativize(phi).toString().replace( + String.format(".%s", PhiMojo.EXT), + String.format(".%s", TranspileMojo.EXT) + ) + ); + home.save( + new PhiSyntax( + phi.getFileName().toString(), + new TextOf(phi) + ).parsed().toString(), + relative + ); + Logger.info( + this, + "Parsed to xmir: %s -> %s", + phi, this.unphiOutputDir.toPath().resolve(relative) + ); + return 1; + }, + new Walk(this.unphiInputDir.toPath()) + ) + ) + ).intValue(); + Logger.info(this, "Parsed %d phi files to xmir", count); + } +} diff --git a/eo-maven-plugin/src/main/resources/log4j.properties b/eo-maven-plugin/src/main/resources/log4j.properties index 0d9b433c04..6398d644fc 100644 --- a/eo-maven-plugin/src/main/resources/log4j.properties +++ b/eo-maven-plugin/src/main/resources/log4j.properties @@ -6,7 +6,7 @@ log4j.appender.CONSOLE.layout.ConversionPattern=%d{HH:mm:ss} [%color{%p}] %c: %m log4j.logger.org.eolang=INFO log4j.logger.com.yegor256.xsline=INFO -log4j.logger.org.eolang.parser.Syntax=INFO +log4j.logger.org.eolang.parser.EoSyntax=INFO log4j.logger.org.eolang.parser.Scenario=INFO log4j.logger.org.eolang.parser.XMIRTest=INFO log4j.logger.org.eolang.maven.SodgMojo=TRACE diff --git a/eo-maven-plugin/src/test/java/org/eolang/maven/FakeMaven.java b/eo-maven-plugin/src/test/java/org/eolang/maven/FakeMaven.java index e23afe2b4a..37e117fd93 100644 --- a/eo-maven-plugin/src/test/java/org/eolang/maven/FakeMaven.java +++ b/eo-maven-plugin/src/test/java/org/eolang/maven/FakeMaven.java @@ -258,6 +258,16 @@ public FakeMaven execute(final Class mojo) throws IO "phiOutputDir", this.workspace.absolute(Paths.get("target/phi")).toFile() ); + this.params.putIfAbsent( + "unphiInputDir", + this.workspace.absolute(Paths.get("target/phi")).toFile() + ); + this.params.putIfAbsent( + "unphiOutputDir", + this.workspace.absolute( + Paths.get(String.format("target/%s", ParseMojo.DIR)) + ).toFile() + ); } final Moja moja = new Moja<>(mojo); for (final Map.Entry entry : this.allowedParams(mojo).entrySet()) { diff --git a/eo-maven-plugin/src/test/java/org/eolang/maven/JavaFilesTest.java b/eo-maven-plugin/src/test/java/org/eolang/maven/JavaFilesTest.java index 7a5d9e58a2..9d3b8c7cf0 100644 --- a/eo-maven-plugin/src/test/java/org/eolang/maven/JavaFilesTest.java +++ b/eo-maven-plugin/src/test/java/org/eolang/maven/JavaFilesTest.java @@ -23,17 +23,16 @@ */ package org.eolang.maven; -import com.jcabi.xml.XMLDocument; +import com.jcabi.xml.XML; import com.yegor256.xsline.Xsline; -import java.io.ByteArrayOutputStream; +import java.io.IOException; import java.nio.file.Path; import java.nio.file.Paths; import org.cactoos.io.InputOf; -import org.cactoos.io.OutputTo; import org.cactoos.io.ResourceOf; import org.cactoos.text.TextOf; import org.eolang.maven.util.HmBase; -import org.eolang.parser.Syntax; +import org.eolang.parser.EoSyntax; import org.hamcrest.MatcherAssert; import org.hamcrest.Matchers; import org.junit.jupiter.api.BeforeEach; @@ -50,17 +49,14 @@ class JavaFilesTest { /** * Parsed eo program from resources. */ - private XMLDocument xmir; + private XML xmir; @BeforeEach - void setUp() throws Exception { - final ByteArrayOutputStream baos = new ByteArrayOutputStream(); - new Syntax( + void setUp() throws IOException { + this.xmir = new EoSyntax( "sum.eo", - new ResourceOf("org/eolang/maven/sum.eo"), - new OutputTo(baos) - ).parse(); - this.xmir = new XMLDocument(baos.toByteArray()); + new ResourceOf("org/eolang/maven/sum.eo") + ).parsed(); } @Test diff --git a/eo-maven-plugin/src/test/java/org/eolang/maven/UnphiMojoTest.java b/eo-maven-plugin/src/test/java/org/eolang/maven/UnphiMojoTest.java new file mode 100644 index 0000000000..260b1f54fb --- /dev/null +++ b/eo-maven-plugin/src/test/java/org/eolang/maven/UnphiMojoTest.java @@ -0,0 +1,99 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2016-2023 Objectionary.com + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package org.eolang.maven; + +import com.jcabi.xml.XML; +import com.jcabi.xml.XMLDocument; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.Arrays; +import java.util.List; +import java.util.Map; +import org.cactoos.list.ListOf; +import org.cactoos.text.TextOf; +import org.eolang.jucs.ClasspathSource; +import org.eolang.maven.util.HmBase; +import org.hamcrest.MatcherAssert; +import org.hamcrest.Matchers; +import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.io.TempDir; +import org.junit.jupiter.params.ParameterizedTest; +import org.yaml.snakeyaml.Yaml; + +/** + * Test cases for {@link UnphiMojo}. + * @since 0.34.0 + * @todo #2642:30min Create test packs for {@link UnphiMojo}. UnphiMojo seems to work correctly. + * We need to create yaml packs and enable {@link UnphiMojoTest#checksUnphiPacks(String, Path)} + * and make sure all of them are passed. Don't forget to remove the puzzle. + */ +class UnphiMojoTest { + @Test + void createsFile(@TempDir final Path temp) throws Exception { + new HmBase(temp).save( + "{std ↦ Φ.org.eolang.io.stdout, y ↦ Φ.org.eolang.x}", + Paths.get("target/phi/std.phi") + ); + MatcherAssert.assertThat( + String.format( + "There should be file with .%s extension after parsing phi to XMIR, but there isn't", + TranspileMojo.EXT + ), + new FakeMaven(temp) + .execute(UnphiMojo.class) + .result(), + Matchers.hasKey(String.format("target/%s/std.xmir", ParseMojo.DIR)) + ); + } + + @ParameterizedTest + @Disabled + @ClasspathSource(value = "org/eolang/maven/unphi", glob = "**.yaml") + void checksUnphiPacks(final String pack, @TempDir final Path temp) throws Exception { + final Map map = new Yaml().load(pack); + final String phi = map.get("phi").toString(); + new HmBase(temp).save(phi, Paths.get("target/phi/main.phi")); + final List failures = new ListOf<>(); + new FakeMaven(temp).execute(UnphiMojo.class); + for (final String xpath : (Iterable) map.get("tests")) { + final List nodes = new XMLDocument( + new TextOf( + Paths.get(String.format("target/%s/main.xmir", ParseMojo.DIR)) + ).asString() + ).nodes(xpath); + if (nodes.isEmpty()) { + failures.add(xpath); + } + } + MatcherAssert.assertThat( + String.format( + "Failed to parse phi expression: %s; failed tests: %s", + phi, Arrays.toString(failures.toArray()) + ), + failures, + Matchers.empty() + ); + } +} diff --git a/eo-maven-plugin/src/test/resources/log4j.properties b/eo-maven-plugin/src/test/resources/log4j.properties index 15ae53fe0c..84d4c2a233 100644 --- a/eo-maven-plugin/src/test/resources/log4j.properties +++ b/eo-maven-plugin/src/test/resources/log4j.properties @@ -6,7 +6,7 @@ log4j.appender.CONSOLE.layout.ConversionPattern=%d{HH:mm:ss} [%p] %c: %m%n log4j.logger.org.eolang=INFO log4j.logger.com.jcabi.log.VerboseProcess=INFO -log4j.logger.org.eolang.parser.Syntax=INFO +log4j.logger.org.eolang.parser.EoSyntax=INFO log4j.logger.org.eolang.parser.Program=INFO log4j.logger.org.eolang.maven.SodgMojo=INFO log4j.logger.org.eolang.maven.SodgMojoTest=INFO diff --git a/eo-parser/pom.xml b/eo-parser/pom.xml index 7c929824e8..7f13662307 100644 --- a/eo-parser/pom.xml +++ b/eo-parser/pom.xml @@ -189,7 +189,7 @@ SOFTWARE. qulice-maven-plugin - checkstyle:/src/main/java/org/eolang/parser/XeListener.java + checkstyle:/src/main/java/org/eolang/parser/XeEoListener.java diff --git a/eo-parser/src/main/antlr4/org/eolang/parser/Program.g4 b/eo-parser/src/main/antlr4/org/eolang/parser/Eo.g4 similarity index 99% rename from eo-parser/src/main/antlr4/org/eolang/parser/Program.g4 rename to eo-parser/src/main/antlr4/org/eolang/parser/Eo.g4 index 47896d4f0b..25e06e9108 100644 --- a/eo-parser/src/main/antlr4/org/eolang/parser/Program.g4 +++ b/eo-parser/src/main/antlr4/org/eolang/parser/Eo.g4 @@ -1,4 +1,4 @@ -grammar Program; +grammar Eo; tokens { TAB, UNTAB } diff --git a/eo-parser/src/main/antlr4/org/eolang/parser/Phi.g4 b/eo-parser/src/main/antlr4/org/eolang/parser/Phi.g4 new file mode 100644 index 0000000000..0761656ab8 --- /dev/null +++ b/eo-parser/src/main/antlr4/org/eolang/parser/Phi.g4 @@ -0,0 +1,169 @@ +grammar Phi; + +program + : LCB bindings RCB + ; + +object + : formation + | application + | dispatch + | termination + ; + +formation + : LSB bindings RSB + ; + +bindings + : binding? + | binding (COMMA SPACE binding)* + ; + +binding + : alphaBinding + | emptyBinding + | deltaBidning + | lambdaBidning + ; + +alphaBinding + : attribute SPACE ARROW SPACE object + ; + +attribute + : PHI + | RHO + | SIGMA + | VTX + | LABEL + | alpha + ; + +alpha + : ALPHA INDEX + ; + +emptyBinding + : attribute SPACE ARROW SPACE EMPTY + ; + +deltaBidning + : DELTA SPACE DASHED_ARROW SPACE BYTES + ; + +lambdaBidning + : LAMBDA SPACE DASHED_ARROW SPACE FUNCTION + ; + +FUNCTION + : [A-Z] ~[ \r\n\t,.|':;!\-?\][}{)(⟧⟦]* + ; + +application + : (formation | dispatch | termination) bnds + ; + +bnds: (LB bindings RB)+ + ; + +dispatch + : (formation | termination) bnds? attr+ disp + | HOME attr+ disp + | XI attr+ disp + ; + +disp: + | dispBnds attr+ disp + ; + +// The rule was separately because it's used as +// marker where it's needed to enter the object +// in order to make application right +dispBnds + : bnds + ; + +attr: DOT attribute + ; + +termination + : ERROR + ; + +LCB : '{' + ; +RCB : '}' + ; +LSB : '⟦' + ; +RSB : '⟧' + ; +LB : '(' + ; +RB : ')' + ; +DOT : '.' + ; +COMMA + : ',' + ; +SPACE + : ' ' + ; +ARROW + : '↦' + ; +DASHED_ARROW + : '⤍' + ; +ALPHA + : 'α' + ; +EMPTY + : '∅' + ; +PHI : 'φ' + ; +RHO : 'ρ' + ; +SIGMA + : 'σ' + ; +VTX : 'ν' + ; +DELTA + : 'Δ' + ; +XI : 'ξ' + ; +LAMBDA + : 'λ' + ; +HOME: 'Φ' + ; +ERROR + : '⊥' + ; +MINUS + : '-' + ; + +INDEX + : [0-9] + | [1-9][0-9]* + ; + +LABEL + : [a-z] ~[ \r\n\t,.|':;!?\][}{)(⟧⟦]* + ; + +fragment BYTE + : [0-9A-F][0-9A-F] + ; + +BYTES + : MINUS MINUS + | BYTE MINUS + | BYTE (MINUS BYTE)+ + ; \ No newline at end of file diff --git a/eo-parser/src/main/java/org/eolang/parser/CheckPack.java b/eo-parser/src/main/java/org/eolang/parser/CheckPack.java index 1e307a8691..e1351c9f75 100644 --- a/eo-parser/src/main/java/org/eolang/parser/CheckPack.java +++ b/eo-parser/src/main/java/org/eolang/parser/CheckPack.java @@ -25,18 +25,15 @@ import com.jcabi.log.Logger; import com.jcabi.xml.XML; -import com.jcabi.xml.XMLDocument; import com.yegor256.xsline.Shift; import com.yegor256.xsline.StClasspath; import com.yegor256.xsline.Train; import com.yegor256.xsline.Xsline; -import java.io.ByteArrayOutputStream; import java.io.IOException; import java.util.Collection; import java.util.LinkedList; import java.util.Map; import org.cactoos.io.InputOf; -import org.cactoos.io.OutputTo; import org.yaml.snakeyaml.Yaml; /** @@ -70,15 +67,7 @@ public CheckPack(final String scrpt) { public Collection failures() throws IOException { final Yaml yaml = new Yaml(); final Map map = yaml.load(this.script); - final ByteArrayOutputStream baos = new ByteArrayOutputStream(); final String src = map.get("eo").toString(); - new Syntax( - "scenario", - new InputOf(String.format("%s\n", src)), - new OutputTo(baos) - ).parse(); - final XML xml = new XMLDocument(baos.toByteArray()); - baos.reset(); final Iterable xsls = (Iterable) map.get("xsls"); Train train = new ParsingTrain(); if (xsls != null) { @@ -89,7 +78,12 @@ public Collection failures() throws IOException { train = train.with(new StClasspath(xsl)); } } - final XML out = new Xsline(train).pass(xml); + final XML out = new Xsline(train).pass( + new EoSyntax( + "scenario", + new InputOf(String.format("%s\n", src)) + ).parsed() + ); Logger.debug(this, "Output XML:\n%s", out); final Collection failures = new LinkedList<>(); for (final String xpath : (Iterable) map.get("tests")) { diff --git a/eo-parser/src/main/java/org/eolang/parser/EoLexer.java b/eo-parser/src/main/java/org/eolang/parser/EoIndentLexer.java similarity index 89% rename from eo-parser/src/main/java/org/eolang/parser/EoLexer.java rename to eo-parser/src/main/java/org/eolang/parser/EoIndentLexer.java index a0995eae50..6de33f038a 100644 --- a/eo-parser/src/main/java/org/eolang/parser/EoLexer.java +++ b/eo-parser/src/main/java/org/eolang/parser/EoIndentLexer.java @@ -39,7 +39,7 @@ * * @since 1.0 */ -public final class EoLexer extends ProgramLexer { +public final class EoIndentLexer extends EoLexer { /** * Generated tokes. */ @@ -55,7 +55,7 @@ public final class EoLexer extends ProgramLexer { * @param txt Source code. * @throws IOException If fails. */ - public EoLexer(final Text txt) throws IOException { + public EoIndentLexer(final Text txt) throws IOException { this(CharStreams.fromStream(new InputStreamOf(txt))); } @@ -63,7 +63,7 @@ public EoLexer(final Text txt) throws IOException { * Ctor. * @param stream Char stream. */ - private EoLexer(final CharStream stream) { + private EoIndentLexer(final CharStream stream) { super(stream); this.indent = new LinkedList<>( Collections.singletonList(0) @@ -84,8 +84,8 @@ public Token nextToken() { */ private void lookAhead() { final Token token = super.nextToken(); - if (token.getType() == ProgramParser.EOL - || token.getType() == ProgramParser.EOP) { + if (token.getType() == EoParser.EOL + || token.getType() == EoParser.EOP) { final int tabs = this.getText().replaceAll("[\r\n]", "").length() / 2; final int last = this.indent.peekLast(); final int shift = tabs - last; @@ -105,7 +105,7 @@ private void lookAhead() { */ private void emitIndent(final int shift) { for (int idx = 0; idx < shift; ++idx) { - this.emitToken(ProgramParser.TAB); + this.emitToken(EoParser.TAB); } } @@ -115,8 +115,8 @@ private void emitIndent(final int shift) { */ private void emitDedent(final int shift) { for (int idx = 0; idx < shift; ++idx) { - this.emitToken(ProgramParser.UNTAB); - this.emitToken(ProgramParser.EOL); + this.emitToken(EoParser.UNTAB); + this.emitToken(EoParser.EOL); } } diff --git a/eo-parser/src/main/java/org/eolang/parser/EoSyntax.java b/eo-parser/src/main/java/org/eolang/parser/EoSyntax.java new file mode 100644 index 0000000000..a9d763fd5c --- /dev/null +++ b/eo-parser/src/main/java/org/eolang/parser/EoSyntax.java @@ -0,0 +1,214 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2016-2023 Objectionary.com + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package org.eolang.parser; + +import com.jcabi.log.Logger; +import com.jcabi.xml.XML; +import com.jcabi.xml.XMLDocument; +import java.io.IOException; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; +import org.antlr.v4.runtime.ANTLRErrorListener; +import org.antlr.v4.runtime.BaseErrorListener; +import org.antlr.v4.runtime.CommonTokenStream; +import org.antlr.v4.runtime.RecognitionException; +import org.antlr.v4.runtime.Recognizer; +import org.antlr.v4.runtime.tree.ParseTreeWalker; +import org.cactoos.Input; +import org.cactoos.Text; +import org.cactoos.iterable.Mapped; +import org.cactoos.list.ListOf; +import org.cactoos.text.FormattedText; +import org.cactoos.text.Joined; +import org.cactoos.text.Split; +import org.cactoos.text.TextOf; +import org.xembly.Directive; +import org.xembly.Directives; +import org.xembly.Xembler; + +/** + * Syntax parser, from EO to XMIR, using ANTLR4. + * + * @since 0.1 + * @checkstyle ClassFanOutComplexityCheck (500 lines) + */ +public final class EoSyntax implements Syntax { + + /** + * The name of it. + */ + private final String name; + + /** + * Text to parse. + */ + private final Input input; + + /** + * Ctor. + * + * @param nme The name of it + * @param ipt Input text + */ + public EoSyntax(final String nme, final Input ipt) { + this.name = nme; + this.input = ipt; + } + + /** + * Compile it to XML and save. + * + *

No exception will be thrown if the syntax is invalid. In any case, XMIR will + * be generated and saved. Read it in order to find the errors, + * at /program/errors XPath.

+ * + * @return Parsed XML + * @throws IOException If fails + */ + public XML parsed() throws IOException { + final List lines = this.lines(); + final ParsingErrors spy = new ParsingErrors(lines); + final EoLexer lexer = new EoIndentLexer(this.normalize()); + lexer.removeErrorListeners(); + lexer.addErrorListener(spy); + final EoParser parser = new EoParser( + new CommonTokenStream(lexer) + ); + parser.removeErrorListeners(); + parser.addErrorListener(spy); + final XeEoListener xel = new XeEoListener(this.name); + new ParseTreeWalker().walk(xel, parser.program()); + final XML dom = new XMLDocument( + new Xembler( + new Directives(xel).append(spy) + ).domQuietly() + ); + new Schema(dom).check(); + if (spy.size() == 0) { + Logger.debug(this, "Input of %d EO lines compiled, no errors", lines.size()); + } else { + Logger.debug( + this, "Input of %d EO lines failed to compile (%d errors)", + lines.size(), spy.size() + ); + } + return dom; + } + + /** + * Normalize input to UNIX format. + * Ensure EOL at EOF. + * + * @return UNIX formatted text. + */ + private Text normalize() { + return new FormattedText( + "%s\n", + new Joined(new TextOf("\n"), this.lines()) + ); + } + + /** + * Split input into lines. + * @return Lines without line breaks. + */ + private List lines() { + return new ListOf<>(new Split(new TextOf(this.input), "\r?\n")); + } + + /** + * Accumulates all parsing errors. + * + * @since 0.30.0 + */ + private static final class ParsingErrors extends BaseErrorListener + implements ANTLRErrorListener, Iterable { + /** + * Errors accumulated. + */ + private final List errors; + + /** + * The source. + */ + private final List lines; + + /** + * Ctor. + * @param src The source in lines + */ + private ParsingErrors(final List src) { + this.errors = new LinkedList<>(); + this.lines = src; + } + + // @checkstyle ParameterNumberCheck (10 lines) + @Override + public void syntaxError(final Recognizer recognizer, + final Object symbol, final int line, + final int position, final String msg, + final RecognitionException error + ) { + this.errors.add( + new ParsingException( + String.format( + "[%d:%d] %s: \"%s\"", + line, position, msg, + // @checkstyle AvoidInlineConditionalsCheck (1 line) + this.lines.size() < line ? "EOF" : this.lines.get(line - 1) + ), + error, + line + ) + ); + } + + @Override + public Iterator iterator() { + return new org.cactoos.iterable.Joined<>( + new Mapped>( + error -> new Directives() + .xpath("/program/errors") + .add("error") + .attr("line", error.line()) + .attr("severity", "critical") + .set(error.getMessage()) + .up(), + this.errors + ) + ).iterator(); + } + + /** + * How many errors? + * @return Count of errors accumulated + */ + public int size() { + return this.errors.size(); + } + + } + +} diff --git a/eo-parser/src/main/java/org/eolang/parser/Objects.java b/eo-parser/src/main/java/org/eolang/parser/Objects.java index f3ae36e427..7c8420465f 100644 --- a/eo-parser/src/main/java/org/eolang/parser/Objects.java +++ b/eo-parser/src/main/java/org/eolang/parser/Objects.java @@ -41,6 +41,12 @@ interface Objects extends Iterable { */ Objects start(int line, int pos); + /** + * Start new object without position. + * @return Self. + */ + Objects start(); + /** * Add data. * @param data Data. @@ -100,6 +106,12 @@ public Objects start(final int line, final int pos) { return this.prop("line", line).prop("pos", pos); } + @Override + public Objects start() { + this.dirs.add("o"); + return this; + } + @Override public Objects data(final String data) { this.dirs.set(data); diff --git a/eo-parser/src/main/java/org/eolang/parser/PhiSyntax.java b/eo-parser/src/main/java/org/eolang/parser/PhiSyntax.java new file mode 100644 index 0000000000..effa593b8c --- /dev/null +++ b/eo-parser/src/main/java/org/eolang/parser/PhiSyntax.java @@ -0,0 +1,87 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2016-2023 Objectionary.com + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package org.eolang.parser; + +import com.jcabi.log.Logger; +import com.jcabi.xml.XML; +import com.jcabi.xml.XMLDocument; +import java.io.IOException; +import org.antlr.v4.runtime.CharStreams; +import org.antlr.v4.runtime.CommonTokenStream; +import org.antlr.v4.runtime.tree.ParseTreeWalker; +import org.cactoos.Text; +import org.cactoos.io.InputStreamOf; +import org.xembly.Directives; +import org.xembly.Xembler; + +/** + * Syntax parser, from Phi-calculus to XMIR, using ANTLR4. + * @since 0.34.0 + */ +public final class PhiSyntax implements Syntax { + /** + * Name of the program. + */ + private final String name; + + /** + * Input. + */ + private final Text input; + + /** + * Ctor. + * @param nme Name of the program + * @param inpt Input + */ + public PhiSyntax(final String nme, final Text inpt) { + this.name = nme; + this.input = inpt; + } + + @Override + public XML parsed() throws IOException { + final XePhiListener xel = new XePhiListener(this.name); + new ParseTreeWalker().walk( + xel, + new PhiParser( + new CommonTokenStream( + new PhiLexer( + CharStreams.fromStream( + new InputStreamOf(this.input) + ) + ) + ) + ).program() + ); + final XML dom = new XMLDocument( + new Xembler( + new Directives(xel) + ).domQuietly() + ); + new Schema(dom).check(); + Logger.debug(this, "Input of PHI calculus compiled, no errors"); + return dom; + } +} diff --git a/eo-parser/src/main/java/org/eolang/parser/SourceText.java b/eo-parser/src/main/java/org/eolang/parser/SourceText.java new file mode 100644 index 0000000000..2ed086cda0 --- /dev/null +++ b/eo-parser/src/main/java/org/eolang/parser/SourceText.java @@ -0,0 +1,56 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2016-2023 Objectionary.com + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package org.eolang.parser; + +import org.antlr.v4.runtime.ParserRuleContext; +import org.antlr.v4.runtime.misc.Interval; + +/** + * Source text of parser context. + * @since 0.34.0 + */ +public final class SourceText { + /** + * Context. + */ + private final ParserRuleContext context; + + /** + * Ctor. + * @param ctx Context + */ + public SourceText(final ParserRuleContext ctx) { + this.context = ctx; + } + + @Override + public String toString() { + return this.context.getStart().getInputStream().getText( + new Interval( + this.context.getStart().getStartIndex(), + this.context.getStop().getStopIndex() + ) + ); + } +} diff --git a/eo-parser/src/main/java/org/eolang/parser/Syntax.java b/eo-parser/src/main/java/org/eolang/parser/Syntax.java index 0a9d3e7a6d..f2c7f0c31a 100644 --- a/eo-parser/src/main/java/org/eolang/parser/Syntax.java +++ b/eo-parser/src/main/java/org/eolang/parser/Syntax.java @@ -23,215 +23,18 @@ */ package org.eolang.parser; -import com.jcabi.log.Logger; import com.jcabi.xml.XML; -import com.jcabi.xml.XMLDocument; import java.io.IOException; -import java.util.Iterator; -import java.util.LinkedList; -import java.util.List; -import org.antlr.v4.runtime.ANTLRErrorListener; -import org.antlr.v4.runtime.BaseErrorListener; -import org.antlr.v4.runtime.CommonTokenStream; -import org.antlr.v4.runtime.RecognitionException; -import org.antlr.v4.runtime.Recognizer; -import org.antlr.v4.runtime.tree.ParseTreeWalker; -import org.cactoos.Input; -import org.cactoos.Output; -import org.cactoos.Text; -import org.cactoos.io.InputOf; -import org.cactoos.io.TeeInput; -import org.cactoos.iterable.Mapped; -import org.cactoos.list.ListOf; -import org.cactoos.scalar.LengthOf; -import org.cactoos.scalar.Unchecked; -import org.cactoos.text.FormattedText; -import org.cactoos.text.Joined; -import org.cactoos.text.Split; -import org.cactoos.text.TextOf; -import org.xembly.Directive; -import org.xembly.Directives; -import org.xembly.Xembler; /** - * Syntax parser, from EO to XMIR, using ANTLR4. - * - * @since 0.1 - * @checkstyle ClassFanOutComplexityCheck (500 lines) + * Syntax parser, to XMIR, using ANTLR4. + * @since 0.34.0 */ -public final class Syntax { - - /** - * The name of it. - */ - private final String name; - - /** - * Text to parse. - */ - private final Input input; - +public interface Syntax { /** - * Target to save XML to. - */ - private final Output target; - - /** - * Ctor. - * - * @param nme The name of it - * @param ipt Input text - * @param tgt Target - * @checkstyle ParameterNumberCheck (10 lines) - */ - public Syntax( - final String nme, - final Input ipt, - final Output tgt - ) { - this.name = nme; - this.input = ipt; - this.target = tgt; - } - - /** - * Compile it to XML and save. - * - *

No exception will be thrown if the syntax is invalid. In any case, XMIR will - * be generated and saved. Read it in order to find the errors, - * at /program/errors XPath.

- * + * Parse it to XML. + * @return Parsed XML * @throws IOException If fails */ - public void parse() throws IOException { - final List lines = this.lines(); - final ParsingErrors spy = new ParsingErrors(lines); - final ProgramLexer lexer = new EoLexer(this.normalize()); - lexer.removeErrorListeners(); - lexer.addErrorListener(spy); - final ProgramParser parser = new ProgramParser( - new CommonTokenStream(lexer) - ); - parser.removeErrorListeners(); - parser.addErrorListener(spy); - final XeListener xel = new XeListener(this.name); - new ParseTreeWalker().walk(xel, parser.program()); - final XML dom = new XMLDocument( - new Xembler( - new Directives(xel).append(spy) - ).domQuietly() - ); - new Schema(dom).check(); - new Unchecked<>( - new LengthOf( - new TeeInput( - new InputOf(dom.toString()), - this.target - ) - ) - ).value(); - if (spy.size() == 0) { - Logger.debug(this, "Input of %d EO lines compiled, no errors", lines.size()); - } else { - Logger.debug( - this, "Input of %d EO lines failed to compile (%d errors)", - lines.size(), spy.size() - ); - } - } - - /** - * Normalize input to UNIX format. - * Ensure EOL at EOF. - * - * @return UNIX formatted text. - */ - private Text normalize() { - return new FormattedText( - "%s\n", - new Joined(new TextOf("\n"), this.lines()) - ); - } - - /** - * Split input into lines. - * @return Lines without line breaks. - */ - private List lines() { - return new ListOf<>(new Split(new TextOf(this.input), "\r?\n")); - } - - /** - * Accumulates all parsing errors. - * - * @since 0.30.0 - */ - private static final class ParsingErrors extends BaseErrorListener - implements ANTLRErrorListener, Iterable { - /** - * Errors accumulated. - */ - private final List errors; - - /** - * The source. - */ - private final List lines; - - /** - * Ctor. - * @param src The source in lines - */ - private ParsingErrors(final List src) { - this.errors = new LinkedList<>(); - this.lines = src; - } - - // @checkstyle ParameterNumberCheck (10 lines) - @Override - public void syntaxError(final Recognizer recognizer, - final Object symbol, final int line, - final int position, final String msg, - final RecognitionException error - ) { - this.errors.add( - new ParsingException( - String.format( - "[%d:%d] %s: \"%s\"", - line, position, msg, - // @checkstyle AvoidInlineConditionalsCheck (1 line) - this.lines.size() < line ? "EOF" : this.lines.get(line - 1) - ), - error, - line - ) - ); - } - - @Override - public Iterator iterator() { - return new org.cactoos.iterable.Joined<>( - new Mapped>( - error -> new Directives() - .xpath("/program/errors") - .add("error") - .attr("line", error.line()) - .attr("severity", "critical") - .set(error.getMessage()) - .up(), - this.errors - ) - ).iterator(); - } - - /** - * How many errors? - * @return Count of errors accumulated - */ - public int size() { - return this.errors.size(); - } - - } - + XML parsed() throws IOException; } diff --git a/eo-parser/src/main/java/org/eolang/parser/XeListener.java b/eo-parser/src/main/java/org/eolang/parser/XeEoListener.java similarity index 63% rename from eo-parser/src/main/java/org/eolang/parser/XeListener.java rename to eo-parser/src/main/java/org/eolang/parser/XeEoListener.java index 435c939e13..cd1ad99fc8 100644 --- a/eo-parser/src/main/java/org/eolang/parser/XeListener.java +++ b/eo-parser/src/main/java/org/eolang/parser/XeEoListener.java @@ -32,7 +32,6 @@ import java.util.Iterator; import java.util.StringJoiner; import org.antlr.v4.runtime.ParserRuleContext; -import org.antlr.v4.runtime.misc.Interval; import org.antlr.v4.runtime.tree.ErrorNode; import org.antlr.v4.runtime.tree.TerminalNode; import org.apache.commons.text.StringEscapeUtils; @@ -42,7 +41,7 @@ import org.xembly.Directives; /** - * The listener for ANTLR4 walker. + * The EO grammar listener for ANTLR4 walker. * * @checkstyle CyclomaticComplexityCheck (500 lines) * @checkstyle ClassFanOutComplexityCheck (500 lines) @@ -55,15 +54,11 @@ "PMD.ExcessivePublicCount", "PMD.ExcessiveClassLength" }) -public final class XeListener implements ProgramListener, Iterable { +public final class XeEoListener implements EoListener, Iterable { /** * Info about xmir. */ - private static final String INFO = String.join( - "", - "This is XMIR - a dialect of XML, which is used to present a parsed EO program. ", - "For more information please visit https://news.eolang.org/2022-11-25-xmir-guide.html" - ); + private static final XmirInfo INFO = new XmirInfo(); /** * The name of it. @@ -90,7 +85,7 @@ public final class XeListener implements ProgramListener, Iterable { * * @param name The name of it */ - public XeListener(final String name) { + public XeEoListener(final String name) { this.name = name; this.dirs = new Directives(); this.objects = new Objects.ObjXembly(); @@ -98,7 +93,7 @@ public XeListener(final String name) { } @Override - public void enterProgram(final ProgramParser.ProgramContext ctx) { + public void enterProgram(final EoParser.ProgramContext ctx) { this.dirs.add("program") .attr("name", this.name) .attr("version", Manifests.read("EO-Version")) @@ -110,8 +105,8 @@ public void enterProgram(final ProgramParser.ProgramContext ctx) { DateTimeFormatter.ISO_INSTANT ) ) - .comment(XeListener.INFO) - .add("listing").set(XeListener.sourceText(ctx)).up() + .comment(XeEoListener.INFO) + .add("listing").set(new SourceText(ctx)).up() .add("errors").up() .add("sheets").up() .add("license").up() @@ -119,14 +114,14 @@ public void enterProgram(final ProgramParser.ProgramContext ctx) { } @Override - public void exitProgram(final ProgramParser.ProgramContext ctx) { + public void exitProgram(final EoParser.ProgramContext ctx) { this.dirs .attr("ms", (System.nanoTime() - this.start) / (1000L * 1000L)) .up(); } @Override - public void enterLicense(final ProgramParser.LicenseContext ctx) { + public void enterLicense(final EoParser.LicenseContext ctx) { this.dirs.addIf("license").set( new Joined( "\n", @@ -139,12 +134,12 @@ public void enterLicense(final ProgramParser.LicenseContext ctx) { } @Override - public void exitLicense(final ProgramParser.LicenseContext ctx) { + public void exitLicense(final EoParser.LicenseContext ctx) { // Nothing here } @Override - public void enterMetas(final ProgramParser.MetasContext ctx) { + public void enterMetas(final EoParser.MetasContext ctx) { this.dirs.addIf("metas"); for (final TerminalNode node : ctx.META()) { final String[] pair = node.getText().split(" ", 2); @@ -166,54 +161,53 @@ public void enterMetas(final ProgramParser.MetasContext ctx) { } @Override - public void exitMetas(final ProgramParser.MetasContext ctx) { + public void exitMetas(final EoParser.MetasContext ctx) { // Nothing here } @Override - public void enterObjects(final ProgramParser.ObjectsContext ctx) { + public void enterObjects(final EoParser.ObjectsContext ctx) { this.dirs.add("objects"); } @Override - public void exitObjects(final ProgramParser.ObjectsContext ctx) { - this.dirs.append(this.objects); - this.dirs.up(); + public void exitObjects(final EoParser.ObjectsContext ctx) { + this.dirs.append(this.objects).up(); } @Override - public void enterObject(final ProgramParser.ObjectContext ctx) { + public void enterObject(final EoParser.ObjectContext ctx) { // Nothing here } @Override - public void exitObject(final ProgramParser.ObjectContext ctx) { + public void exitObject(final EoParser.ObjectContext ctx) { // Nothing here } @Override - public void enterJust(final ProgramParser.JustContext ctx) { + public void enterJust(final EoParser.JustContext ctx) { // Nothing here } @Override - public void exitJust(final ProgramParser.JustContext ctx) { + public void exitJust(final EoParser.JustContext ctx) { // Nothing here } @Override - public void enterJustNamed(final ProgramParser.JustNamedContext ctx) { + public void enterJustNamed(final EoParser.JustNamedContext ctx) { // Nothing here } @Override - public void exitJustNamed(final ProgramParser.JustNamedContext ctx) { + public void exitJustNamed(final EoParser.JustNamedContext ctx) { // Nothing here } @Override @SuppressWarnings("PMD.ConfusingTernary") - public void enterAtom(final ProgramParser.AtomContext ctx) { + public void enterAtom(final EoParser.AtomContext ctx) { this.startObject(ctx); if (ctx.type().NAME() != null) { this.objects.prop("atom", ctx.type().NAME().getText()); @@ -224,117 +218,117 @@ public void enterAtom(final ProgramParser.AtomContext ctx) { } @Override - public void exitAtom(final ProgramParser.AtomContext ctx) { + public void exitAtom(final EoParser.AtomContext ctx) { // Nothing here } @Override - public void enterFormation(final ProgramParser.FormationContext ctx) { + public void enterFormation(final EoParser.FormationContext ctx) { this.startObject(ctx).prop("abstract").leave(); } @Override - public void exitFormation(final ProgramParser.FormationContext ctx) { + public void exitFormation(final EoParser.FormationContext ctx) { // Nothing here } @Override - public void enterInners(final ProgramParser.InnersContext ctx) { + public void enterInners(final EoParser.InnersContext ctx) { this.objects.enter(); } @Override - public void exitInners(final ProgramParser.InnersContext ctx) { + public void exitInners(final EoParser.InnersContext ctx) { this.objects.leave(); } @Override - public void enterAttributes(final ProgramParser.AttributesContext ctx) { + public void enterAttributes(final EoParser.AttributesContext ctx) { this.objects.enter(); } @Override - public void exitAttributes(final ProgramParser.AttributesContext ctx) { + public void exitAttributes(final EoParser.AttributesContext ctx) { this.objects.leave(); } @Override - public void enterAttribute(final ProgramParser.AttributeContext ctx) { + public void enterAttribute(final EoParser.AttributeContext ctx) { this.startObject(ctx).prop("name", ctx.NAME().getText()); } @Override - public void exitAttribute(final ProgramParser.AttributeContext ctx) { + public void exitAttribute(final EoParser.AttributeContext ctx) { this.objects.leave(); } @Override - public void enterType(final ProgramParser.TypeContext ctx) { + public void enterType(final EoParser.TypeContext ctx) { // Nothing here } @Override - public void exitType(final ProgramParser.TypeContext ctx) { + public void exitType(final EoParser.TypeContext ctx) { // Nothing here } @Override - public void enterApplication(final ProgramParser.ApplicationContext ctx) { + public void enterApplication(final EoParser.ApplicationContext ctx) { // Nothing here } @Override - public void exitApplication(final ProgramParser.ApplicationContext ctx) { + public void exitApplication(final EoParser.ApplicationContext ctx) { // Nothing here } @Override - public void enterHapplicationExtended(final ProgramParser.HapplicationExtendedContext ctx) { + public void enterHapplicationExtended(final EoParser.HapplicationExtendedContext ctx) { // Nothing here } @Override - public void exitHapplicationExtended(final ProgramParser.HapplicationExtendedContext ctx) { + public void exitHapplicationExtended(final EoParser.HapplicationExtendedContext ctx) { // Nothing here } @Override - public void enterHapplication(final ProgramParser.HapplicationContext ctx) { + public void enterHapplication(final EoParser.HapplicationContext ctx) { // Nothing here } @Override - public void exitHapplication(final ProgramParser.HapplicationContext ctx) { + public void exitHapplication(final EoParser.HapplicationContext ctx) { // Nothing here } @Override - public void enterHapplicationHead(final ProgramParser.HapplicationHeadContext ctx) { + public void enterHapplicationHead(final EoParser.HapplicationHeadContext ctx) { // Nothing here } @Override - public void exitHapplicationHead(final ProgramParser.HapplicationHeadContext ctx) { + public void exitHapplicationHead(final EoParser.HapplicationHeadContext ctx) { // Nothing here } @Override public void enterHapplicationHeadExtended( - final ProgramParser.HapplicationHeadExtendedContext ctx + final EoParser.HapplicationHeadExtendedContext ctx ) { // Nothing here } @Override public void exitHapplicationHeadExtended( - final ProgramParser.HapplicationHeadExtendedContext ctx + final EoParser.HapplicationHeadExtendedContext ctx ) { // Nothing here } @Override @SuppressWarnings("PMD.ConfusingTernary") - public void enterApplicable(final ProgramParser.ApplicableContext ctx) { + public void enterApplicable(final EoParser.ApplicableContext ctx) { if (ctx.reversed() == null) { this.startObject(ctx); final String base; @@ -359,425 +353,425 @@ public void enterApplicable(final ProgramParser.ApplicableContext ctx) { } @Override - public void exitApplicable(final ProgramParser.ApplicableContext ctx) { + public void exitApplicable(final EoParser.ApplicableContext ctx) { // Nothing here } @Override - public void enterHapplicationTail(final ProgramParser.HapplicationTailContext ctx) { + public void enterHapplicationTail(final EoParser.HapplicationTailContext ctx) { this.objects.enter(); } @Override - public void exitHapplicationTail(final ProgramParser.HapplicationTailContext ctx) { + public void exitHapplicationTail(final EoParser.HapplicationTailContext ctx) { this.objects.leave(); } @Override - public void enterHapplicationArg(final ProgramParser.HapplicationArgContext ctx) { + public void enterHapplicationArg(final EoParser.HapplicationArgContext ctx) { // Nothing here } @Override - public void exitHapplicationArg(final ProgramParser.HapplicationArgContext ctx) { + public void exitHapplicationArg(final EoParser.HapplicationArgContext ctx) { // Nothing here } @Override public void enterHapplicationTailExtended( - final ProgramParser.HapplicationTailExtendedContext ctx + final EoParser.HapplicationTailExtendedContext ctx ) { this.objects.enter(); } @Override public void exitHapplicationTailExtended( - final ProgramParser.HapplicationTailExtendedContext ctx + final EoParser.HapplicationTailExtendedContext ctx ) { this.objects.leave(); } @Override public void enterHapplicationArgExtended( - final ProgramParser.HapplicationArgExtendedContext ctx + final EoParser.HapplicationArgExtendedContext ctx ) { // Nothing here } @Override public void exitHapplicationArgExtended( - final ProgramParser.HapplicationArgExtendedContext ctx + final EoParser.HapplicationArgExtendedContext ctx ) { // Nothing here } @Override - public void enterVapplication(final ProgramParser.VapplicationContext ctx) { + public void enterVapplication(final EoParser.VapplicationContext ctx) { // Nothing here } @Override - public void exitVapplication(final ProgramParser.VapplicationContext ctx) { + public void exitVapplication(final EoParser.VapplicationContext ctx) { // Nothing here } @Override - public void enterVapplicationHead(final ProgramParser.VapplicationHeadContext ctx) { + public void enterVapplicationHead(final EoParser.VapplicationHeadContext ctx) { // Nothing here } @Override - public void exitVapplicationHead(final ProgramParser.VapplicationHeadContext ctx) { + public void exitVapplicationHead(final EoParser.VapplicationHeadContext ctx) { // Nothing here } @Override - public void enterVapplicationHeadNamed(final ProgramParser.VapplicationHeadNamedContext ctx) { + public void enterVapplicationHeadNamed(final EoParser.VapplicationHeadNamedContext ctx) { // Nothing here } @Override - public void exitVapplicationHeadNamed(final ProgramParser.VapplicationHeadNamedContext ctx) { + public void exitVapplicationHeadNamed(final EoParser.VapplicationHeadNamedContext ctx) { // Nothing here } @Override - public void enterVapplicationArgs(final ProgramParser.VapplicationArgsContext ctx) { + public void enterVapplicationArgs(final EoParser.VapplicationArgsContext ctx) { this.objects.enter(); } @Override - public void exitVapplicationArgs(final ProgramParser.VapplicationArgsContext ctx) { + public void exitVapplicationArgs(final EoParser.VapplicationArgsContext ctx) { this.objects.leave(); } @Override - public void enterVapplicationArg(final ProgramParser.VapplicationArgContext ctx) { + public void enterVapplicationArg(final EoParser.VapplicationArgContext ctx) { // Nothing here } @Override - public void exitVapplicationArg(final ProgramParser.VapplicationArgContext ctx) { + public void exitVapplicationArg(final EoParser.VapplicationArgContext ctx) { // Nothing here } @Override - public void enterVapplicationArgBinded(final ProgramParser.VapplicationArgBindedContext ctx) { + public void enterVapplicationArgBinded(final EoParser.VapplicationArgBindedContext ctx) { // Nothing here } @Override - public void exitVapplicationArgBinded(final ProgramParser.VapplicationArgBindedContext ctx) { + public void exitVapplicationArgBinded(final EoParser.VapplicationArgBindedContext ctx) { // Nothing here } @Override - public void enterVapplicationArgUnbinded(final ProgramParser.VapplicationArgUnbindedContext ctx) { + public void enterVapplicationArgUnbinded(final EoParser.VapplicationArgUnbindedContext ctx) { // Nothing here } @Override - public void exitVapplicationArgUnbinded(final ProgramParser.VapplicationArgUnbindedContext ctx) { + public void exitVapplicationArgUnbinded(final EoParser.VapplicationArgUnbindedContext ctx) { // Nothing here } @Override public void enterVapplicationArgHapplicationBinded( - final ProgramParser.VapplicationArgHapplicationBindedContext ctx + final EoParser.VapplicationArgHapplicationBindedContext ctx ) { // Nothing here } @Override public void exitVapplicationArgHapplicationBinded( - final ProgramParser.VapplicationArgHapplicationBindedContext ctx + final EoParser.VapplicationArgHapplicationBindedContext ctx ) { // Nothing here } @Override public void enterVapplicationArgHapplicationUnbinded( - final ProgramParser.VapplicationArgHapplicationUnbindedContext ctx + final EoParser.VapplicationArgHapplicationUnbindedContext ctx ) { // Nothing here } @Override public void exitVapplicationArgHapplicationUnbinded( - final ProgramParser.VapplicationArgHapplicationUnbindedContext ctx + final EoParser.VapplicationArgHapplicationUnbindedContext ctx ) { // Nothing here } @Override public void enterVapplicationHeadAs( - final ProgramParser.VapplicationHeadAsContext ctx + final EoParser.VapplicationHeadAsContext ctx ) { // Nothing here } @Override - public void exitVapplicationHeadAs(final ProgramParser.VapplicationHeadAsContext ctx) { + public void exitVapplicationHeadAs(final EoParser.VapplicationHeadAsContext ctx) { // Nothing here } @Override public void enterVapplicationArgVanonymUnbinded( - final ProgramParser.VapplicationArgVanonymUnbindedContext ctx + final EoParser.VapplicationArgVanonymUnbindedContext ctx ) { this.startObject(ctx).prop("abstract").leave(); } @Override public void exitVapplicationArgVanonymUnbinded( - final ProgramParser.VapplicationArgVanonymUnbindedContext ctx + final EoParser.VapplicationArgVanonymUnbindedContext ctx ) { // Nothing here } @Override public void enterVapplicationArgVanonymBinded( - final ProgramParser.VapplicationArgVanonymBindedContext ctx + final EoParser.VapplicationArgVanonymBindedContext ctx ) { this.startObject(ctx).prop("abstract").leave(); } @Override public void exitVapplicationArgVanonymBinded( - final ProgramParser.VapplicationArgVanonymBindedContext ctx + final EoParser.VapplicationArgVanonymBindedContext ctx ) { // Nothing here } @Override public void enterVapplicationArgHanonymBinded( - final ProgramParser.VapplicationArgHanonymBindedContext ctx + final EoParser.VapplicationArgHanonymBindedContext ctx ) { // Nothing here } @Override public void exitVapplicationArgHanonymBinded( - final ProgramParser.VapplicationArgHanonymBindedContext ctx + final EoParser.VapplicationArgHanonymBindedContext ctx ) { // Nothing here } @Override public void enterVapplicationArgHanonymUnbinded( - final ProgramParser.VapplicationArgHanonymUnbindedContext ctx + final EoParser.VapplicationArgHanonymUnbindedContext ctx ) { // Nothing here } @Override public void exitVapplicationArgHanonymUnbinded( - final ProgramParser.VapplicationArgHanonymUnbindedContext ctx + final EoParser.VapplicationArgHanonymUnbindedContext ctx ) { // Nothing here } @Override - public void enterHanonym(final ProgramParser.HanonymContext ctx) { + public void enterHanonym(final EoParser.HanonymContext ctx) { this.startObject(ctx).prop("abstract").leave(); } @Override - public void exitHanonym(final ProgramParser.HanonymContext ctx) { + public void exitHanonym(final EoParser.HanonymContext ctx) { // Nothing here } @Override - public void enterHanonymInner(final ProgramParser.HanonymInnerContext ctx) { + public void enterHanonymInner(final EoParser.HanonymInnerContext ctx) { this.objects.enter(); } @Override - public void exitHanonymInner(final ProgramParser.HanonymInnerContext ctx) { + public void exitHanonymInner(final EoParser.HanonymInnerContext ctx) { this.objects.leave(); } @Override - public void enterFormatees(final ProgramParser.FormateesContext ctx) { + public void enterFormatees(final EoParser.FormateesContext ctx) { this.objects.enter(); } @Override - public void exitFormatees(final ProgramParser.FormateesContext ctx) { + public void exitFormatees(final EoParser.FormateesContext ctx) { this.objects.leave(); } @Override - public void enterInnerformatee(final ProgramParser.InnerformateeContext ctx) { + public void enterInnerformatee(final EoParser.InnerformateeContext ctx) { this.startObject(ctx).prop("abstract").leave(); } @Override - public void exitInnerformatee(final ProgramParser.InnerformateeContext ctx) { + public void exitInnerformatee(final EoParser.InnerformateeContext ctx) { // Nothing here } @Override - public void enterAhead(final ProgramParser.AheadContext ctx) { + public void enterAhead(final EoParser.AheadContext ctx) { // Nothing here } @Override - public void exitAhead(final ProgramParser.AheadContext ctx) { + public void exitAhead(final EoParser.AheadContext ctx) { // Nothing here } @Override - public void enterMethod(final ProgramParser.MethodContext ctx) { + public void enterMethod(final EoParser.MethodContext ctx) { // Nothing here } @Override - public void exitMethod(final ProgramParser.MethodContext ctx) { + public void exitMethod(final EoParser.MethodContext ctx) { // Nothing here } @Override - public void enterMethodNamed(final ProgramParser.MethodNamedContext ctx) { + public void enterMethodNamed(final EoParser.MethodNamedContext ctx) { // Nothing here } @Override - public void exitMethodNamed(final ProgramParser.MethodNamedContext ctx) { + public void exitMethodNamed(final EoParser.MethodNamedContext ctx) { // Nothing here } @Override - public void enterMethodAs(final ProgramParser.MethodAsContext ctx) { + public void enterMethodAs(final EoParser.MethodAsContext ctx) { // Nothing here } @Override - public void exitMethodAs(final ProgramParser.MethodAsContext ctx) { + public void exitMethodAs(final EoParser.MethodAsContext ctx) { // Nothing here } @Override - public void enterHmethod(final ProgramParser.HmethodContext ctx) { + public void enterHmethod(final EoParser.HmethodContext ctx) { // Nothing here } @Override - public void exitHmethod(final ProgramParser.HmethodContext ctx) { + public void exitHmethod(final EoParser.HmethodContext ctx) { // Nothing here } @Override - public void enterHmethodExtended(final ProgramParser.HmethodExtendedContext ctx) { + public void enterHmethodExtended(final EoParser.HmethodExtendedContext ctx) { // Nothing here } @Override - public void exitHmethodExtended(final ProgramParser.HmethodExtendedContext ctx) { + public void exitHmethodExtended(final EoParser.HmethodExtendedContext ctx) { // Nothing here } @Override - public void enterHmethodVersioned(final ProgramParser.HmethodVersionedContext ctx) { + public void enterHmethodVersioned(final EoParser.HmethodVersionedContext ctx) { // Nothing here } @Override - public void exitHmethodVersioned(final ProgramParser.HmethodVersionedContext ctx) { + public void exitHmethodVersioned(final EoParser.HmethodVersionedContext ctx) { // Nothing here } @Override public void enterHmethodExtendedVersioned( - final ProgramParser.HmethodExtendedVersionedContext ctx + final EoParser.HmethodExtendedVersionedContext ctx ) { // Nothing here } @Override public void exitHmethodExtendedVersioned( - final ProgramParser.HmethodExtendedVersionedContext ctx + final EoParser.HmethodExtendedVersionedContext ctx ) { // Nothing here } @Override - public void enterHmethodHead(final ProgramParser.HmethodHeadContext ctx) { + public void enterHmethodHead(final EoParser.HmethodHeadContext ctx) { // Nothing here } @Override - public void exitHmethodHead(final ProgramParser.HmethodHeadContext ctx) { + public void exitHmethodHead(final EoParser.HmethodHeadContext ctx) { // Nothing here } @Override - public void enterHmethodHeadExtended(final ProgramParser.HmethodHeadExtendedContext ctx) { + public void enterHmethodHeadExtended(final EoParser.HmethodHeadExtendedContext ctx) { // Nothing here } @Override - public void exitHmethodHeadExtended(final ProgramParser.HmethodHeadExtendedContext ctx) { + public void exitHmethodHeadExtended(final EoParser.HmethodHeadExtendedContext ctx) { // Nothing here } @Override - public void enterVmethod(final ProgramParser.VmethodContext ctx) { + public void enterVmethod(final EoParser.VmethodContext ctx) { // Nothing here } @Override - public void exitVmethod(final ProgramParser.VmethodContext ctx) { + public void exitVmethod(final EoParser.VmethodContext ctx) { // Nothing here } @Override - public void enterVmethodVersioned(final ProgramParser.VmethodVersionedContext ctx) { + public void enterVmethodVersioned(final EoParser.VmethodVersionedContext ctx) { // Nothing here } @Override - public void exitVmethodVersioned(final ProgramParser.VmethodVersionedContext ctx) { + public void exitVmethodVersioned(final EoParser.VmethodVersionedContext ctx) { // Nothing here } @Override - public void enterVmethodHead(final ProgramParser.VmethodHeadContext ctx) { + public void enterVmethodHead(final EoParser.VmethodHeadContext ctx) { // Nothing here } @Override - public void exitVmethodHead(final ProgramParser.VmethodHeadContext ctx) { + public void exitVmethodHead(final EoParser.VmethodHeadContext ctx) { // Nothing here } @Override - public void enterVmethodTail(final ProgramParser.VmethodTailContext ctx) { + public void enterVmethodTail(final EoParser.VmethodTailContext ctx) { // Nothing here } @Override - public void exitVmethodTail(final ProgramParser.VmethodTailContext ctx) { + public void exitVmethodTail(final EoParser.VmethodTailContext ctx) { // Nothing here } @Override - public void enterVmethodTailVersioned(final ProgramParser.VmethodTailVersionedContext ctx) { + public void enterVmethodTailVersioned(final EoParser.VmethodTailVersionedContext ctx) { // Nothing here } @Override - public void exitVmethodTailVersioned(final ProgramParser.VmethodTailVersionedContext ctx) { + public void exitVmethodTailVersioned(final EoParser.VmethodTailVersionedContext ctx) { // Nothing here } @Override - public void enterMethodTail(final ProgramParser.MethodTailContext ctx) { + public void enterMethodTail(final EoParser.MethodTailContext ctx) { // Nothing here } @Override - public void exitMethodTail(final ProgramParser.MethodTailContext ctx) { + public void exitMethodTail(final EoParser.MethodTailContext ctx) { this.objects .enter() .prop("method") @@ -787,20 +781,20 @@ public void exitMethodTail(final ProgramParser.MethodTailContext ctx) { } @Override - public void enterMethodTailVersioned(final ProgramParser.MethodTailVersionedContext ctx) { + public void enterMethodTailVersioned(final EoParser.MethodTailVersionedContext ctx) { this.startObject(ctx) .prop("base", String.format(".%s", ctx.NAME().getText())) .prop("method"); } @Override - public void exitMethodTailVersioned(final ProgramParser.MethodTailVersionedContext ctx) { + public void exitMethodTailVersioned(final EoParser.MethodTailVersionedContext ctx) { this.objects.leave(); } @Override @SuppressWarnings("PMD.ConfusingTernary") - public void enterBeginner(final ProgramParser.BeginnerContext ctx) { + public void enterBeginner(final EoParser.BeginnerContext ctx) { this.startObject(ctx); if (ctx.data() == null) { final String base; @@ -823,13 +817,13 @@ public void enterBeginner(final ProgramParser.BeginnerContext ctx) { } @Override - public void exitBeginner(final ProgramParser.BeginnerContext ctx) { + public void exitBeginner(final EoParser.BeginnerContext ctx) { this.objects.leave(); } @Override @SuppressWarnings("PMD.ConfusingTernary") - public void enterFinisher(final ProgramParser.FinisherContext ctx) { + public void enterFinisher(final EoParser.FinisherContext ctx) { this.startObject(ctx); final String base; if (ctx.NAME() != null) { @@ -851,49 +845,49 @@ public void enterFinisher(final ProgramParser.FinisherContext ctx) { } @Override - public void exitFinisher(final ProgramParser.FinisherContext ctx) { + public void exitFinisher(final EoParser.FinisherContext ctx) { this.objects.leave(); } @Override - public void enterFinisherCopied(final ProgramParser.FinisherCopiedContext ctx) { + public void enterFinisherCopied(final EoParser.FinisherCopiedContext ctx) { // Nothing here } @Override - public void exitFinisherCopied(final ProgramParser.FinisherCopiedContext ctx) { + public void exitFinisherCopied(final EoParser.FinisherCopiedContext ctx) { if (ctx.COPY() != null) { this.objects.enter().prop("copy").leave(); } } @Override - public void enterVersioned(final ProgramParser.VersionedContext ctx) { + public void enterVersioned(final EoParser.VersionedContext ctx) { this.startObject(ctx).prop("base", ctx.NAME().getText()); } @Override - public void exitVersioned(final ProgramParser.VersionedContext ctx) { + public void exitVersioned(final EoParser.VersionedContext ctx) { this.objects.leave(); } @Override - public void enterReversed(final ProgramParser.ReversedContext ctx) { + public void enterReversed(final EoParser.ReversedContext ctx) { // Nothing here } @Override - public void exitReversed(final ProgramParser.ReversedContext ctx) { + public void exitReversed(final EoParser.ReversedContext ctx) { this.objects.enter().xprop("base", "concat('.',@base)").leave(); } @Override - public void enterOname(final ProgramParser.OnameContext ctx) { + public void enterOname(final EoParser.OnameContext ctx) { // Nothing here } @Override - public void exitOname(final ProgramParser.OnameContext ctx) { + public void exitOname(final EoParser.OnameContext ctx) { if (ctx.CONST() != null) { this.objects.enter().prop("const").leave(); } @@ -901,7 +895,7 @@ public void exitOname(final ProgramParser.OnameContext ctx) { @Override @SuppressWarnings("PMD.ConfusingTernary") - public void enterSuffix(final ProgramParser.SuffixContext ctx) { + public void enterSuffix(final EoParser.SuffixContext ctx) { this.objects.enter(); if (ctx.AT() != null) { this.objects.prop("name", ctx.AT().getText()); @@ -911,45 +905,45 @@ public void enterSuffix(final ProgramParser.SuffixContext ctx) { } @Override - public void exitSuffix(final ProgramParser.SuffixContext ctx) { + public void exitSuffix(final EoParser.SuffixContext ctx) { this.objects.leave(); } @Override - public void enterScope(final ProgramParser.ScopeContext ctx) { + public void enterScope(final EoParser.ScopeContext ctx) { // Nothing here } @Override - public void exitScope(final ProgramParser.ScopeContext ctx) { + public void exitScope(final EoParser.ScopeContext ctx) { // Nothing here } @Override - public void enterScopeExtended(final ProgramParser.ScopeExtendedContext ctx) { + public void enterScopeExtended(final EoParser.ScopeExtendedContext ctx) { // Nothing here } @Override - public void exitScopeExtended(final ProgramParser.ScopeExtendedContext ctx) { + public void exitScopeExtended(final EoParser.ScopeExtendedContext ctx) { // Nothing here } @Override - public void enterVersion(final ProgramParser.VersionContext ctx) { + public void enterVersion(final EoParser.VersionContext ctx) { if (ctx.VER() != null) { this.objects.prop("ver", ctx.VER().getText()); } } @Override - public void exitVersion(final ProgramParser.VersionContext ctx) { + public void exitVersion(final EoParser.VersionContext ctx) { // Nothing here } @Override @SuppressWarnings("PMD.ConfusingTernary") - public void enterAs(final ProgramParser.AsContext ctx) { + public void enterAs(final EoParser.AsContext ctx) { this.objects.enter(); final String has; if (ctx.NAME() != null) { @@ -963,13 +957,13 @@ public void enterAs(final ProgramParser.AsContext ctx) { } @Override - public void exitAs(final ProgramParser.AsContext ctx) { + public void exitAs(final EoParser.AsContext ctx) { this.objects.leave(); } @Override @SuppressWarnings("PMD.ConfusingTernary") - public void enterData(final ProgramParser.DataContext ctx) { + public void enterData(final EoParser.DataContext ctx) { final String type; final String data; final String base; @@ -982,14 +976,14 @@ public void enterData(final ProgramParser.DataContext ctx) { type = "bytes"; base = "bool"; if (Boolean.parseBoolean(text)) { - data = XeListener.bytesToHex((byte) 0x01); + data = XeEoListener.bytesToHex((byte) 0x01); } else { - data = XeListener.bytesToHex((byte) 0x00); + data = XeEoListener.bytesToHex((byte) 0x00); } } else if (ctx.FLOAT() != null) { type = "bytes"; base = "float"; - data = XeListener.bytesToHex( + data = XeEoListener.bytesToHex( ByteBuffer .allocate(Long.BYTES) .putDouble(Double.parseDouble(text)) @@ -998,7 +992,7 @@ public void enterData(final ProgramParser.DataContext ctx) { } else if (ctx.INT() != null) { type = "bytes"; base = "int"; - data = XeListener.bytesToHex( + data = XeEoListener.bytesToHex( ByteBuffer .allocate(Long.BYTES) .putLong(Long.parseLong(text)) @@ -1007,7 +1001,7 @@ public void enterData(final ProgramParser.DataContext ctx) { } else if (ctx.HEX() != null) { type = "bytes"; base = "int"; - data = XeListener.bytesToHex( + data = XeEoListener.bytesToHex( ByteBuffer .allocate(Long.BYTES) .putLong(Long.parseLong(text.substring(2), 16)) @@ -1016,7 +1010,7 @@ public void enterData(final ProgramParser.DataContext ctx) { } else if (ctx.STRING() != null) { type = "bytes"; base = "string"; - data = XeListener.bytesToHex( + data = XeEoListener.bytesToHex( StringEscapeUtils.unescapeJava( text.substring(1, text.length() - 1) ).getBytes(StandardCharsets.UTF_8) @@ -1025,9 +1019,9 @@ public void enterData(final ProgramParser.DataContext ctx) { type = "bytes"; base = "string"; final int indent = ctx.getStart().getCharPositionInLine(); - data = XeListener.bytesToHex( + data = XeEoListener.bytesToHex( StringEscapeUtils.unescapeJava( - XeListener.trimMargin(text, indent) + XeEoListener.trimMargin(text, indent) ).getBytes(StandardCharsets.UTF_8) ); } else { @@ -1046,7 +1040,7 @@ public void enterData(final ProgramParser.DataContext ctx) { } @Override - public void exitData(final ProgramParser.DataContext ctx) { + public void exitData(final EoParser.DataContext ctx) { // Nothing here } @@ -1093,21 +1087,6 @@ private Objects startObject(final ParserRuleContext ctx) { ); } - /** - * Text source code. - * - * @param ctx Program context. - * @return Original code. - */ - private static String sourceText(final ProgramParser.ProgramContext ctx) { - return ctx.getStart().getInputStream().getText( - new Interval( - ctx.getStart().getStartIndex(), - ctx.getStop().getStopIndex() - ) - ); - } - /** * Trim margin from text block. * diff --git a/eo-parser/src/main/java/org/eolang/parser/XePhiListener.java b/eo-parser/src/main/java/org/eolang/parser/XePhiListener.java new file mode 100644 index 0000000000..ad86f00aa0 --- /dev/null +++ b/eo-parser/src/main/java/org/eolang/parser/XePhiListener.java @@ -0,0 +1,423 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2016-2023 Objectionary.com + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package org.eolang.parser; + +import com.jcabi.manifests.Manifests; +import java.time.ZoneOffset; +import java.time.ZonedDateTime; +import java.time.format.DateTimeFormatter; +import java.util.ArrayDeque; +import java.util.Collection; +import java.util.Deque; +import java.util.Iterator; +import java.util.Stack; +import org.antlr.v4.runtime.ParserRuleContext; +import org.antlr.v4.runtime.tree.ErrorNode; +import org.antlr.v4.runtime.tree.TerminalNode; +import org.cactoos.list.ListOf; +import org.xembly.Directive; +import org.xembly.Directives; + +/** + * The PHI-CALCULUS grammar listener for ANTLR4 walker. + * + * @checkstyle CyclomaticComplexityCheck (500 lines) + * @checkstyle ClassFanOutComplexityCheck (500 lines) + * @checkstyle MethodCountCheck (1300 lines) + * @since 0.34.0 + */ +@SuppressWarnings({ + "PMD.TooManyMethods", + "PMD.AvoidDuplicateLiterals", + "PMD.ExcessivePublicCount", + "PMD.ExcessiveClassLength" +}) +public final class XePhiListener implements PhiListener, Iterable { + /** + * Info about xmir. + */ + private static final XmirInfo INFO = new XmirInfo(); + + /** + * Package lambda. + */ + private static final String LAMBDA_PACKAGE = "Package"; + + /** + * Xembly directives we are building (mutable). + */ + private final Directives dirs; + + /** + * Attributes stack. + */ + private final Stack attributes; + + /** + * XMIR properties. + */ + private final Stack properties; + + /** + * Objects. + */ + private final Deque objs; + + /** + * Packages. + */ + private final Collection packages; + + /** + * When we start. + */ + private final long start; + + /** + * The name of it. + */ + private final String name; + + /** + * Ctor. + * @param nme The name of it + */ + public XePhiListener(final String nme) { + this.name = nme; + this.dirs = new Directives(); + this.objs = new ArrayDeque<>(); + this.attributes = new Stack<>(); + this.properties = new Stack<>(); + this.packages = new ListOf<>(); + this.start = System.nanoTime(); + } + + @Override + public void enterProgram(final PhiParser.ProgramContext ctx) { + this.objs.add(new Objects.ObjXembly()); + this.dirs.add("program") + .attr("name", this.name) + .attr("version", Manifests.read("EO-Version")) + .attr("revision", Manifests.read("EO-Revision")) + .attr("dob", Manifests.read("EO-Dob")) + .attr( + "time", + ZonedDateTime.now(ZoneOffset.UTC).format(DateTimeFormatter.ISO_INSTANT) + ) + .comment(XePhiListener.INFO) + .add("listing").set(new SourceText(ctx)).up() + .add("errors").up() + .add("sheets").up() + .add("license").up() + .add("metas").up(); + this.properties.push("name"); + } + + @Override + public void exitProgram(final PhiParser.ProgramContext ctx) { + this.properties.pop(); + if (!this.packages.isEmpty()) { + final String pckg = String.join(".", this.packages); + this.dirs.xpath("metas[last()]").strict(1) + .add("meta") + .add("head").set("package").up() + .add("tail").set(pckg).up() + .add("part").set(pckg).up() + .up().up(); + } + this.dirs.add("objects") + .append(this.objs.pollLast()) + .up() + .attr("ms", (System.nanoTime() - this.start) / (1000L * 1000L)); + } + + @Override + public void enterObject(final PhiParser.ObjectContext ctx) { + // Nothing here + } + + @Override + public void exitObject(final PhiParser.ObjectContext ctx) { + // Nothing here + } + + @Override + public void enterFormation(final PhiParser.FormationContext ctx) { + this.properties.push("name"); + } + + @Override + public void exitFormation(final PhiParser.FormationContext ctx) { + this.properties.pop(); + if (!XePhiListener.hasLambdaPackage(ctx.bindings())) { + this.objects() + .prop("abstract") + .prop("name", this.attributes.pop()); + } + } + + @Override + public void enterBindings(final PhiParser.BindingsContext ctx) { + if (XePhiListener.hasLambdaPackage(ctx)) { + this.packages.add(this.attributes.peek()); + this.objs.add(new Objects.ObjXembly()); + } + } + + @Override + public void exitBindings(final PhiParser.BindingsContext ctx) { + if (XePhiListener.hasLambdaPackage(ctx)) { + this.objs.poll(); + } + } + + @Override + public void enterBinding(final PhiParser.BindingContext ctx) { + if (ctx.alphaBinding() != null || ctx.emptyBinding() != null) { + this.objects().start(); + } + } + + @Override + public void exitBinding(final PhiParser.BindingContext ctx) { + if ((ctx.alphaBinding() != null || ctx.emptyBinding() != null) + && this.objs.size() > this.packages.size()) { + this.objects().leave(); + } + } + + @Override + public void enterAlphaBinding(final PhiParser.AlphaBindingContext ctx) { + // Nothing here + } + + @Override + public void exitAlphaBinding(final PhiParser.AlphaBindingContext ctx) { + // Nothing here + } + + @Override + @SuppressWarnings("PMD.ConfusingTernary") + public void enterAttribute(final PhiParser.AttributeContext ctx) { + final String attr; + if (ctx.PHI() != null) { + attr = "@"; + } else if (ctx.RHO() != null) { + attr = "^"; + } else if (ctx.SIGMA() != null) { + attr = "&"; + } else if (ctx.VTX() != null) { + attr = "<"; + } else if (ctx.LABEL() != null) { + attr = ctx.LABEL().getText(); + } else if (ctx.alpha() != null) { + attr = ctx.alpha().INDEX().getText(); + } else { + attr = ""; + } + this.attributes.push(attr); + } + + @Override + public void exitAttribute(final PhiParser.AttributeContext ctx) { + // Nothing here + } + + @Override + public void enterAlpha(final PhiParser.AlphaContext ctx) { + // Nothing here + } + + @Override + public void exitAlpha(final PhiParser.AlphaContext ctx) { + // Nothing here + } + + @Override + public void enterEmptyBinding(final PhiParser.EmptyBindingContext ctx) { + // Nothing here + } + + @Override + public void exitEmptyBinding(final PhiParser.EmptyBindingContext ctx) { + this.objects().prop("name", this.attributes.pop()); + } + + @Override + public void enterDeltaBidning(final PhiParser.DeltaBidningContext ctx) { + if (!ctx.BYTES().getText().equals("--")) { + this.objects().data( + ctx.BYTES().getText() + .replaceAll("-", " ") + .trim() + ); + } + } + + @Override + public void exitDeltaBidning(final PhiParser.DeltaBidningContext ctx) { + // Nothing here + } + + @Override + public void enterLambdaBidning(final PhiParser.LambdaBidningContext ctx) { + if (!ctx.FUNCTION().getText().equals(XePhiListener.LAMBDA_PACKAGE)) { + this.objects().prop("atom"); + } + } + + @Override + public void exitLambdaBidning(final PhiParser.LambdaBidningContext ctx) { + // Nothing here + } + + @Override + public void enterApplication(final PhiParser.ApplicationContext ctx) { + // Nothing here + } + + @Override + public void exitApplication(final PhiParser.ApplicationContext ctx) { + // Nothing here + } + + @Override + public void enterBnds(final PhiParser.BndsContext ctx) { + this.properties.push("as"); + } + + @Override + public void exitBnds(final PhiParser.BndsContext ctx) { + this.properties.pop(); + } + + @Override + @SuppressWarnings("PMD.ConfusingTernary") + public void enterDispatch(final PhiParser.DispatchContext ctx) { + if (ctx.HOME() != null) { + this.objects().prop("base", "Q").leave(); + } else if (ctx.XI() != null) { + this.objects().prop("base", "$").leave(); + } + } + + @Override + public void exitDispatch(final PhiParser.DispatchContext ctx) { + this.objects().enter(); + final String attribute = this.attributes.pop(); + if (!attribute.isEmpty()) { + this.objects().prop(this.properties.peek(), attribute); + } + } + + @Override + public void enterDisp(final PhiParser.DispContext ctx) { + // Nothing here + } + + @Override + public void exitDisp(final PhiParser.DispContext ctx) { + // Nothing here + } + + @Override + public void enterDispBnds(final PhiParser.DispBndsContext ctx) { + this.objects().enter(); + } + + @Override + public void exitDispBnds(final PhiParser.DispBndsContext ctx) { + this.objects().leave(); + } + + @Override + public void enterAttr(final PhiParser.AttrContext ctx) { + this.objects().start(); + } + + @Override + public void exitAttr(final PhiParser.AttrContext ctx) { + this.objects() + .prop("method") + .prop("base", String.format(".%s", this.attributes.pop())) + .leave(); + } + + @Override + public void enterTermination(final PhiParser.TerminationContext ctx) { + // Nothing here + } + + @Override + public void exitTermination(final PhiParser.TerminationContext ctx) { + // Nothing here + } + + @Override + public void visitTerminal(final TerminalNode node) { + // Nothing here + } + + @Override + public void visitErrorNode(final ErrorNode node) { + // Nothing here + } + + @Override + public void enterEveryRule(final ParserRuleContext ctx) { + // Nothing here + } + + @Override + public void exitEveryRule(final ParserRuleContext ctx) { + // Nothing here + } + + @Override + public Iterator iterator() { + return this.dirs.iterator(); + } + + /** + * Objects at the last level of stack. + * @return Objects + */ + private Objects objects() { + return this.objs.getLast(); + } + + /** + * Check if bindings on the given context have lambda package. + * @param ctx Context + * @return If bindings have lambda package + */ + private static boolean hasLambdaPackage(final PhiParser.BindingsContext ctx) { + return ctx.binding() + .stream() + .anyMatch( + context -> context.lambdaBidning() != null + && context.lambdaBidning().FUNCTION().getText().equals(XePhiListener.LAMBDA_PACKAGE) + ); + } +} diff --git a/eo-parser/src/main/java/org/eolang/parser/XmirInfo.java b/eo-parser/src/main/java/org/eolang/parser/XmirInfo.java new file mode 100644 index 0000000000..9492e8a539 --- /dev/null +++ b/eo-parser/src/main/java/org/eolang/parser/XmirInfo.java @@ -0,0 +1,44 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2016-2023 Objectionary.com + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package org.eolang.parser; + +/** + * Info about XMIR. + * @since 0.34.0 + */ +public final class XmirInfo { + /** + * Info about xmir. + */ + private static final String INFO = String.join( + "", + "This is XMIR - a dialect of XML, which is used to present a parsed EO program. ", + "For more information please visit https://news.eolang.org/2022-11-25-xmir-guide.html" + ); + + @Override + public String toString() { + return XmirInfo.INFO; + } +} diff --git a/eo-parser/src/test/java/org/eolang/parser/EoLexerTest.java b/eo-parser/src/test/java/org/eolang/parser/EoIndentLexerTest.java similarity index 84% rename from eo-parser/src/test/java/org/eolang/parser/EoLexerTest.java rename to eo-parser/src/test/java/org/eolang/parser/EoIndentLexerTest.java index 15d2986c92..392252d3a9 100644 --- a/eo-parser/src/test/java/org/eolang/parser/EoLexerTest.java +++ b/eo-parser/src/test/java/org/eolang/parser/EoIndentLexerTest.java @@ -30,55 +30,55 @@ import org.junit.jupiter.api.Test; /** - * Test for {@link EoLexer}. + * Test for {@link EoIndentLexer}. * * @since 1.0 */ -final class EoLexerTest { +final class EoIndentLexerTest { @Test void emitsTab() throws IOException { - final EoLexer lexer = new EoLexer( + final EoIndentLexer lexer = new EoIndentLexer( new TextOf("\n ") ); lexer.nextToken(); MatcherAssert.assertThat( lexer.nextToken().getType(), Matchers.is( - ProgramParser.TAB + EoParser.TAB ) ); } @Test void ensuresGrammarFile() throws IOException { - final EoLexer lexer = new EoLexer( + final EoIndentLexer lexer = new EoIndentLexer( new TextOf("") ); MatcherAssert.assertThat( lexer.getGrammarFileName(), Matchers.is( - "Program.g4" + "Eo.g4" ) ); } @Test void emitsTabWhenEmptyLine() throws IOException { - final EoLexer lexer = new EoLexer( + final EoIndentLexer lexer = new EoIndentLexer( new TextOf("\n\n ") ); lexer.nextToken(); MatcherAssert.assertThat( lexer.nextToken().getType(), Matchers.is( - ProgramParser.TAB + EoParser.TAB ) ); } @Test void emitsUntab() throws IOException { - final EoLexer lexer = new EoLexer( + final EoIndentLexer lexer = new EoIndentLexer( new TextOf("\n \n") ); lexer.nextToken(); @@ -87,20 +87,20 @@ void emitsUntab() throws IOException { MatcherAssert.assertThat( lexer.nextToken().getType(), Matchers.is( - ProgramParser.UNTAB + EoParser.UNTAB ) ); } @Test void readsEmptyString() throws IOException { - final EoLexer lexer = new EoLexer( + final EoIndentLexer lexer = new EoIndentLexer( new TextOf("") ); MatcherAssert.assertThat( lexer.nextToken().getType(), Matchers.is( - ProgramParser.EOF + EoParser.EOF ) ); } diff --git a/eo-parser/src/test/java/org/eolang/parser/SyntaxTest.java b/eo-parser/src/test/java/org/eolang/parser/EoSyntaxTest.java similarity index 65% rename from eo-parser/src/test/java/org/eolang/parser/SyntaxTest.java rename to eo-parser/src/test/java/org/eolang/parser/EoSyntaxTest.java index 086b893373..6757a7fe3d 100644 --- a/eo-parser/src/test/java/org/eolang/parser/SyntaxTest.java +++ b/eo-parser/src/test/java/org/eolang/parser/EoSyntaxTest.java @@ -26,14 +26,10 @@ import com.jcabi.matchers.XhtmlMatchers; import com.jcabi.xml.XML; import com.jcabi.xml.XMLDocument; -import com.yegor256.xsline.Xsline; -import java.io.ByteArrayOutputStream; import java.io.IOException; import java.nio.charset.StandardCharsets; import java.util.Map; -import org.cactoos.io.DeadOutput; import org.cactoos.io.InputOf; -import org.cactoos.io.OutputTo; import org.cactoos.io.ResourceOf; import org.cactoos.text.TextOf; import org.eolang.jucs.ClasspathSource; @@ -47,24 +43,22 @@ import org.yaml.snakeyaml.Yaml; /** - * Test case for {@link Xsline}. + * Test case for {@link EoSyntax}. * * @since 0.1 */ -final class SyntaxTest { - +final class EoSyntaxTest { @Test void parsesSimpleCode() throws Exception { - final ByteArrayOutputStream baos = new ByteArrayOutputStream(); - final Syntax syntax = new Syntax( - "test-1", - new ResourceOf("org/eolang/parser/fibonacci.eo"), - new OutputTo(baos) - ); - syntax.parse(); MatcherAssert.assertThat( XhtmlMatchers.xhtml( - new String(baos.toByteArray(), StandardCharsets.UTF_8) + new String( + new EoSyntax( + "test-1", + new ResourceOf("org/eolang/parser/fibonacci.eo") + ).parsed().toString().getBytes(), + StandardCharsets.UTF_8 + ) ), XhtmlMatchers.hasXPaths( "/program[@name='test-1']", @@ -78,17 +72,16 @@ void parsesSimpleCode() throws Exception { @Test void printsProperListingEvenWhenSyntaxIsBroken() throws Exception { - final ByteArrayOutputStream baos = new ByteArrayOutputStream(); final String src = "# hello, world!\n\n[] > x-н, 1\n"; - final Syntax syntax = new Syntax( - "test-44", - new InputOf(src), - new OutputTo(baos) - ); - syntax.parse(); MatcherAssert.assertThat( XhtmlMatchers.xhtml( - new String(baos.toByteArray(), StandardCharsets.UTF_8) + new String( + new EoSyntax( + "test-44", + new InputOf(src) + ).parsed().toString().getBytes(StandardCharsets.UTF_8), + StandardCharsets.UTF_8 + ) ), XhtmlMatchers.hasXPaths( "/program/errors[count(error)=2]", @@ -99,18 +92,17 @@ void printsProperListingEvenWhenSyntaxIsBroken() throws Exception { @Test void copiesListingCorrectly() throws Exception { - final ByteArrayOutputStream baos = new ByteArrayOutputStream(); final String src = new TextOf( new ResourceOf("org/eolang/parser/factorial.eo") ).asString(); - final Syntax syntax = new Syntax( - "test-22", - new InputOf(src), - new OutputTo(baos) - ); - syntax.parse(); final XML xml = new XMLDocument( - new String(baos.toByteArray(), StandardCharsets.UTF_8) + new String( + new EoSyntax( + "test-22", + new InputOf(src) + ).parsed().toString().getBytes(), + StandardCharsets.UTF_8 + ) ); MatcherAssert.assertThat( xml.xpath("/program/listing/text()"), @@ -131,27 +123,22 @@ void copiesListingCorrectly() throws Exception { "[] > x\n x ^ > @" }) void parsesSuccessfully(final String code) { - final Syntax syntax = new Syntax( + final EoSyntax syntax = new EoSyntax( "test-2", - new InputOf(code), - new DeadOutput() + new InputOf(code) ); Assertions.assertDoesNotThrow( - syntax::parse + syntax::parsed ); } @Test void parsesArrow() throws IOException { - final ByteArrayOutputStream baos = new ByteArrayOutputStream(); - final Syntax syntax = new Syntax( - "test-it-3", - new InputOf("1 > x"), - new OutputTo(baos) - ); - syntax.parse(); MatcherAssert.assertThat( - new XMLDocument(baos.toByteArray()), + new EoSyntax( + "test-it-3", + new InputOf("1 > x") + ).parsed(), XhtmlMatchers.hasXPaths( "/program/objects/o[@base='int' and @name='x' and ends-with(text(), '1')]" ) @@ -160,17 +147,13 @@ void parsesArrow() throws IOException { @Test void prasesNested() throws IOException { - final ByteArrayOutputStream baos = new ByteArrayOutputStream(); - final Syntax syntax = new Syntax( - "test-it-4", - new InputOf( - "[] > base\n memory 0 > x\n [self] > f\n v > @\n v\n" - ), - new OutputTo(baos) - ); - syntax.parse(); MatcherAssert.assertThat( - new XMLDocument(baos.toByteArray()), + new EoSyntax( + "test-it-4", + new InputOf( + "[] > base\n memory 0 > x\n [self] > f\n v > @\n v\n" + ) + ).parsed(), XhtmlMatchers.hasXPaths( "/program/objects[count(o)=1]", "/program/objects/o[count(o)=2]" @@ -180,17 +163,11 @@ void prasesNested() throws IOException { @Test void parsesDefinition() throws IOException { - final ByteArrayOutputStream baos = new ByteArrayOutputStream(); - final Syntax syntax = new Syntax( - "test-it-5", - new InputOf( - "[v] > p\n f.write > @\n" - ), - new OutputTo(baos) - ); - syntax.parse(); MatcherAssert.assertThat( - new XMLDocument(baos.toByteArray()), + new EoSyntax( + "test-it-5", + new InputOf("[v] > p\n f.write > @\n") + ).parsed(), XhtmlMatchers.hasXPaths( "/program/objects[count(o)=1]", "/program/objects/o[count(o)=3]" @@ -200,15 +177,11 @@ void parsesDefinition() throws IOException { @Test void parsesMethodCalls() throws IOException { - final ByteArrayOutputStream baos = new ByteArrayOutputStream(); - final Syntax syntax = new Syntax( - "test-it-1", - new InputOf("add.\n 0\n TRUE"), - new OutputTo(baos) - ); - syntax.parse(); MatcherAssert.assertThat( - new XMLDocument(baos.toByteArray()), + new EoSyntax( + "test-it-1", + new InputOf("add.\n 0\n TRUE") + ).parsed(), XhtmlMatchers.hasXPaths( "/program[@name='test-it-1']", "/program/objects/o[@base='.add']", @@ -224,15 +197,14 @@ void parsesMethodCalls() throws IOException { "TRUE > true" }) void storesAsBytes(final String code) throws IOException { - final ByteArrayOutputStream output = new ByteArrayOutputStream(); - final Syntax syntax = new Syntax( - "test-3", - new InputOf(code), - new OutputTo(output) - ); - syntax.parse(); final XML xml = new XMLDocument( - new String(output.toByteArray(), StandardCharsets.UTF_8) + new String( + new EoSyntax( + "test-3", + new InputOf(code) + ).parsed().toString().getBytes(), + StandardCharsets.UTF_8 + ) ); MatcherAssert.assertThat( xml, @@ -249,13 +221,10 @@ void checksTypoPacks(final String yml) throws IOException, NumberFormatException final Yaml yaml = new Yaml(); final Map map = yaml.load(yml); Assumptions.assumeTrue(map.get("skip") == null); - final ByteArrayOutputStream xmir = new ByteArrayOutputStream(); - new Syntax( + final XML xml = new EoSyntax( "typo", - new InputOf(String.format("%s\n", map.get("eo"))), - new OutputTo(xmir) - ).parse(); - final XML xml = new XMLDocument(xmir.toByteArray()); + new InputOf(String.format("%s\n", map.get("eo"))) + ).parsed(); MatcherAssert.assertThat( XhtmlMatchers.xhtml(xml.toString()), XhtmlMatchers.hasXPaths("/program/errors/error/@line") diff --git a/eo-parser/src/test/java/org/eolang/parser/XMIRTest.java b/eo-parser/src/test/java/org/eolang/parser/XMIRTest.java index 2998b237d3..5d4e92b4e5 100644 --- a/eo-parser/src/test/java/org/eolang/parser/XMIRTest.java +++ b/eo-parser/src/test/java/org/eolang/parser/XMIRTest.java @@ -26,13 +26,9 @@ import com.jcabi.log.Logger; import com.jcabi.xml.ClasspathSources; import com.jcabi.xml.XML; -import com.jcabi.xml.XMLDocument; -import com.jcabi.xml.XSL; import com.jcabi.xml.XSLDocument; -import java.io.ByteArrayOutputStream; import java.io.IOException; import org.cactoos.io.InputOf; -import org.cactoos.io.OutputTo; import org.eolang.jucs.ClasspathSource; import org.hamcrest.MatcherAssert; import org.hamcrest.Matchers; @@ -86,15 +82,13 @@ void printsToEO(final String src) throws Exception { * @throws IOException If fails */ private static XML parse(final String source) throws IOException { - final ByteArrayOutputStream baos = new ByteArrayOutputStream(); - final Syntax syntax = new Syntax( - "test", new InputOf(source), new OutputTo(baos) - ); - syntax.parse(); - final XSL wrap = new XSLDocument( + return new XSLDocument( XMIRTest.class.getResourceAsStream("wrap-method-calls.xsl") - ).with(new ClasspathSources()); - return wrap.transform(new XMLDocument(baos.toByteArray())); + ).with(new ClasspathSources()).transform( + new EoSyntax( + "test", new InputOf(source) + ).parsed() + ); } /**