diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 9e3393391..8e5abc7e0 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -18,15 +18,17 @@ jobs: java-version: '11' distribution: 'temurin' - - name: Generate JFlex files + - name: Install JFlex run: | sudo apt-get install -y jflex - ./benchmarks/generate_lexers.sh - - name: Generate ANTLR4 files + - name: Install ANTLR4 files run: | sudo apt-get install antlr4 - ./benchmarks/generate_antlr_classes.sh + + - name: Generate files + run: | + ./scripts/generate_all.sh - name: Build with Gradle uses: gradle/gradle-build-action@bd5760595778326ba7f1441bcf7e88b49de61a25 # v2.6.0 diff --git a/.gitignore b/.gitignore index 54882ea3f..60a20ab27 100644 --- a/.gitignore +++ b/.gitignore @@ -52,8 +52,6 @@ out/ hs_err_pid* .gradle -build/ -out/ !gradle/wrapper/gradle-wrapper.jar !**/src/main/**/build/ !**/src/test/**/build/ @@ -88,3 +86,9 @@ bin/ ### Generated files ### /gen/ +/benchmarks/src/main/java/org/antlr/* +!/benchmarks/src/main/java/org/antlr/Java8.g4 +/benchmarks/src/main/kotlin/org/ucfs/* +/benchmarks/src/main/java/org/ucfs/* +/benchmarks/logs/ +/examples/src/main/java/java7/JavaLexer.java diff --git a/benchmarks/README.md b/benchmarks/README.md new file mode 100644 index 000000000..834bee591 --- /dev/null +++ b/benchmarks/README.md @@ -0,0 +1,19 @@ +# UCFSBenchmarks + +## Prerequisites + +```text +(1) Gradle (version >= 7.2) +(2) Antlr V4 +(3) Jflex +``` +## Generate files +Run `/scripts/generate_all.sh` +## Run benchmarks +Set data-set folder and parser mode in script `/scripts/run_bench.sh` and run it + +## Logging + +Logs are stored in `logs` + +Results are stored in `build/reports/benchmarks` diff --git a/benchmarks/build.gradle.kts b/benchmarks/build.gradle.kts index 656654148..d67bc4335 100644 --- a/benchmarks/build.gradle.kts +++ b/benchmarks/build.gradle.kts @@ -1,7 +1,7 @@ plugins { java kotlin("jvm") version "1.9.20" - id("me.champeau.jmh") version "0.7.2" + id("org.jetbrains.kotlinx.benchmark") version "0.4.10" kotlin("plugin.allopen") version "1.9.20" } @@ -11,42 +11,64 @@ repositories { } dependencies { + //benchmarks tool + testImplementation("org.jetbrains.kotlin:kotlin-test") + implementation("org.jetbrains.kotlinx:kotlinx-benchmark-runtime:0.4.10") + //compared projects + // 1. for ucfs implementation(project(":solver")) + implementation(project(":generator")) + implementation(project(":examples")) + // 2. for java_cup (?) implementation("java_cup:java_cup:0.9e") + // 3. for antlr implementation("org.antlr:antlr4:4.13.1") - jmhImplementation("org.openjdk.jmh:jmh-core:1.36") - jmhImplementation("org.openjdk.jmh:jmh-generator-annprocess:1.36") - jmhImplementation("org.openjdk.jmh:jmh-generator-bytecode:1.36") + // 4. for iguana + implementation("io.usethesource:capsule:0.6.3") + implementation("info.picocli:picocli:4.7.0") + implementation("com.google.guava:guava-testlib:23.0") + implementation("com.fasterxml.jackson.core:jackson-core:2.14.0") + implementation("com.fasterxml.jackson.core:jackson-databind:2.14.0") } -kotlin { jvmToolchain(11) } -configure { - named("jmh") { - kotlin.srcDir("benchmarks/src/jmh/kotlin") - resources.srcDir("benchmarks/src/jmh/resources") +fun getArgs(strFolder: String): Array { + val resourcesDir = File(strFolder) + val files = resourcesDir.listFiles()!! + return files.map { it.toString() }.sorted().toTypedArray() +} + +benchmark { + configurations { + named("main") { + val dataset = "dataset" + if (!hasProperty(dataset)) { + println("BENCHMARKS FAILED! Set dataset folder by property '$dataset'") + } + else{ + param("fileName", *getArgs(property(dataset).toString())) + } + this.reportFormat = "csv" + iterations = 15 + iterationTime = 1000 + iterationTimeUnit = "ms" + warmups = 5 + outputTimeUnit = "ms" + mode = "avgt" + val tools = "toolName" + if (hasProperty(tools)) { + println("Run benchmarks for: .*${property(tools)}.*") + include(".*${property(tools)}.*") + } + + } + } + targets { + register("main") } } -jmh { - duplicateClassesStrategy = DuplicatesStrategy.EXCLUDE - zip64 = true - warmupForks = 0 - warmupBatchSize = 1 - warmupIterations = 5 - warmup = "0s" - timeOnIteration = "0s" - fork = 1 - batchSize = 1 - iterations = 15 - verbosity = "EXTRA" - jmhTimeout = "300s" - benchmarkMode.addAll("ss") - failOnError = false - forceGC = true - resultFormat = "CSV" - jvmArgs.addAll("-Xmx4096m", "-Xss4m", "-XX:+UseG1GC") +allOpen { + annotation("org.openjdk.jmh.annotations.State") } -tasks.processJmhResources { - duplicatesStrategy = DuplicatesStrategy.EXCLUDE -} \ No newline at end of file +kotlin { jvmToolchain(11) } \ No newline at end of file diff --git a/benchmarks/generate_antlr_classes.sh b/benchmarks/generate_antlr_classes.sh deleted file mode 100755 index 34637013a..000000000 --- a/benchmarks/generate_antlr_classes.sh +++ /dev/null @@ -1,7 +0,0 @@ -#!/bin/bash - -shopt -s nullglob #ingore failed patterns - -cd ./benchmarks/src/jmh/kotlin/antlr4 - -antlr4 Java8.g4 \ No newline at end of file diff --git a/benchmarks/generate_lexers.sh b/benchmarks/generate_lexers.sh deleted file mode 100755 index e6f390362..000000000 --- a/benchmarks/generate_lexers.sh +++ /dev/null @@ -1,10 +0,0 @@ -#!/bin/bash - -shopt -s nullglob #ingore failed patterns - -cd ./benchmarks/src/jmh/kotlin/lexers - -for lexer_name in *.jflex *.jlex *.lex *.flex *.x -do - jflex $lexer_name -done \ No newline at end of file diff --git a/benchmarks/gradle.properties b/benchmarks/gradle.properties new file mode 100644 index 000000000..2de43ab72 --- /dev/null +++ b/benchmarks/gradle.properties @@ -0,0 +1,3 @@ +kotlin.code.style=official +org.gradle.daemon=true +org.gradle.jvmargs=-Xmx4096m -Xss4m -XX:+UseG1GC \ No newline at end of file diff --git a/benchmarks/gradle/wrapper/gradle-wrapper.properties b/benchmarks/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 000000000..06febab41 --- /dev/null +++ b/benchmarks/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,5 @@ +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-8.2-bin.zip +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists \ No newline at end of file diff --git a/benchmarks/gradlew b/benchmarks/gradlew new file mode 100755 index 000000000..1b6c78733 --- /dev/null +++ b/benchmarks/gradlew @@ -0,0 +1,234 @@ +#!/bin/sh + +# +# Copyright © 2015-2021 the original authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +############################################################################## +# +# Gradle start up script for POSIX generated by Gradle. +# +# Important for running: +# +# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is +# noncompliant, but you have some other compliant shell such as ksh or +# bash, then to run this script, type that shell name before the whole +# command line, like: +# +# ksh Gradle +# +# Busybox and similar reduced shells will NOT work, because this script +# requires all of these POSIX shell features: +# * functions; +# * expansions «$var», «${var}», «${var:-default}», «${var+SET}», +# «${var#prefix}», «${var%suffix}», and «$( cmd )»; +# * compound commands having a testable exit status, especially «case»; +# * various built-in commands including «command», «set», and «ulimit». +# +# Important for patching: +# +# (2) This script targets any POSIX shell, so it avoids extensions provided +# by Bash, Ksh, etc; in particular arrays are avoided. +# +# The "traditional" practice of packing multiple parameters into a +# space-separated string is a well documented source of bugs and security +# problems, so this is (mostly) avoided, by progressively accumulating +# options in "$@", and eventually passing that to Java. +# +# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, +# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; +# see the in-line comments for details. +# +# There are tweaks for specific operating systems such as AIX, CygWin, +# Darwin, MinGW, and NonStop. +# +# (3) This script is generated from the Groovy template +# https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# within the Gradle project. +# +# You can find Gradle at https://github.com/gradle/gradle/. +# +############################################################################## + +# Attempt to set APP_HOME + +# Resolve links: $0 may be a link +app_path=$0 + +# Need this for daisy-chained symlinks. +while + APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path + [ -h "$app_path" ] +do + ls=$( ls -ld "$app_path" ) + link=${ls#*' -> '} + case $link in #( + /*) app_path=$link ;; #( + *) app_path=$APP_HOME$link ;; + esac +done + +APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit + +APP_NAME="Gradle" +APP_BASE_NAME=${0##*/} + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD=maximum + +warn () { + echo "$*" +} >&2 + +die () { + echo + echo "$*" + echo + exit 1 +} >&2 + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "$( uname )" in #( + CYGWIN* ) cygwin=true ;; #( + Darwin* ) darwin=true ;; #( + MSYS* | MINGW* ) msys=true ;; #( + NONSTOP* ) nonstop=true ;; +esac + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD=$JAVA_HOME/jre/sh/java + else + JAVACMD=$JAVA_HOME/bin/java + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD=java + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." +fi + +# Increase the maximum file descriptors if we can. +if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then + case $MAX_FD in #( + max*) + MAX_FD=$( ulimit -H -n ) || + warn "Could not query maximum file descriptor limit" + esac + case $MAX_FD in #( + '' | soft) :;; #( + *) + ulimit -n "$MAX_FD" || + warn "Could not set maximum file descriptor limit to $MAX_FD" + esac +fi + +# Collect all arguments for the java command, stacking in reverse order: +# * args from the command line +# * the main class name +# * -classpath +# * -D...appname settings +# * --module-path (only if needed) +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. + +# For Cygwin or MSYS, switch paths to Windows format before running java +if "$cygwin" || "$msys" ; then + APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) + CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) + + JAVACMD=$( cygpath --unix "$JAVACMD" ) + + # Now convert the arguments - kludge to limit ourselves to /bin/sh + for arg do + if + case $arg in #( + -*) false ;; # don't mess with options #( + /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath + [ -e "$t" ] ;; #( + *) false ;; + esac + then + arg=$( cygpath --path --ignore --mixed "$arg" ) + fi + # Roll the args list around exactly as many times as the number of + # args, so each arg winds up back in the position where it started, but + # possibly modified. + # + # NB: a `for` loop captures its iteration list before it begins, so + # changing the positional parameters here affects neither the number of + # iterations, nor the values presented in `arg`. + shift # remove old arg + set -- "$@" "$arg" # push replacement arg + done +fi + +# Collect all arguments for the java command; +# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of +# shell script including quotes and variable substitutions, so put them in +# double quotes to make sure that they get re-expanded; and +# * put everything else in single quotes, so that it's not re-expanded. + +set -- \ + "-Dorg.gradle.appname=$APP_BASE_NAME" \ + -classpath "$CLASSPATH" \ + org.gradle.wrapper.GradleWrapperMain \ + "$@" + +# Use "xargs" to parse quoted args. +# +# With -n1 it outputs one arg per line, with the quotes and backslashes removed. +# +# In Bash we could simply go: +# +# readarray ARGS < <( xargs -n1 <<<"$var" ) && +# set -- "${ARGS[@]}" "$@" +# +# but POSIX shell has neither arrays nor command substitution, so instead we +# post-process each arg (as a line of input to sed) to backslash-escape any +# character that might be a shell metacharacter, then use eval to reverse +# that process (while maintaining the separation between arguments), and wrap +# the whole thing up as a single "set" statement. +# +# This will of course break if any of these variables contains a newline or +# an unmatched quote. +# + +eval "set -- $( + printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | + xargs -n1 | + sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | + tr '\n' ' ' + )" '"$@"' + +exec "$JAVACMD" "$@" diff --git a/benchmarks/gradlew.bat b/benchmarks/gradlew.bat new file mode 100644 index 000000000..107acd32c --- /dev/null +++ b/benchmarks/gradlew.bat @@ -0,0 +1,89 @@ +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem + +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto execute + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto execute + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* + +:end +@rem End local scope for the variables with windows NT shell +if "%ERRORLEVEL%"=="0" goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 +exit /b 1 + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/benchmarks/src/jmh/kotlin/JmhBenchmark.kt b/benchmarks/src/jmh/kotlin/JmhBenchmark.kt deleted file mode 100644 index 94c49e50f..000000000 --- a/benchmarks/src/jmh/kotlin/JmhBenchmark.kt +++ /dev/null @@ -1,87 +0,0 @@ -package jmh.kotlin - - -import antlr4.Java8Parser -import antlr4.Java8Lexer -import lexers.JavaLexer -import lexers.JavaToken -import grammars.JavaGrammar -import org.antlr.v4.runtime.CharStreams -import org.antlr.v4.runtime.CommonTokenStream -import org.ucfs.parser.Gll -import org.openjdk.jmh.annotations.* -import org.openjdk.jmh.infra.Blackhole -import org.ucfs.input.LinearInputLabel -import org.ucfs.input.RecoveryLinearInput -import org.ucfs.rsm.symbol.Term -import java.io.File -import java.io.StringReader -import java.util.concurrent.TimeUnit - -val pathToInput = "benchmarks/src/jmh/resources/srcFiles/" - -fun getTokenStream(input: String): RecoveryLinearInput { - val inputGraph = RecoveryLinearInput() - val lexer = JavaLexer(StringReader(input)) - var vertexId = 0 - var token: JavaToken - - inputGraph.addStartVertex(vertexId) - inputGraph.addVertex(vertexId) - - while (true) { - token = lexer.yylex() as JavaToken - if (token == JavaToken.EOF) break - println(token.name) - inputGraph.addEdge(vertexId, LinearInputLabel(Term(token)), ++vertexId) - inputGraph.addVertex(vertexId) - } - - return inputGraph -} - -@State(Scope.Benchmark) -@BenchmarkMode(Mode.SingleShotTime) -open class AntlrBenchmark { - - @Param("OneTestCase_processed.java","NotPublicTestCase_processed.java","NoTestsRemainException_processed.java","OldTests_processed.java","TestRule_processed.java","JUnit4ClassRunner_processed.java","CategoryFilterFactoryTest_processed.java","TestClassTest_processed.java","ObjectContractTest_processed.java","LoggingStatement_processed.java","ThrowableMessageMatcher_processed.java","SortingRequest_processed.java","InheritedTestTest_processed.java","SerializableValueDescription_processed.java","JUnit3Builder_processed.java","FrameworkField_processed.java","JavadocTest_processed.java","SynchronizedRunListenerTest_processed.java","Ordering_processed.java","ClassRulesTest_processed.java","ComparisonCriteria_processed.java","TestDescriptionMethodNameTest_processed.java","JUnit4TestAdapterCache_processed.java","RuleContainer_processed.java","InvalidTestClassError_processed.java","JUnit4TestCaseFacade_processed.java","StubbedTheoriesTest_processed.java","FailedConstructionTest_processed.java","ReflectiveThreadMXBean_processed.java","Theory_processed.java","DataPoint_processed.java","Ignore_processed.java","ExpectedExceptionMatcherBuilder_processed.java","BlockJUnit4ClassRunnerWithParameters_processed.java","TestSystem_processed.java","TestWithParametersTest_processed.java","MultiCategoryTest_processed.java","AllMembersSupplier_processed.java","AnnotationsValidator_processed.java","ActiveTestSuite_processed.java","AssertTest_processed.java","RunListener_processed.java","Assume_processed.java","DataPoints_processed.java","TheoryTestUtils_processed.java","AllDefaultPossibilitiesBuilder_processed.java","TestRuleTest_processed.java","AllAssertionTests_processed.java","InvalidOrderingException_processed.java","ResultPrinter_processed.java","AllManipulationTests_processed.java","TextListenerTest_processed.java","Sortable_processed.java","ParameterizedNamesTest_processed.java","ParameterSignature_processed.java","RunnerBuilderStub_processed.java","ValidationTest_processed.java","StubbedTheories_processed.java","SuiteMethodBuilder_processed.java","AllRunnersTests_processed.java","PotentialAssignment_processed.java","StacktracePrintingMatcher_processed.java","Filterable_processed.java","SystemExitTest_processed.java","Filter_processed.java","MainRunner_processed.java","Result_processed.java","TemporaryFolderUsageTest_processed.java","AllTestsTest_processed.java","MultipleFailureException_processed.java","AssertionFailedError_processed.java","ParallelComputer_processed.java","AfterClass_processed.java","UseSuiteAsASuperclassTest_processed.java","ClassLevelMethodsWithIgnoredTestsTest_processed.java","MethodRulesTest_processed.java","Correspondent_processed.java","TypeMatchingBetweenMultiDataPointsMethod_processed.java","ActiveTestTest_processed.java","TestWatchman_processed.java","BadlyFormedClassesTest_processed.java","TestSuite_processed.java","MaxHistory_processed.java","AllParallelTests_processed.java","ComparisonCompactor_processed.java","ParameterSupplier_processed.java","AllClassesTests_processed.java","BlockJUnit4ClassRunnerWithParametersFactory_processed.java","AnnotatedBuilderTest_processed.java","AllExperimentalTests_processed.java","OverrideTestCase_processed.java","TempFolderRuleTest_processed.java","ComparisonFailureTest_processed.java","Parameterized_processed.java","ExpectExceptionTest_processed.java","PrintableResult_processed.java","ReflectiveRuntimeMXBean_processed.java","AllCoreTests_processed.java","ComparisonFailure_processed.java","RunAfters_processed.java","AlphanumericOrdering_processed.java","TestImplementorTest_processed.java","WithParameterSupplier_processed.java","WasRun_processed.java","MultipleFailureExceptionTest_processed.java","RuleChainTest_processed.java","TestListener_processed.java","Statement_processed.java","RepeatedTestTest_processed.java","BlockJUnit4ClassRunner_processed.java","FilterOptionIntegrationTest_processed.java","TestCaseTest_processed.java","ExpectedTest_processed.java","TextRunnerTest_processed.java","EnclosedTest_processed.java","InexactComparisonCriteria_processed.java","OrderWith_processed.java","IMoney_processed.java","UnsuccessfulWithDataPointFields_processed.java","Theories_processed.java","OrderableTest_processed.java","Protectable_processed.java","StacktracePrintingMatcherTest_processed.java","Description_processed.java","BlockJUnit4ClassRunnerTest_processed.java","ParentRunnerTest_processed.java","SuiteTest_processed.java","WithAutoGeneratedDataPoints_processed.java","ExpectException_processed.java","BaseTestRunnerTest_processed.java","TestDescriptionTest_processed.java","SynchronizedRunListener_processed.java","AllParameterizedTests_processed.java","AllModelTests_processed.java","Comparators_processed.java","ThreeTestCases_processed.java","RuleChain_processed.java","Computer_processed.java","TestClass_processed.java","SuiteDescriptionTest_processed.java","MaxCore_processed.java","CustomBlockJUnit4ClassRunnerTest_processed.java","MemoizingRequest_processed.java","ErrorReportingRunnerTest_processed.java","JUnit38ClassRunner_processed.java","TextListener_processed.java","FakeRuntimeMXBean_processed.java","PublicClassValidatorTest_processed.java","Timeout_processed.java","StopwatchTest_processed.java","ConcurrentRunNotifierTest_processed.java","TestCouldNotBeSkippedException_processed.java","Success_processed.java","LoggingMethodRule_processed.java","FilterFactoryParams_processed.java","AssumptionTest_processed.java","WithExtendedParameterSources_processed.java","FilterableTest_processed.java","AllDescriptionTests_processed.java","JUnit4_processed.java","AllRunnerTests_processed.java","SuiteMethodTest_processed.java","SingleMethodTest_processed.java","Describable_processed.java","JUnit4Builder_processed.java","FrameworkFieldTest_processed.java","IgnoreClassTest_processed.java","JUnitCommandLineParseResultTest_processed.java","MatcherTest_processed.java","ThrowableCauseMatcherTest_processed.java","AssumptionViolatedException_processed.java","CategoryValidatorTest_processed.java","ParentRunnerFilteringTest_processed.java","Orderable_processed.java","TestMethodTest_processed.java","ExternalResource_processed.java","ValidateWith_processed.java","AllCategoriesTests_processed.java","ExcludeCategories_processed.java","StoppedByUserException_processed.java","ParameterizedTestMethodTest_processed.java","FilterFactoriesTest_processed.java","RunBefores_processed.java","AllResultsTests_processed.java","ComparisonCompactorTest_processed.java","PrintableResultTest_processed.java","SampleJUnit3Tests_processed.java","ResultTest_processed.java","WithOnlyTestAnnotations_processed.java","Super_processed.java","TestedOn_processed.java","NullBuilder_processed.java","NoTestCases_processed.java","TestMethod_processed.java","Annotatable_processed.java","AssumptionViolatedExceptionTest_processed.java","NoArgTestCaseTest_processed.java","ErrorCollector_processed.java","AllSamplesTests_processed.java","RealSystem_processed.java","MethodSorterTest_processed.java","ForwardCompatibilityPrintingTest_processed.java","Guesser_processed.java","RepeatedTest_processed.java","TestSetup_processed.java","FilterFactory_processed.java","RuleContainerTest_processed.java","CouldNotReadCoreException_processed.java","ErrorReportingRunner_processed.java","FakeThreadMXBean_processed.java","VerifierRuleTest_processed.java","OrderWithValidator_processed.java","SpecificDataPointsSupplierTest_processed.java","WithDataPointMethod_processed.java","MethodValidator_processed.java","MemberValueConsumer_processed.java","ParentRunnerClassLoaderTest_processed.java","AllMethodsTests_processed.java","AllMembersSupplierTest_processed.java","RunRules_processed.java","ListenerTest_processed.java","RequestTest_processed.java","IgnoredBuilder_processed.java","IgnoredClassRunner_processed.java","SuiteMethod_processed.java","JUnitCoreTest_processed.java","TestResult_processed.java","NoGenericTypeParametersValidator_processed.java","RuleMemberValidator_processed.java","InitializationError_processed.java","Failure_processed.java","FilterTest_processed.java","ForwardCompatibilityTest_processed.java","RunnerBuilder_processed.java","AllTheoriesInternalTests_processed.java","IncludeCategories_processed.java","SuccessfulWithDataPointFields_processed.java","MaxStarterTest_processed.java","PublicClassValidator_processed.java","TypeSafeMatcher_processed.java","RuleMemberValidatorTest_processed.java","Stopwatch_processed.java","JUnitCommandLineParseResult_processed.java","RunWithTest_processed.java","TestWithParameters_processed.java","Categories_processed.java","MoneyBag_processed.java","JUnitMatchers_processed.java","FilterRequest_processed.java","ReguessableValue_processed.java","Stub_processed.java","OrderingRequest_processed.java","TimeoutRuleTest_processed.java","EnumSupplier_processed.java","JUnit38SortingTest_processed.java","AllInternalTests_processed.java","FailureList_processed.java","EventCollector_processed.java","MethodRule_processed.java","RunnerScheduler_processed.java","ErrorCollectorTest_processed.java","ArrayComparisonFailureTest_processed.java","InheritedTestCase_processed.java","ManagementFactory_processed.java","FailOnTimeout_processed.java","MethodSorters_processed.java","Category_processed.java","Checks_processed.java","AllJUnit3CompatibilityTests_processed.java","EachTestNotifier_processed.java","CategoryValidator_processed.java","ReflectiveCallable_processed.java","WithUnresolvedGenericTypeVariablesOnTheoryParms_processed.java","ParallelMethodTest_processed.java","TestWatcher_processed.java","TheoriesPerformanceTest_processed.java","TestListenerTest_processed.java","TestWithClassRule_processed.java","Fail_processed.java","ThrowableCauseMatcher_processed.java","DisableOnDebug_processed.java","AnnotationValidatorFactory_processed.java","RunnerSpy_processed.java","ParallelClassTest_processed.java","ParameterSignatureTest_processed.java","FrameworkMember_processed.java","TimeoutTest_processed.java","MethodRoadie_processed.java","OrderWithValidatorTest_processed.java","TemporaryFolder_processed.java","JUnit4TestAdapterTest_processed.java","NameRulesTest_processed.java","ListTest_processed.java","FailOnTimeoutTest_processed.java","ParameterizedAssertionError_processed.java","TestedOnSupplierTest_processed.java","TestName_processed.java","ParametersSuppliedBy_processed.java","Sub_processed.java","AllMaxTests_processed.java","Sorter_processed.java","ExternalResourceRuleTest_processed.java","ThreadsTest_processed.java","Version_processed.java","BaseTestRunner_processed.java","LoggingTestWatcher_processed.java","ExactComparisonCriteria_processed.java","Suite_processed.java","Before_processed.java","FailedBefore_processed.java","MoneyTest_processed.java","ExpectedException_processed.java","ExtensionTest_processed.java","RunNotifierTest_processed.java","OldTestClassAdaptingListenerTest_processed.java","Test_processed.java","AllNotificationTests_processed.java","ResultMatchersTest_processed.java","SampleJUnit4Tests_processed.java","ParentRunner_processed.java","AnnotationTest_processed.java","ThreadMXBean_processed.java","TestCase_processed.java","AnnotationValidator_processed.java","Money_processed.java","Assert_processed.java","DescriptionTest_processed.java","JUnit4TestAdapter_processed.java","WhenNoParametersMatch_processed.java","TestedOnSupplier_processed.java","ParameterizedTestTest_processed.java","FromDataPoints_processed.java","InvokeMethod_processed.java","ParameterizedAssertionErrorTest_processed.java","ClassRequest_processed.java","FilterFactories_processed.java","AllTests_processed.java","StackFilterTest_processed.java","RunWith_processed.java","UserStopTest_processed.java","TestWatchmanTest_processed.java","AllValidationTests_processed.java","Rule_processed.java","PotentialAssignmentTest_processed.java","Runner_processed.java","MethodSorter_processed.java","SortableTest_processed.java","AllTheoriesRunnerTests_processed.java","ValidationError_processed.java","ReverseAlphanumericSorter_processed.java","FailingDataPointMethods_processed.java","Enclosed_processed.java","FixMethodOrder_processed.java","AnnotationValidatorFactoryTest_processed.java","AnnotationsValidatorTest_processed.java","NoTestCaseClass_processed.java","TestWatcherTest_processed.java","NotVoidTestCase_processed.java","TestClassValidator_processed.java","SerializableMatcherDescription_processed.java","JUnit38ClassRunnerTest_processed.java","StringableObject_processed.java","AssertionFailedErrorTest_processed.java","LoggingTestRule_processed.java","package-info_processed.java","AnnotatedDescriptionTest_processed.java","DisableOnDebugTest_processed.java","RunnerTest_processed.java","GuesserQueue_processed.java","ArrayComparisonFailure_processed.java","Classes_processed.java","CategoryTest_processed.java","After_processed.java","OrderWithTest_processed.java","AnnotatedBuilder_processed.java","AllRunningTests_processed.java","WithNamedDataPoints_processed.java","JUnitSystem_processed.java","CommandLineTest_processed.java","CategoryFilterFactory_processed.java","ComparatorBasedOrdering_processed.java","Assignments_processed.java","BeforeClass_processed.java","CategoriesAndParameterizedTest_processed.java","TestTimedOutException_processed.java","TestDecorator_processed.java","TestRunListener_processed.java","InitializationErrorForwardCompatibilityTest_processed.java","AllDeprecatedTests_processed.java","BlockJUnit4ClassRunnerOverrideTest_processed.java","FrameworkMethod_processed.java","JUnitCore_processed.java","AllListeningTests_processed.java","TextFeedbackTest_processed.java","AllValidatorTests_processed.java","JUnitCoreReturnsCorrectExitCodeTest_processed.java","BlockJUnit4ClassRunnerWithParametersTest_processed.java","RunNotifier_processed.java","ThrowingRunnable_processed.java","RuntimeMXBean_processed.java","SpecificDataPointsSupplier_processed.java","TextRunnerSingleMethodTest_processed.java","AllRulesTests_processed.java","Alphanumeric_processed.java","StackTracesTest_processed.java","ClassRule_processed.java","AssumingInTheoriesTest_processed.java","TestFailure_processed.java","InvalidTestClassErrorTest_processed.java","BooleanSupplier_processed.java","ParametersRunnerFactory_processed.java","JUnit4ClassRunnerTest_processed.java","ResultMatchers_processed.java","ClassRequestTest_processed.java","Orderer_processed.java","TemporaryFolderRuleAssuredDeletionTest_processed.java","AllTheoriesTests_processed.java","MethodCall_processed.java","FrameworkMethodTest_processed.java","Request_processed.java","ExpectedExceptionTest_processed.java","TestRunner_processed.java","Verifier_processed.java","ReverseAlphanumericOrdering_processed.java","ClassRoadie_processed.java",) - var filename: String = "" - - lateinit var fileContents: String - - @Setup(Level.Trial) - fun prepare() { - fileContents = File(pathToInput + filename).readText() - } - - @Benchmark - @OutputTimeUnit(TimeUnit.NANOSECONDS) - fun measureAntlr(blackhole: Blackhole) { - val antlrParser = Java8Parser(CommonTokenStream(Java8Lexer(CharStreams.fromString(fileContents)))) - blackhole.consume(antlrParser.compilationUnit()) - } -} - -@State(Scope.Benchmark) -open class GllBenchmark { - @Param("OneTestCase_processed.java","NotPublicTestCase_processed.java","NoTestsRemainException_processed.java","OldTests_processed.java","TestRule_processed.java","JUnit4ClassRunner_processed.java","CategoryFilterFactoryTest_processed.java","TestClassTest_processed.java","ObjectContractTest_processed.java","LoggingStatement_processed.java","ThrowableMessageMatcher_processed.java","SortingRequest_processed.java","InheritedTestTest_processed.java","SerializableValueDescription_processed.java","JUnit3Builder_processed.java","FrameworkField_processed.java","JavadocTest_processed.java","SynchronizedRunListenerTest_processed.java","Ordering_processed.java","ClassRulesTest_processed.java","ComparisonCriteria_processed.java","TestDescriptionMethodNameTest_processed.java","JUnit4TestAdapterCache_processed.java","RuleContainer_processed.java","InvalidTestClassError_processed.java","JUnit4TestCaseFacade_processed.java","StubbedTheoriesTest_processed.java","FailedConstructionTest_processed.java","ReflectiveThreadMXBean_processed.java","Theory_processed.java","DataPoint_processed.java","Ignore_processed.java","ExpectedExceptionMatcherBuilder_processed.java","BlockJUnit4ClassRunnerWithParameters_processed.java","TestSystem_processed.java","TestWithParametersTest_processed.java","MultiCategoryTest_processed.java","AllMembersSupplier_processed.java","AnnotationsValidator_processed.java","ActiveTestSuite_processed.java","AssertTest_processed.java","RunListener_processed.java","Assume_processed.java","DataPoints_processed.java","TheoryTestUtils_processed.java","AllDefaultPossibilitiesBuilder_processed.java","TestRuleTest_processed.java","AllAssertionTests_processed.java","InvalidOrderingException_processed.java","ResultPrinter_processed.java","AllManipulationTests_processed.java","TextListenerTest_processed.java","Sortable_processed.java","ParameterizedNamesTest_processed.java","ParameterSignature_processed.java","RunnerBuilderStub_processed.java","ValidationTest_processed.java","StubbedTheories_processed.java","SuiteMethodBuilder_processed.java","AllRunnersTests_processed.java","PotentialAssignment_processed.java","StacktracePrintingMatcher_processed.java","Filterable_processed.java","SystemExitTest_processed.java","Filter_processed.java","MainRunner_processed.java","Result_processed.java","TemporaryFolderUsageTest_processed.java","AllTestsTest_processed.java","MultipleFailureException_processed.java","AssertionFailedError_processed.java","ParallelComputer_processed.java","AfterClass_processed.java","UseSuiteAsASuperclassTest_processed.java","ClassLevelMethodsWithIgnoredTestsTest_processed.java","MethodRulesTest_processed.java","Correspondent_processed.java","TypeMatchingBetweenMultiDataPointsMethod_processed.java","ActiveTestTest_processed.java","TestWatchman_processed.java","BadlyFormedClassesTest_processed.java","TestSuite_processed.java","MaxHistory_processed.java","AllParallelTests_processed.java","ComparisonCompactor_processed.java","ParameterSupplier_processed.java","AllClassesTests_processed.java","BlockJUnit4ClassRunnerWithParametersFactory_processed.java","AnnotatedBuilderTest_processed.java","AllExperimentalTests_processed.java","OverrideTestCase_processed.java","TempFolderRuleTest_processed.java","ComparisonFailureTest_processed.java","Parameterized_processed.java","ExpectExceptionTest_processed.java","PrintableResult_processed.java","ReflectiveRuntimeMXBean_processed.java","AllCoreTests_processed.java","ComparisonFailure_processed.java","RunAfters_processed.java","AlphanumericOrdering_processed.java","TestImplementorTest_processed.java","WithParameterSupplier_processed.java","WasRun_processed.java","MultipleFailureExceptionTest_processed.java","RuleChainTest_processed.java","TestListener_processed.java","Statement_processed.java","RepeatedTestTest_processed.java","BlockJUnit4ClassRunner_processed.java","FilterOptionIntegrationTest_processed.java","TestCaseTest_processed.java","ExpectedTest_processed.java","TextRunnerTest_processed.java","EnclosedTest_processed.java","InexactComparisonCriteria_processed.java","OrderWith_processed.java","IMoney_processed.java","UnsuccessfulWithDataPointFields_processed.java","Theories_processed.java","OrderableTest_processed.java","Protectable_processed.java","StacktracePrintingMatcherTest_processed.java","Description_processed.java","BlockJUnit4ClassRunnerTest_processed.java","ParentRunnerTest_processed.java","SuiteTest_processed.java","WithAutoGeneratedDataPoints_processed.java","ExpectException_processed.java","BaseTestRunnerTest_processed.java","TestDescriptionTest_processed.java","SynchronizedRunListener_processed.java","AllParameterizedTests_processed.java","AllModelTests_processed.java","Comparators_processed.java","ThreeTestCases_processed.java","RuleChain_processed.java","Computer_processed.java","TestClass_processed.java","SuiteDescriptionTest_processed.java","MaxCore_processed.java","CustomBlockJUnit4ClassRunnerTest_processed.java","MemoizingRequest_processed.java","ErrorReportingRunnerTest_processed.java","JUnit38ClassRunner_processed.java","TextListener_processed.java","FakeRuntimeMXBean_processed.java","PublicClassValidatorTest_processed.java","Timeout_processed.java","StopwatchTest_processed.java","ConcurrentRunNotifierTest_processed.java","TestCouldNotBeSkippedException_processed.java","Success_processed.java","LoggingMethodRule_processed.java","FilterFactoryParams_processed.java","AssumptionTest_processed.java","WithExtendedParameterSources_processed.java","FilterableTest_processed.java","AllDescriptionTests_processed.java","JUnit4_processed.java","AllRunnerTests_processed.java","SuiteMethodTest_processed.java","SingleMethodTest_processed.java","Describable_processed.java","JUnit4Builder_processed.java","FrameworkFieldTest_processed.java","IgnoreClassTest_processed.java","JUnitCommandLineParseResultTest_processed.java","MatcherTest_processed.java","ThrowableCauseMatcherTest_processed.java","AssumptionViolatedException_processed.java","CategoryValidatorTest_processed.java","ParentRunnerFilteringTest_processed.java","Orderable_processed.java","TestMethodTest_processed.java","ExternalResource_processed.java","ValidateWith_processed.java","AllCategoriesTests_processed.java","ExcludeCategories_processed.java","StoppedByUserException_processed.java","ParameterizedTestMethodTest_processed.java","FilterFactoriesTest_processed.java","RunBefores_processed.java","AllResultsTests_processed.java","ComparisonCompactorTest_processed.java","PrintableResultTest_processed.java","SampleJUnit3Tests_processed.java","ResultTest_processed.java","WithOnlyTestAnnotations_processed.java","Super_processed.java","TestedOn_processed.java","NullBuilder_processed.java","NoTestCases_processed.java","TestMethod_processed.java","Annotatable_processed.java","AssumptionViolatedExceptionTest_processed.java","NoArgTestCaseTest_processed.java","ErrorCollector_processed.java","AllSamplesTests_processed.java","RealSystem_processed.java","MethodSorterTest_processed.java","ForwardCompatibilityPrintingTest_processed.java","Guesser_processed.java","RepeatedTest_processed.java","TestSetup_processed.java","FilterFactory_processed.java","RuleContainerTest_processed.java","CouldNotReadCoreException_processed.java","ErrorReportingRunner_processed.java","FakeThreadMXBean_processed.java","VerifierRuleTest_processed.java","OrderWithValidator_processed.java","SpecificDataPointsSupplierTest_processed.java","WithDataPointMethod_processed.java","MethodValidator_processed.java","MemberValueConsumer_processed.java","ParentRunnerClassLoaderTest_processed.java","AllMethodsTests_processed.java","AllMembersSupplierTest_processed.java","RunRules_processed.java","ListenerTest_processed.java","RequestTest_processed.java","IgnoredBuilder_processed.java","IgnoredClassRunner_processed.java","SuiteMethod_processed.java","JUnitCoreTest_processed.java","TestResult_processed.java","NoGenericTypeParametersValidator_processed.java","RuleMemberValidator_processed.java","InitializationError_processed.java","Failure_processed.java","FilterTest_processed.java","ForwardCompatibilityTest_processed.java","RunnerBuilder_processed.java","AllTheoriesInternalTests_processed.java","IncludeCategories_processed.java","SuccessfulWithDataPointFields_processed.java","MaxStarterTest_processed.java","PublicClassValidator_processed.java","TypeSafeMatcher_processed.java","RuleMemberValidatorTest_processed.java","Stopwatch_processed.java","JUnitCommandLineParseResult_processed.java","RunWithTest_processed.java","TestWithParameters_processed.java","Categories_processed.java","MoneyBag_processed.java","JUnitMatchers_processed.java","FilterRequest_processed.java","ReguessableValue_processed.java","Stub_processed.java","OrderingRequest_processed.java","TimeoutRuleTest_processed.java","EnumSupplier_processed.java","JUnit38SortingTest_processed.java","AllInternalTests_processed.java","FailureList_processed.java","EventCollector_processed.java","MethodRule_processed.java","RunnerScheduler_processed.java","ErrorCollectorTest_processed.java","ArrayComparisonFailureTest_processed.java","InheritedTestCase_processed.java","ManagementFactory_processed.java","FailOnTimeout_processed.java","MethodSorters_processed.java","Category_processed.java","Checks_processed.java","AllJUnit3CompatibilityTests_processed.java","EachTestNotifier_processed.java","CategoryValidator_processed.java","ReflectiveCallable_processed.java","WithUnresolvedGenericTypeVariablesOnTheoryParms_processed.java","ParallelMethodTest_processed.java","TestWatcher_processed.java","TheoriesPerformanceTest_processed.java","TestListenerTest_processed.java","TestWithClassRule_processed.java","Fail_processed.java","ThrowableCauseMatcher_processed.java","DisableOnDebug_processed.java","AnnotationValidatorFactory_processed.java","RunnerSpy_processed.java","ParallelClassTest_processed.java","ParameterSignatureTest_processed.java","FrameworkMember_processed.java","TimeoutTest_processed.java","MethodRoadie_processed.java","OrderWithValidatorTest_processed.java","TemporaryFolder_processed.java","JUnit4TestAdapterTest_processed.java","NameRulesTest_processed.java","ListTest_processed.java","FailOnTimeoutTest_processed.java","ParameterizedAssertionError_processed.java","TestedOnSupplierTest_processed.java","TestName_processed.java","ParametersSuppliedBy_processed.java","Sub_processed.java","AllMaxTests_processed.java","Sorter_processed.java","ExternalResourceRuleTest_processed.java","ThreadsTest_processed.java","Version_processed.java","BaseTestRunner_processed.java","LoggingTestWatcher_processed.java","ExactComparisonCriteria_processed.java","Suite_processed.java","Before_processed.java","FailedBefore_processed.java","MoneyTest_processed.java","ExpectedException_processed.java","ExtensionTest_processed.java","RunNotifierTest_processed.java","OldTestClassAdaptingListenerTest_processed.java","Test_processed.java","AllNotificationTests_processed.java","ResultMatchersTest_processed.java","SampleJUnit4Tests_processed.java","ParentRunner_processed.java","AnnotationTest_processed.java","ThreadMXBean_processed.java","TestCase_processed.java","AnnotationValidator_processed.java","Money_processed.java","Assert_processed.java","DescriptionTest_processed.java","JUnit4TestAdapter_processed.java","WhenNoParametersMatch_processed.java","TestedOnSupplier_processed.java","ParameterizedTestTest_processed.java","FromDataPoints_processed.java","InvokeMethod_processed.java","ParameterizedAssertionErrorTest_processed.java","ClassRequest_processed.java","FilterFactories_processed.java","AllTests_processed.java","StackFilterTest_processed.java","RunWith_processed.java","UserStopTest_processed.java","TestWatchmanTest_processed.java","AllValidationTests_processed.java","Rule_processed.java","PotentialAssignmentTest_processed.java","Runner_processed.java","MethodSorter_processed.java","SortableTest_processed.java","AllTheoriesRunnerTests_processed.java","ValidationError_processed.java","ReverseAlphanumericSorter_processed.java","FailingDataPointMethods_processed.java","Enclosed_processed.java","FixMethodOrder_processed.java","AnnotationValidatorFactoryTest_processed.java","AnnotationsValidatorTest_processed.java","NoTestCaseClass_processed.java","TestWatcherTest_processed.java","NotVoidTestCase_processed.java","TestClassValidator_processed.java","SerializableMatcherDescription_processed.java","JUnit38ClassRunnerTest_processed.java","StringableObject_processed.java","AssertionFailedErrorTest_processed.java","LoggingTestRule_processed.java","package-info_processed.java","AnnotatedDescriptionTest_processed.java","DisableOnDebugTest_processed.java","RunnerTest_processed.java","GuesserQueue_processed.java","ArrayComparisonFailure_processed.java","Classes_processed.java","CategoryTest_processed.java","After_processed.java","OrderWithTest_processed.java","AnnotatedBuilder_processed.java","AllRunningTests_processed.java","WithNamedDataPoints_processed.java","JUnitSystem_processed.java","CommandLineTest_processed.java","CategoryFilterFactory_processed.java","ComparatorBasedOrdering_processed.java","Assignments_processed.java","BeforeClass_processed.java","CategoriesAndParameterizedTest_processed.java","TestTimedOutException_processed.java","TestDecorator_processed.java","TestRunListener_processed.java","InitializationErrorForwardCompatibilityTest_processed.java","AllDeprecatedTests_processed.java","BlockJUnit4ClassRunnerOverrideTest_processed.java","FrameworkMethod_processed.java","JUnitCore_processed.java","AllListeningTests_processed.java","TextFeedbackTest_processed.java","AllValidatorTests_processed.java","JUnitCoreReturnsCorrectExitCodeTest_processed.java","BlockJUnit4ClassRunnerWithParametersTest_processed.java","RunNotifier_processed.java","ThrowingRunnable_processed.java","RuntimeMXBean_processed.java","SpecificDataPointsSupplier_processed.java","TextRunnerSingleMethodTest_processed.java","AllRulesTests_processed.java","Alphanumeric_processed.java","StackTracesTest_processed.java","ClassRule_processed.java","AssumingInTheoriesTest_processed.java","TestFailure_processed.java","InvalidTestClassErrorTest_processed.java","BooleanSupplier_processed.java","ParametersRunnerFactory_processed.java","JUnit4ClassRunnerTest_processed.java","ResultMatchers_processed.java","ClassRequestTest_processed.java","Orderer_processed.java","TemporaryFolderRuleAssuredDeletionTest_processed.java","AllTheoriesTests_processed.java","MethodCall_processed.java","FrameworkMethodTest_processed.java","Request_processed.java","ExpectedExceptionTest_processed.java","TestRunner_processed.java","Verifier_processed.java","ReverseAlphanumericOrdering_processed.java","ClassRoadie_processed.java",) - var filename: String = "" - - val startState = JavaGrammar().rsm - - lateinit var fileContents: String - - @Setup(Level.Trial) - fun prepare() { - fileContents = File(pathToInput + filename).readText() - } - - @Benchmark - @OutputTimeUnit(TimeUnit.NANOSECONDS) - fun measureGll(blackhole: Blackhole) { - val inputGraph = getTokenStream(fileContents) - val gll = Gll.recoveryGll(startState, inputGraph) - - blackhole.consume(gll.parse()) - } -} diff --git a/benchmarks/src/jmh/kotlin/grammars/JavaGrammar.kt b/benchmarks/src/jmh/kotlin/grammars/JavaGrammar.kt deleted file mode 100644 index 36eeb9118..000000000 --- a/benchmarks/src/jmh/kotlin/grammars/JavaGrammar.kt +++ /dev/null @@ -1,546 +0,0 @@ -package grammars -import lexers.JavaToken -import org.ucfs.grammar.combinator.Grammar -import org.ucfs.grammar.combinator.regexp.* - -class JavaGrammar : Grammar() { - var CompilationUnit by Nt() - var Identifier by Nt() - var Literal by Nt() - var Type by Nt() - var PrimitiveType by Nt() - var ReferenceType by Nt() - var Annotation by Nt() - var NumericType by Nt() - var IntegralType by Nt() - var FloatingPointType by Nt() - var ClassOrInterfaceType by Nt() - var TypeVariable by Nt() - var ArrayType by Nt() - var ClassType by Nt() - var InterfaceType by Nt() - var TypeArguments by Nt() - var Dims by Nt() - var TypeParameter by Nt() - var TypeParameterModifier by Nt() - var TypeBound by Nt() - var AdditionalBound by Nt() - var TypeArgumentList by Nt() - var TypeArgument by Nt() - var Wildcard by Nt() - var WildcardBounds by Nt() - var TypeName by Nt() - var PackageOrTypeName by Nt() - var ExpressionName by Nt() - var AmbiguousName by Nt() - var MethodName by Nt() - var PackageName by Nt() - var Result by Nt() - var PackageDeclaration by Nt() - var ImportDeclaration by Nt() - var TypeDeclaration by Nt() - var PackageModifier by Nt() - var SingleTypeImportDeclaration by Nt() - var TypeImportOnDemandDeclaration by Nt() - var SingleStaticImportDeclaration by Nt() - var StaticImportOnDemandDeclaration by Nt() - var ClassDeclaration by Nt() - var InterfaceDeclaration by Nt() - var Throws by Nt() - var NormalClassDeclaration by Nt() - var EnumDeclaration by Nt() - var ClassModifier by Nt() - var TypeParameters by Nt() - var Superclass by Nt() - var Superinterfaces by Nt() - var ClassBody by Nt() - var TypeParameterList by Nt() - var InterfaceTypeList by Nt() - var ClassBodyDeclaration by Nt() - var ClassMemberDeclaration by Nt() - var InstanceInitializer by Nt() - var StaticInitializer by Nt() - var ConstructorDeclaration by Nt() - var FieldDeclaration by Nt() - var MethodDeclaration by Nt() - var FieldModifier by Nt() - var UnannType by Nt() - var VariableDeclaratorList by Nt() - var VariableDeclarator by Nt() - var VariableDeclaratorId by Nt() - var VariableInitializer by Nt() - var Expression by Nt() - var ArrayInitializer by Nt() - var UnannPrimitiveType by Nt() - var UnannReferenceType by Nt() - var UnannClassOrInterfaceType by Nt() - var UnannTypeVariable by Nt() - var UnannArrayType by Nt() - var UnannClassType by Nt() - var UnannInterfaceType by Nt() - var MethodModifier by Nt() - var MethodHeader by Nt() - var MethodBody by Nt() - var MethodDeclarator by Nt() - var FormalParameterList by Nt() - var ReceiverParameter by Nt() - var FormalParameters by Nt() - var LastFormalParameter by Nt() - var FormalParameter by Nt() - var VariableModifier by Nt() - var ExceptionTypeList by Nt() - var ExceptionType by Nt() - var Block by Nt() - var ConstructorModifier by Nt() - var ConstructorDeclarator by Nt() - var ConstructorBody by Nt() - var SimpleTypeName by Nt() - var ExplicitConstructorInvocation by Nt() - var EnumBody by Nt() - var EnumConstantList by Nt() - var EnumConstant by Nt() - var EnumConstantModifier by Nt() - var EnumBodyDeclarations by Nt() - var BlockStatements by Nt() - var ArgumentList by Nt() - var Primary by Nt() - var NormalInterfaceDeclaration by Nt() - var InterfaceModifier by Nt() - var ExtendsInterfaces by Nt() - var InterfaceBody by Nt() - var InterfaceMemberDeclaration by Nt() - var ConstantDeclaration by Nt() - var ConstantModifier by Nt() - var AnnotationTypeDeclaration by Nt() - var AnnotationTypeBody by Nt() - var AnnotationTypeMemberDeclaration by Nt() - var AnnotationTypeElementDeclaration by Nt() - var DefaultValue by Nt() - var NormalAnnotation by Nt() - var ElementValuePairList by Nt() - var ElementValuePair by Nt() - var ElementValue by Nt() - var ElementValueArrayInitializer by Nt() - var ElementValueList by Nt() - var MarkerAnnotation by Nt() - var SingleElementAnnotation by Nt() - var InterfaceMethodDeclaration by Nt() - var AnnotationTypeElementModifier by Nt() - var ConditionalExpression by Nt() - var VariableInitializerList by Nt() - var BlockStatement by Nt() - var LocalVariableDeclarationStatement by Nt() - var LocalVariableDeclaration by Nt() - var Statement by Nt() - var StatementNoShortIf by Nt() - var StatementWithoutTrailingSubstatement by Nt() - var EmptyStatement by Nt() - var LabeledStatement by Nt() - var LabeledStatementNoShortIf by Nt() - var ExpressionStatement by Nt() - var StatementExpression by Nt() - var IfThenStatement by Nt() - var IfThenElseStatement by Nt() - var IfThenElseStatementNoShortIf by Nt() - var AssertStatement by Nt() - var SwitchStatement by Nt() - var SwitchBlock by Nt() - var SwitchBlockStatementGroup by Nt() - var SwitchLabels by Nt() - var SwitchLabel by Nt() - var EnumConstantName by Nt() - var WhileStatement by Nt() - var WhileStatementNoShortIf by Nt() - var DoStatement by Nt() - var InterfaceMethodModifier by Nt() - var ForStatement by Nt() - var ForStatementNoShortIf by Nt() - var BasicForStatement by Nt() - var BasicForStatementNoShortIf by Nt() - var ForInit by Nt() - var ForUpdate by Nt() - var StatementExpressionList by Nt() - var EnhancedForStatement by Nt() - var EnhancedForStatementNoShortIf by Nt() - var BreakStatement by Nt() - var ContinueStatement by Nt() - var ReturnStatement by Nt() - var ThrowStatement by Nt() - var SynchronizedStatement by Nt() - var TryStatement by Nt() - var Catches by Nt() - var CatchClause by Nt() - var CatchFormalParameter by Nt() - var CatchType by Nt() - var Finally by Nt() - var TryWithResourcesStatement by Nt() - var ResourceSpecification by Nt() - var ResourceList by Nt() - var Resource by Nt() - var PrimaryNoNewArray by Nt() - var ClassLiteral by Nt() - var classOrInterfaceTypeToInstantiate by Nt() - var UnqualifiedClassInstanceCreationExpression by Nt() - var ClassInstanceCreationExpression by Nt() - var FieldAccess by Nt() - var TypeArgumentsOrDiamond by Nt() - var ArrayAccess by Nt() - var MethodInvocation by Nt() - var MethodReference by Nt() - var ArrayCreationExpression by Nt() - var DimExprs by Nt() - var DimExpr by Nt() - var LambdaExpression by Nt() - var LambdaParameters by Nt() - var InferredFormalParameterList by Nt() - var LambdaBody by Nt() - var AssignmentExpression by Nt() - var Assignment by Nt() - var LeftHandSide by Nt() - var AssignmentOperator by Nt() - var ConditionalOrExpression by Nt() - var ConditionalAndExpression by Nt() - var InclusiveOrExpression by Nt() - var ExclusiveOrExpression by Nt() - var AndExpression by Nt() - var EqualityExpression by Nt() - var RelationalExpression by Nt() - var ShiftExpression by Nt() - var AdditiveExpression by Nt() - var MultiplicativeExpression by Nt() - var PreIncrementExpression by Nt() - var PreDecrementExpression by Nt() - var UnaryExpressionNotPlusMinus by Nt() - var UnaryExpression by Nt() - var PostfixExpression by Nt() - var PostIncrementExpression by Nt() - var PostDecrementExpression by Nt() - var CastExpression by Nt() - var ConstantExpression by Nt() - - init { - Identifier = JavaToken.ID - - Literal = JavaToken.INTEGERLIT or JavaToken.FLOATINGLIT or JavaToken.BOOLEANLIT or - JavaToken.CHARLIT or JavaToken.STRINGLIT or JavaToken.NULLLIT - - /** - * Productions from §4 (Types, Values, and Variables) - */ - Type = PrimitiveType or ReferenceType - PrimitiveType = Many(Annotation) * NumericType or Many(Annotation) * JavaToken.BOOLEAN - NumericType = IntegralType or FloatingPointType - IntegralType = JavaToken.BYTE or JavaToken.SHORT or JavaToken.INT or JavaToken.LONG or JavaToken.CHAR - FloatingPointType = JavaToken.FLOAT or JavaToken.DOUBLE - ReferenceType = ClassOrInterfaceType or TypeVariable or ArrayType - ClassOrInterfaceType = ClassType or InterfaceType - ClassType = Many(Annotation) * Identifier * Option(TypeArguments) or - ClassOrInterfaceType * JavaToken.DOT * Many(Annotation) * Identifier * Option(TypeArguments) - InterfaceType = ClassType - TypeVariable = Many(Annotation) * Identifier - ArrayType = PrimitiveType * Dims or ClassOrInterfaceType * Dims or TypeVariable * Dims - Dims = Some(Many(Annotation) * JavaToken.BRACKETLEFT * JavaToken.BRACKETRIGHT) - TypeParameter = Many(TypeParameterModifier) * Identifier * Option(TypeBound) - TypeParameterModifier = Annotation - TypeBound = JavaToken.EXTENDS * TypeVariable or JavaToken.EXTENDS * ClassOrInterfaceType * Many(AdditionalBound) - AdditionalBound = JavaToken.ANDBIT * InterfaceType - TypeArguments = JavaToken.LT * TypeArgumentList * JavaToken.GT - TypeArgumentList = TypeArgument * Many(JavaToken.COMMA * TypeArgument) - TypeArgument = ReferenceType or Wildcard - Wildcard = Many(Annotation) * JavaToken.QUESTIONMARK * Option(WildcardBounds) - WildcardBounds = JavaToken.EXTENDS * ReferenceType or JavaToken.SUPER * ReferenceType - - /** - * Productions from §6 (Names) - */ - - TypeName = Identifier or PackageOrTypeName * JavaToken.DOT * Identifier - PackageOrTypeName = Identifier or PackageOrTypeName * JavaToken.DOT * Identifier - ExpressionName = Identifier or AmbiguousName * JavaToken.DOT * Identifier - MethodName = Identifier - PackageName = Identifier or PackageName * JavaToken.DOT * Identifier - AmbiguousName = Identifier or AmbiguousName * JavaToken.DOT * Identifier - - /** - * Productions from §7 (Packages) - */ - - CompilationUnit = Option(PackageDeclaration) * Many(ImportDeclaration) * Many(TypeDeclaration) - PackageDeclaration = Many(PackageModifier) * JavaToken.PACKAGE * Identifier * Many(JavaToken.DOT * Identifier) * JavaToken.SEMICOLON - PackageModifier = Annotation - ImportDeclaration = SingleTypeImportDeclaration or TypeImportOnDemandDeclaration or - SingleStaticImportDeclaration or StaticImportOnDemandDeclaration - SingleTypeImportDeclaration = JavaToken.IMPORT * TypeName * JavaToken.SEMICOLON - TypeImportOnDemandDeclaration = JavaToken.IMPORT * PackageOrTypeName * JavaToken.DOT * JavaToken.STAR * JavaToken.SEMICOLON - SingleStaticImportDeclaration = JavaToken.IMPORT * JavaToken.STATIC * TypeName * JavaToken.DOT * Identifier * JavaToken.SEMICOLON - StaticImportOnDemandDeclaration = JavaToken.IMPORT * JavaToken.STATIC * TypeName * JavaToken.DOT * JavaToken.STAR * JavaToken.SEMICOLON - TypeDeclaration = ClassDeclaration or InterfaceDeclaration or JavaToken.SEMICOLON - - /** - * Productions from §8 (Classes) - */ - - ClassDeclaration = NormalClassDeclaration or EnumDeclaration - NormalClassDeclaration = Many(ClassModifier) * JavaToken.CLASS * Identifier * - Option(TypeParameters) * Option(Superclass) * Option(Superinterfaces) * ClassBody - ClassModifier = Annotation or JavaToken.PUBLIC or JavaToken.PROTECTED or JavaToken.PRIVATE or - JavaToken.ABSTRACT or JavaToken.STATIC or JavaToken.FINAL or JavaToken.STRICTFP - TypeParameters = JavaToken.LT * TypeParameterList * JavaToken.GT - TypeParameterList = TypeParameter * Many(JavaToken.COMMA * TypeParameter) - Superclass = JavaToken.EXTENDS * ClassType - Superinterfaces = JavaToken.IMPLEMENTS * InterfaceTypeList - InterfaceTypeList = InterfaceType * Many(JavaToken.COMMA * InterfaceType) - ClassBody = JavaToken.CURLYLEFT * Many(ClassBodyDeclaration) * JavaToken.CURLYRIGHT - ClassBodyDeclaration = ClassMemberDeclaration or InstanceInitializer or StaticInitializer or ConstructorDeclaration - ClassMemberDeclaration = FieldDeclaration or MethodDeclaration or ClassDeclaration or InterfaceDeclaration or JavaToken.SEMICOLON - FieldDeclaration = Many(FieldModifier) * UnannType * VariableDeclaratorList * JavaToken.SEMICOLON - FieldModifier = Annotation or JavaToken.PUBLIC or JavaToken.PROTECTED or JavaToken.PRIVATE or JavaToken.STATIC or - JavaToken.FINAL or JavaToken.TRANSIENT or JavaToken.VOLATILE - VariableDeclaratorList = VariableDeclarator * Many(JavaToken.COMMA * VariableDeclarator) - VariableDeclarator = VariableDeclaratorId * Option(JavaToken.ASSIGN * VariableInitializer) - VariableDeclaratorId = Identifier * Option(Dims) - VariableInitializer = Expression or ArrayInitializer - UnannType = UnannPrimitiveType or UnannReferenceType - UnannPrimitiveType = NumericType or JavaToken.BOOLEAN - UnannReferenceType = UnannClassOrInterfaceType or UnannTypeVariable or UnannArrayType - UnannClassOrInterfaceType = UnannClassType or UnannInterfaceType - UnannClassType = Identifier * Option(TypeArguments) or - UnannClassOrInterfaceType * JavaToken.DOT * Many(Annotation) * Identifier * Option(TypeArguments) - UnannInterfaceType = UnannClassType - UnannTypeVariable = Identifier - UnannArrayType = UnannPrimitiveType * Dims or UnannClassOrInterfaceType * Dims or UnannTypeVariable * Dims - MethodDeclaration = Many(MethodModifier) * MethodHeader * MethodBody - MethodModifier = Annotation or JavaToken.PUBLIC or JavaToken.PROTECTED or JavaToken.PRIVATE or JavaToken.ABSTRACT or - JavaToken.STATIC or JavaToken.FINAL or JavaToken.SYNCHRONIZED or JavaToken.NATIVE or JavaToken.STRICTFP - MethodHeader = Result * MethodDeclarator * Option(Throws) or - TypeParameters * Many(Annotation) * Result * MethodDeclarator * Option(Throws) - Result = UnannType or JavaToken.VOID - MethodDeclarator = Identifier * JavaToken.PARENTHLEFT * Option(FormalParameterList) * JavaToken.PARENTHRIGHT * Option(Dims) - FormalParameterList = ReceiverParameter or FormalParameters * JavaToken.COMMA * LastFormalParameter or - LastFormalParameter - FormalParameters = FormalParameter * Many(JavaToken.COMMA * FormalParameter) or - ReceiverParameter * Many(JavaToken.COMMA * FormalParameter) - FormalParameter = Many(VariableModifier) * UnannType * VariableDeclaratorId - VariableModifier = Annotation or JavaToken.FINAL - LastFormalParameter = Many(VariableModifier) * UnannType * Many(Annotation) * JavaToken.ELLIPSIS * VariableDeclaratorId or FormalParameter - ReceiverParameter = Many(Annotation) * UnannType * Option(Identifier * JavaToken.DOT) * JavaToken.THIS - Throws = JavaToken.THROWS * ExceptionTypeList - ExceptionTypeList = ExceptionType * Many(JavaToken.COMMA * ExceptionType) - ExceptionType = ClassType or TypeVariable - MethodBody = Block or JavaToken.SEMICOLON - InstanceInitializer = Block - StaticInitializer = JavaToken.STATIC * Block - ConstructorDeclaration = Many(ConstructorModifier) * ConstructorDeclarator * Option(Throws) * ConstructorBody - ConstructorModifier = Annotation or JavaToken.PUBLIC or JavaToken.PROTECTED or JavaToken.PRIVATE - ConstructorDeclarator = Option(TypeParameters) * SimpleTypeName * JavaToken.PARENTHLEFT * Option(FormalParameterList) * JavaToken.PARENTHRIGHT - SimpleTypeName = Identifier - ConstructorBody = JavaToken.CURLYLEFT * Option(ExplicitConstructorInvocation) * Option(BlockStatements) * JavaToken.CURLYRIGHT - ExplicitConstructorInvocation = Option(TypeArguments) * JavaToken.THIS * JavaToken.PARENTHLEFT * Option(ArgumentList) * JavaToken.PARENTHRIGHT * JavaToken.SEMICOLON or - Option(TypeArguments) * JavaToken.SUPER * JavaToken.PARENTHLEFT * Option(ArgumentList) * JavaToken.PARENTHRIGHT * JavaToken.SEMICOLON or - ExpressionName * JavaToken.DOT * Option(TypeArguments) * JavaToken.SUPER * JavaToken.PARENTHLEFT * Option(ArgumentList) * JavaToken.PARENTHRIGHT * JavaToken.SEMICOLON or - Primary * JavaToken.DOT * Option(TypeArguments) * JavaToken.SUPER * JavaToken.PARENTHLEFT * Option(ArgumentList) * JavaToken.PARENTHRIGHT * JavaToken.SEMICOLON - EnumDeclaration = Many(ClassModifier) * JavaToken.ENUM * Identifier * Option(Superinterfaces) * EnumBody - EnumBody = JavaToken.CURLYLEFT * Option(EnumConstantList) * Option(JavaToken.COMMA) * Option(EnumBodyDeclarations) * JavaToken.CURLYRIGHT - EnumConstantList = EnumConstant * Many(JavaToken.COMMA * EnumConstant) - EnumConstant = Many(EnumConstantModifier) * Identifier * Option(JavaToken.PARENTHLEFT * Option(ArgumentList) * JavaToken.PARENTHRIGHT * Option(ClassBody)) - EnumConstantModifier = Annotation - EnumBodyDeclarations = JavaToken.SEMICOLON * Many(ClassBodyDeclaration) - - /** - * Productions from §9 (Interfaces) - */ - - InterfaceDeclaration = NormalInterfaceDeclaration or AnnotationTypeDeclaration - NormalInterfaceDeclaration = - Many(InterfaceModifier) * JavaToken.INTERFACE * Identifier * Option(TypeParameters) * Option(ExtendsInterfaces) * InterfaceBody - InterfaceModifier = Annotation or JavaToken.PUBLIC or JavaToken.PROTECTED or JavaToken.PRIVATE or - JavaToken.ABSTRACT or JavaToken.STATIC or JavaToken.STRICTFP - ExtendsInterfaces = JavaToken.EXTENDS * InterfaceTypeList - InterfaceBody = JavaToken.CURLYLEFT * Many(InterfaceMemberDeclaration) * JavaToken.CURLYRIGHT - InterfaceMemberDeclaration = ConstantDeclaration or InterfaceMethodDeclaration or ClassDeclaration or InterfaceDeclaration or JavaToken.SEMICOLON - ConstantDeclaration = Many(ConstantModifier) * UnannType * VariableDeclaratorList * JavaToken.SEMICOLON - ConstantModifier = Annotation or JavaToken.PUBLIC or JavaToken.STATIC or JavaToken.FINAL - InterfaceMethodDeclaration = Many(InterfaceMethodModifier) * MethodHeader * MethodBody - InterfaceMethodModifier = Annotation or JavaToken.PUBLIC or JavaToken.ABSTRACT or JavaToken.DEFAULT or JavaToken.STATIC or JavaToken.STRICTFP - AnnotationTypeDeclaration = Many(InterfaceModifier) * JavaToken.AT * JavaToken.INTERFACE * Identifier * AnnotationTypeBody - AnnotationTypeBody = JavaToken.CURLYLEFT * Many(AnnotationTypeMemberDeclaration) * JavaToken.CURLYRIGHT - AnnotationTypeMemberDeclaration = AnnotationTypeElementDeclaration or ConstantDeclaration or ClassDeclaration or InterfaceDeclaration or JavaToken.SEMICOLON - AnnotationTypeElementDeclaration = - Many(AnnotationTypeElementModifier) * UnannType * Identifier * JavaToken.PARENTHLEFT * JavaToken.PARENTHRIGHT * Option(Dims) * Option(DefaultValue) * JavaToken.SEMICOLON - AnnotationTypeElementModifier = Annotation or JavaToken.PUBLIC or JavaToken.ABSTRACT - DefaultValue = JavaToken.DEFAULT * ElementValue - Annotation = NormalAnnotation or MarkerAnnotation or SingleElementAnnotation - NormalAnnotation = JavaToken.AT * TypeName * JavaToken.PARENTHLEFT * Option(ElementValuePairList) * JavaToken.PARENTHRIGHT - ElementValuePairList = ElementValuePair * Many(JavaToken.COMMA * ElementValuePair) - ElementValuePair = Identifier * JavaToken.ASSIGN * ElementValue - ElementValue = ConditionalExpression or ElementValueArrayInitializer or Annotation - ElementValueArrayInitializer = JavaToken.CURLYLEFT * Option(ElementValueList) * Option(JavaToken.COMMA) * JavaToken.CURLYRIGHT - ElementValueList = ElementValue * Many(JavaToken.COMMA * ElementValue) - MarkerAnnotation = JavaToken.AT * TypeName - SingleElementAnnotation = JavaToken.AT * TypeName * JavaToken.PARENTHLEFT * ElementValue * JavaToken.PARENTHRIGHT - - /** - * Productions from §10 (Arrays) - */ - - ArrayInitializer = JavaToken.CURLYLEFT * Option(VariableInitializerList) * Option(JavaToken.COMMA) * JavaToken.CURLYRIGHT - VariableInitializerList = VariableInitializer * Many(JavaToken.COMMA * VariableInitializer) - - /** - * Productions from §14 (Blocks and Statements) - */ - - Block = JavaToken.CURLYLEFT * Option(BlockStatements) * JavaToken.CURLYRIGHT - BlockStatements = BlockStatement * Many(BlockStatement) - BlockStatement = LocalVariableDeclarationStatement or ClassDeclaration or Statement - LocalVariableDeclarationStatement = LocalVariableDeclaration * JavaToken.SEMICOLON - LocalVariableDeclaration = Many(VariableModifier) * UnannType * VariableDeclaratorList - Statement = StatementWithoutTrailingSubstatement or LabeledStatement or IfThenStatement or IfThenElseStatement or - WhileStatement or ForStatement - StatementNoShortIf = StatementWithoutTrailingSubstatement or LabeledStatementNoShortIf or IfThenElseStatementNoShortIf or - WhileStatementNoShortIf or ForStatementNoShortIf - StatementWithoutTrailingSubstatement = Block or EmptyStatement or ExpressionStatement or AssertStatement or - SwitchStatement or DoStatement or BreakStatement or ContinueStatement or ReturnStatement or SynchronizedStatement or - ThrowStatement or TryStatement - EmptyStatement = JavaToken.SEMICOLON - LabeledStatement = Identifier * JavaToken.COLON * Statement - LabeledStatementNoShortIf = Identifier * JavaToken.COLON * StatementNoShortIf - ExpressionStatement = StatementExpression * JavaToken.SEMICOLON - StatementExpression = Assignment or PreIncrementExpression or PreDecrementExpression or PostIncrementExpression or - PostDecrementExpression or MethodInvocation or ClassInstanceCreationExpression - IfThenStatement = JavaToken.IF * JavaToken.PARENTHLEFT * Expression * JavaToken.PARENTHRIGHT * Statement - IfThenElseStatement = JavaToken.IF * JavaToken.PARENTHLEFT * Expression * JavaToken.PARENTHRIGHT * StatementNoShortIf * JavaToken.ELSE * Statement - IfThenElseStatementNoShortIf = - JavaToken.IF * JavaToken.PARENTHLEFT * Expression * JavaToken.PARENTHRIGHT * StatementNoShortIf * JavaToken.ELSE * StatementNoShortIf - AssertStatement = JavaToken.ASSERT * Expression * JavaToken.SEMICOLON or - JavaToken.ASSERT * Expression * JavaToken.COLON * Expression * JavaToken.SEMICOLON - SwitchStatement = JavaToken.SWITCH * JavaToken.PARENTHLEFT * Expression * JavaToken.PARENTHRIGHT * SwitchBlock - SwitchBlock = JavaToken.CURLYLEFT * Many(SwitchBlockStatementGroup) * Many(SwitchLabel) * JavaToken.CURLYRIGHT - SwitchBlockStatementGroup = SwitchLabels * BlockStatements - SwitchLabels = Some(SwitchLabel) - SwitchLabel = JavaToken.CASE * ConstantExpression * JavaToken.COLON or - JavaToken.CASE * EnumConstantName * JavaToken.COLON or JavaToken.DEFAULT * JavaToken.COLON - EnumConstantName = Identifier - WhileStatement = JavaToken.WHILE * JavaToken.PARENTHLEFT * Expression * JavaToken.PARENTHRIGHT * Statement - WhileStatementNoShortIf = JavaToken.WHILE * JavaToken.PARENTHLEFT * Expression * JavaToken.PARENTHRIGHT * StatementNoShortIf - DoStatement = JavaToken.DO * Statement * JavaToken.WHILE * JavaToken.PARENTHLEFT * Expression * JavaToken.PARENTHRIGHT * JavaToken.SEMICOLON - ForStatement = BasicForStatement or EnhancedForStatement - ForStatementNoShortIf = BasicForStatementNoShortIf or EnhancedForStatementNoShortIf - BasicForStatement = JavaToken.FOR * JavaToken.PARENTHLEFT * Option(ForInit) * JavaToken.SEMICOLON * Option(Expression) * JavaToken.SEMICOLON * Option(ForUpdate) * JavaToken.PARENTHRIGHT * Statement - BasicForStatementNoShortIf = JavaToken.FOR * JavaToken.PARENTHLEFT * Option(ForInit) * JavaToken.SEMICOLON * Option(Expression) * JavaToken.SEMICOLON * Option(ForUpdate) * JavaToken.PARENTHRIGHT * StatementNoShortIf - ForInit = StatementExpressionList or LocalVariableDeclaration - ForUpdate = StatementExpressionList - StatementExpressionList = StatementExpression * Many(JavaToken.COMMA * StatementExpression) - EnhancedForStatement = JavaToken.FOR * JavaToken.PARENTHLEFT * Many(VariableModifier) * UnannType * VariableDeclaratorId * JavaToken.COLON * Expression * JavaToken.PARENTHRIGHT * Statement - EnhancedForStatementNoShortIf = JavaToken.FOR * JavaToken.PARENTHLEFT * Many(VariableModifier) * UnannType * VariableDeclaratorId * JavaToken.COLON * Expression * JavaToken.PARENTHRIGHT * StatementNoShortIf - BreakStatement = JavaToken.BREAK * Option(Identifier) * JavaToken.SEMICOLON - ContinueStatement = JavaToken.CONTINUE * Option(Identifier) * JavaToken.SEMICOLON - ReturnStatement = JavaToken.RETURN * Option(Expression) * JavaToken.SEMICOLON - ThrowStatement = JavaToken.THROW * Expression * JavaToken.SEMICOLON - SynchronizedStatement = JavaToken.SYNCHRONIZED * JavaToken.PARENTHLEFT * Expression * JavaToken.PARENTHRIGHT * Block - TryStatement = JavaToken.TRY * Block * Catches or JavaToken.TRY * Block * Option(Catches) * Finally or TryWithResourcesStatement - Catches = Some(CatchClause) - CatchClause = JavaToken.CATCH * JavaToken.PARENTHLEFT * CatchFormalParameter * JavaToken.PARENTHRIGHT * Block - CatchFormalParameter = Many(VariableModifier) * CatchType * VariableDeclaratorId - CatchType = UnannClassType * Many(JavaToken.ORBIT * ClassType) - Finally = JavaToken.FINALLY * Block - TryWithResourcesStatement = JavaToken.TRY * ResourceSpecification * Block * Option(Catches) * Option(Finally) - ResourceSpecification = JavaToken.PARENTHLEFT * ResourceList * Option(JavaToken.SEMICOLON) * JavaToken.PARENTHRIGHT - ResourceList = Resource * Many(JavaToken.COMMA * Resource) - Resource = Many(VariableModifier) * UnannType * VariableDeclaratorId * JavaToken.ASSIGN * Expression - - /** - * Productions from §15 (Expressions) - */ - - Primary = PrimaryNoNewArray or ArrayCreationExpression - PrimaryNoNewArray = Literal or ClassLiteral or JavaToken.THIS or TypeName * JavaToken.DOT * JavaToken.THIS or - JavaToken.PARENTHLEFT * Expression * JavaToken.PARENTHRIGHT or ClassInstanceCreationExpression or FieldAccess or - ArrayAccess or MethodInvocation or MethodReference - ClassLiteral = TypeName * Many(JavaToken.BRACKETLEFT * JavaToken.BRACKETRIGHT) * JavaToken.DOT * JavaToken.CLASS or - NumericType * Many(JavaToken.BRACKETLEFT * JavaToken.BRACKETRIGHT) * JavaToken.DOT * JavaToken.CLASS or - JavaToken.BOOLEAN * Many(JavaToken.BRACKETLEFT * JavaToken.BRACKETRIGHT) * JavaToken.DOT * JavaToken.CLASS or - JavaToken.VOID * JavaToken.DOT * JavaToken.CLASS - ClassInstanceCreationExpression = UnqualifiedClassInstanceCreationExpression or - ExpressionName * JavaToken.DOT * UnqualifiedClassInstanceCreationExpression or - Primary * JavaToken.DOT * UnqualifiedClassInstanceCreationExpression - UnqualifiedClassInstanceCreationExpression = - JavaToken.NEW * Option(TypeArguments) * classOrInterfaceTypeToInstantiate * JavaToken.PARENTHLEFT * Option(ArgumentList) * JavaToken.PARENTHRIGHT * Option(ClassBody) - classOrInterfaceTypeToInstantiate = Many(Annotation) * Identifier * Many(JavaToken.DOT * Many(Annotation) * Identifier) * Option(TypeArgumentsOrDiamond) - TypeArgumentsOrDiamond = TypeArguments or JavaToken.LT * JavaToken.GT - FieldAccess = Primary * JavaToken.DOT * Identifier or JavaToken.SUPER * JavaToken.DOT * Identifier or - TypeName * JavaToken.DOT * JavaToken.SUPER * JavaToken.DOT * Identifier - ArrayAccess = ExpressionName * JavaToken.BRACKETLEFT * Expression * JavaToken.BRACKETRIGHT or - PrimaryNoNewArray * JavaToken.BRACKETLEFT * Expression * JavaToken.BRACKETRIGHT - MethodInvocation = MethodName * JavaToken.PARENTHLEFT * Option(ArgumentList) * JavaToken.PARENTHRIGHT or - TypeName * JavaToken.DOT * Option(TypeArguments) * Identifier * JavaToken.PARENTHLEFT * Option(ArgumentList) * JavaToken.PARENTHRIGHT or - ExpressionName * JavaToken.DOT * Option(TypeArguments) * Identifier * JavaToken.PARENTHLEFT * Option(ArgumentList) * JavaToken.PARENTHRIGHT or - Primary * JavaToken.DOT * Option(TypeArguments) * Identifier * JavaToken.PARENTHLEFT * Option(ArgumentList) * JavaToken.PARENTHRIGHT or - JavaToken.SUPER * JavaToken.DOT * Option(TypeArguments) * Identifier * JavaToken.PARENTHLEFT * Option(ArgumentList) * JavaToken.PARENTHRIGHT or - TypeName * JavaToken.DOT * JavaToken.SUPER * JavaToken.DOT * Option(TypeArguments) * Identifier * JavaToken.PARENTHLEFT * Option(ArgumentList) * JavaToken.PARENTHRIGHT - ArgumentList = Expression * Many(JavaToken.COMMA * Expression) - MethodReference = ExpressionName * JavaToken.DOUBLECOLON * Option(TypeArguments) * Identifier or - ReferenceType * JavaToken.DOUBLECOLON * Option(TypeArguments) * Identifier or - Primary * JavaToken.DOUBLECOLON * Option(TypeArguments) * Identifier or - JavaToken.SUPER * JavaToken.DOUBLECOLON * Option(TypeArguments) * Identifier or - TypeName * JavaToken.DOT * JavaToken.SUPER * JavaToken.DOUBLECOLON * Option(TypeArguments) * Identifier or - ClassType * JavaToken.DOUBLECOLON * Option(TypeArguments) * JavaToken.NEW or - ArrayType * JavaToken.DOUBLECOLON * JavaToken.NEW - ArrayCreationExpression = JavaToken.NEW * PrimitiveType * DimExprs * Option(Dims) or - JavaToken.NEW * ClassOrInterfaceType * DimExprs * Option(Dims) or - JavaToken.NEW * PrimitiveType * Dims * ArrayInitializer or - JavaToken.NEW * ClassOrInterfaceType * Dims * ArrayInitializer - DimExprs = Some(DimExpr) - DimExpr = Many(Annotation) * JavaToken.BRACKETLEFT * Expression * JavaToken.BRACKETRIGHT - Expression = LambdaExpression or AssignmentExpression - LambdaExpression = LambdaParameters * JavaToken.ARROW * LambdaBody - LambdaParameters = Identifier or JavaToken.PARENTHLEFT * Option(FormalParameterList) * JavaToken.PARENTHRIGHT or - JavaToken.PARENTHLEFT * InferredFormalParameterList * JavaToken.PARENTHRIGHT - InferredFormalParameterList = Identifier * Many(JavaToken.COMMA * Identifier) - LambdaBody = Expression or Block - AssignmentExpression = ConditionalExpression or Assignment - Assignment = LeftHandSide * AssignmentOperator * Expression - LeftHandSide = ExpressionName or FieldAccess or ArrayAccess - AssignmentOperator = JavaToken.ASSIGN or JavaToken.STARASSIGN or JavaToken.SLASHASSIGN or JavaToken.PERCENTASSIGN or JavaToken.PLUSASSIGN or JavaToken.MINUSASSIGN or - JavaToken.SHIFTLEFTASSIGN or JavaToken.SHIFTRIGHTASSIGN or JavaToken.USRIGHTSHIFTASSIGN or JavaToken.ANDASSIGN or JavaToken.XORASSIGN or JavaToken.ORASSIGN - ConditionalExpression = ConditionalOrExpression or - ConditionalOrExpression * JavaToken.QUESTIONMARK * Expression * JavaToken.COLON * ConditionalExpression or - ConditionalOrExpression * JavaToken.QUESTIONMARK * Expression * JavaToken.COLON * LambdaExpression - ConditionalOrExpression = ConditionalAndExpression or - ConditionalOrExpression * JavaToken.OR * ConditionalAndExpression - ConditionalAndExpression = InclusiveOrExpression or - ConditionalAndExpression * JavaToken.AND * InclusiveOrExpression - InclusiveOrExpression = ExclusiveOrExpression or - InclusiveOrExpression * JavaToken.ORBIT * ExclusiveOrExpression - ExclusiveOrExpression = AndExpression or ExclusiveOrExpression * JavaToken.XORBIT * AndExpression - AndExpression = EqualityExpression or AndExpression * JavaToken.ANDBIT * EqualityExpression - EqualityExpression = RelationalExpression or EqualityExpression * JavaToken.EQ * RelationalExpression or - EqualityExpression * JavaToken.NOTEQ * RelationalExpression - RelationalExpression = ShiftExpression or RelationalExpression * JavaToken.LT * ShiftExpression or - RelationalExpression * JavaToken.GT * ShiftExpression or RelationalExpression * JavaToken.LESSEQ * ShiftExpression or - RelationalExpression * JavaToken.GREATEQ * ShiftExpression or RelationalExpression * JavaToken.INSTANCEOF * ReferenceType - ShiftExpression = AdditiveExpression or ShiftExpression * JavaToken.LT * JavaToken.LT * AdditiveExpression or - ShiftExpression * JavaToken.GT * JavaToken.GT * AdditiveExpression or - ShiftExpression * JavaToken.GT * JavaToken.GT * JavaToken.GT * AdditiveExpression - AdditiveExpression = MultiplicativeExpression or AdditiveExpression * JavaToken.PLUS * MultiplicativeExpression or - AdditiveExpression * JavaToken.MINUS * MultiplicativeExpression - MultiplicativeExpression = UnaryExpression or MultiplicativeExpression * JavaToken.STAR * UnaryExpression or - MultiplicativeExpression * JavaToken.SLASH * UnaryExpression or - MultiplicativeExpression * JavaToken.PERCENT * UnaryExpression - UnaryExpression = PreIncrementExpression or PreDecrementExpression or JavaToken.PLUS * UnaryExpression or - JavaToken.MINUS * UnaryExpression or UnaryExpressionNotPlusMinus - PreIncrementExpression = JavaToken.PLUSPLUS * UnaryExpression - PreDecrementExpression = JavaToken.MINUSMINUS * UnaryExpression - UnaryExpressionNotPlusMinus = PostfixExpression or JavaToken.TILDA * UnaryExpression or JavaToken.EXCLAMATIONMARK * UnaryExpression or - CastExpression - PostfixExpression = Primary or ExpressionName or PostIncrementExpression or PostDecrementExpression - PostIncrementExpression = PostfixExpression * JavaToken.PLUSPLUS - PostDecrementExpression = PostfixExpression * JavaToken.MINUSMINUS - CastExpression = JavaToken.PARENTHLEFT * PrimitiveType * JavaToken.PARENTHRIGHT * UnaryExpression or - JavaToken.PARENTHLEFT * ReferenceType * Many(AdditionalBound) * JavaToken.PARENTHRIGHT * UnaryExpressionNotPlusMinus or - JavaToken.PARENTHLEFT * ReferenceType * Many(AdditionalBound) * JavaToken.PARENTHRIGHT * LambdaExpression - ConstantExpression = Expression - - setStart(CompilationUnit) - } -} \ No newline at end of file diff --git a/benchmarks/src/jmh/kotlin/antlr4/Java8.g4 b/benchmarks/src/main/java/org/antlr/Java8.g4 similarity index 99% rename from benchmarks/src/jmh/kotlin/antlr4/Java8.g4 rename to benchmarks/src/main/java/org/antlr/Java8.g4 index 0a75e1741..af89ebed1 100644 --- a/benchmarks/src/jmh/kotlin/antlr4/Java8.g4 +++ b/benchmarks/src/main/java/org/antlr/Java8.g4 @@ -55,7 +55,7 @@ Total lexer+parser time 30844ms. grammar Java8; @header { -package antlr4; +package org.antlr; } /* diff --git a/benchmarks/src/main/kotlin/org/Antlr.kt b/benchmarks/src/main/kotlin/org/Antlr.kt new file mode 100644 index 000000000..dc1c59567 --- /dev/null +++ b/benchmarks/src/main/kotlin/org/Antlr.kt @@ -0,0 +1,25 @@ +package org + +import kotlinx.benchmark.* +import org.antlr.Java8Lexer +import org.antlr.Java8Parser +import org.antlr.v4.runtime.CharStreams +import org.antlr.v4.runtime.CommonTokenStream + + +@State(Scope.Benchmark) +class Antlr : BaseBench(){ + + @Benchmark + fun measureAntlr(blackhole: Blackhole) { + val antlrParser = + Java8Parser( + CommonTokenStream( + Java8Lexer( + CharStreams.fromString(fileContents) + ) + ) + ) + blackhole.consume(antlrParser.compilationUnit()) + } +} diff --git a/benchmarks/src/main/kotlin/org/BaseBench.kt b/benchmarks/src/main/kotlin/org/BaseBench.kt new file mode 100644 index 000000000..9bc706710 --- /dev/null +++ b/benchmarks/src/main/kotlin/org/BaseBench.kt @@ -0,0 +1,17 @@ +package org + +import kotlinx.benchmark.* +import java.io.File +@State(Scope.Benchmark) +abstract class BaseBench { + @Param("Throwables.java") + var fileName: String = "" + + lateinit var fileContents: String + + @Setup + open fun prepare() { + fileContents = File(fileName).readText() + } + +} \ No newline at end of file diff --git a/benchmarks/src/main/kotlin/org/Benchmarks.kt b/benchmarks/src/main/kotlin/org/Benchmarks.kt new file mode 100644 index 000000000..bc88c3e07 --- /dev/null +++ b/benchmarks/src/main/kotlin/org/Benchmarks.kt @@ -0,0 +1,58 @@ +package org + +import java7.JavaLexer +import java7.JavaToken +import org.ucfs.input.* +import org.ucfs.rsm.symbol.Term +import java.io.StringReader + +fun getResultPath( + pathToOutput: String, + inputName: String, + grammarMode: String, + grammarName: String, + sppfMode: String, +): String { + return pathToOutput + (if (pathToOutput.endsWith("/")) "" else "/") + "${inputName}_${grammarMode}_${grammarName}_${sppfMode}.csv" +} + + +fun getTokenStream(input: String): LinearInput { + val graph = LinearInput() + getTokenStream(input, graph) + return graph +} + + + +fun > getTokenStream(input: String, inputGraph: G): G { + val lexer = JavaLexer(StringReader(input)) + var token: JavaToken + var vertexId = 1 + + inputGraph.addVertex(vertexId) + inputGraph.addStartVertex(vertexId) + + while (true) { + token = lexer.yylex() as JavaToken + if (token == JavaToken.EOF) break + inputGraph.addEdge(vertexId, LinearInputLabel(token), ++vertexId) + } + + return inputGraph +} + +fun getCharStream(input: String): LinearInput { + val inputGraph = LinearInput() + var vertexId = 1 + + inputGraph.addVertex(vertexId) + inputGraph.addStartVertex(vertexId) + + for (ch in input) { + inputGraph.addEdge(vertexId, LinearInputLabel(Term(ch.toString())), ++vertexId) + inputGraph.addVertex(vertexId) + } + + return inputGraph +} diff --git a/benchmarks/src/main/kotlin/org/OfflineGll.kt b/benchmarks/src/main/kotlin/org/OfflineGll.kt new file mode 100644 index 000000000..0f74eaa6a --- /dev/null +++ b/benchmarks/src/main/kotlin/org/OfflineGll.kt @@ -0,0 +1,16 @@ +package org + +import kotlinx.benchmark.* +import org.ucfs.input.LinearInputLabel + + +@State(Scope.Benchmark) +class OfflineGll : BaseBench() { + + @Benchmark + fun measureGll(blackhole: Blackhole) { + val parser = org.ucfs.Java7Parser() + parser.input = getTokenStream(fileContents) + blackhole.consume(parser.parse()) + } +} diff --git a/benchmarks/src/main/kotlin/org/OnlineGll.kt b/benchmarks/src/main/kotlin/org/OnlineGll.kt new file mode 100644 index 000000000..8a3896b1e --- /dev/null +++ b/benchmarks/src/main/kotlin/org/OnlineGll.kt @@ -0,0 +1,29 @@ +package org + +import java7.Java7 +import kotlinx.benchmark.* +import org.junit.Before +import org.ucfs.input.LinearInput +import org.ucfs.input.LinearInputLabel +import org.ucfs.parser.Gll + + +@State(Scope.Benchmark) +class OnlineGll : BaseBench() { + + val startState = Java7().rsm + lateinit var tokens: LinearInput + + @Setup + @Before + override fun prepare() { + super.prepare() + tokens = getTokenStream(fileContents) + } + + @Benchmark + fun measureGll(blackhole: Blackhole) { + val gll = Gll.gll(startState, getTokenStream(fileContents)) + blackhole.consume(gll.parse()) + } +} diff --git a/benchmarks/src/main/kotlin/org/RecoveryOfflineGll.kt b/benchmarks/src/main/kotlin/org/RecoveryOfflineGll.kt new file mode 100644 index 000000000..316ef8809 --- /dev/null +++ b/benchmarks/src/main/kotlin/org/RecoveryOfflineGll.kt @@ -0,0 +1,15 @@ +package org + +import kotlinx.benchmark.* +import org.ucfs.input.LinearInputLabel + +@State(Scope.Benchmark) +class RecoveryOfflineGll : BaseBench() { + + @Benchmark + fun measureGll(blackhole: Blackhole) { + val parser = org.ucfs.Java7ParserRecovery() + parser.input = getTokenStream(fileContents) + blackhole.consume(parser.parse()) + } +} diff --git a/benchmarks/src/main/kotlin/org/RecoveryOnlineGll.kt b/benchmarks/src/main/kotlin/org/RecoveryOnlineGll.kt new file mode 100644 index 000000000..de020f5f1 --- /dev/null +++ b/benchmarks/src/main/kotlin/org/RecoveryOnlineGll.kt @@ -0,0 +1,29 @@ +package org + +import java7.Java7 +import kotlinx.benchmark.* +import org.junit.Before +import org.ucfs.input.LinearInput +import org.ucfs.input.LinearInputLabel +import org.ucfs.parser.Gll + + +@State(Scope.Benchmark) +class RecoveryOnlineGll : BaseBench() { + + val startState = Java7().rsm + lateinit var tokens: LinearInput + + @Setup + @Before + override fun prepare() { + super.prepare() + tokens = getTokenStream(fileContents) + } + + @Benchmark + fun measureGll(blackhole: Blackhole) { + val gll = Gll.recoveryGll(startState, getTokenStream(fileContents)) + blackhole.consume(gll.parse()) + } +} diff --git a/examples/build.gradle.kts b/examples/build.gradle.kts new file mode 100644 index 000000000..d3327a12b --- /dev/null +++ b/examples/build.gradle.kts @@ -0,0 +1,22 @@ +plugins { + + java + kotlin("jvm") version "1.9.20" + application +} + +group = "org.example" +version = "unspecified" + +application{ + mainClass = "java7.GeneratorKt" +} +repositories { + mavenCentral() +} + +dependencies { + implementation(project(":solver")) + implementation(project(":generator")) +} + diff --git a/benchmarks/src/jmh/kotlin/lexers/Java.x b/examples/src/main/java/java7/Java.x similarity index 98% rename from benchmarks/src/jmh/kotlin/lexers/Java.x rename to examples/src/main/java/java7/Java.x index b54c7e5ba..5e310aad3 100644 --- a/benchmarks/src/jmh/kotlin/lexers/Java.x +++ b/examples/src/main/java/java7/Java.x @@ -1,4 +1,4 @@ -package lexers; +package java7; import java.io.*; @@ -54,9 +54,9 @@ Comment = {TraditionalComment} | {DocumentationComment} TraditionalComment = "/*" [^*] ~"*/" | "/*" "*"+ "/" DocumentationComment = "/**" {CommentContent} "*"+ "/" CommentContent = ( [^*] | \*+ [^/*] )* - %% +"//".* { /* DO NOTHING */ } "boolean" { return JavaToken.BOOLEAN; } "byte" { return JavaToken.BYTE; } "short" { return JavaToken.SHORT; } diff --git a/examples/src/main/kotlin/dyck/DyckGrammar.kt b/examples/src/main/kotlin/dyck/DyckGrammar.kt new file mode 100644 index 000000000..940a5aa28 --- /dev/null +++ b/examples/src/main/kotlin/dyck/DyckGrammar.kt @@ -0,0 +1,19 @@ +package dyck + +import org.ucfs.grammar.combinator.Grammar +import org.ucfs.grammar.combinator.extension.StringExtension.times +import org.ucfs.grammar.combinator.regexp.Epsilon +import org.ucfs.grammar.combinator.regexp.Nt +import org.ucfs.grammar.combinator.regexp.or +import org.ucfs.grammar.combinator.regexp.times + +class DyckGrammar : Grammar() { + val S by Nt().asStart() + val Round by Nt("(" * S * ")") + val Quadrat by Nt("[" * S * "]") + val Curly by Nt("{" * S * "}") + + init { + S /= S * (Round or Quadrat or Curly) or Epsilon + } +} \ No newline at end of file diff --git a/examples/src/main/kotlin/java7/Generator.kt b/examples/src/main/kotlin/java7/Generator.kt new file mode 100644 index 000000000..955dff19a --- /dev/null +++ b/examples/src/main/kotlin/java7/Generator.kt @@ -0,0 +1,28 @@ +package java7 +import org.ucfs.parser.ParserGenerator +import org.ucfs.parser.RecoveryParserGenerator +import java.nio.file.Path +class Generator +fun main(args: Array){ + if(args.size != 1){ + throw IllegalArgumentException("Set first argument as path to generation") + } + val path = Path.of(args[0]) + println("Generate java7 UCFS parsers at ${path.toAbsolutePath()}") + generateJavaParser(path) + generateJavaRecoveryParser(path) +} + +fun generateJavaParser(path: Path) { + ParserGenerator( + Java7::class.java, + JavaToken::class.java + ).generate(path, "org.ucfs") +} +fun generateJavaRecoveryParser(path: Path) { + RecoveryParserGenerator( + Java7::class.java, + JavaToken::class.java + ).generate(path, "org.ucfs") +} + diff --git a/examples/src/main/kotlin/java7/Java7.kt b/examples/src/main/kotlin/java7/Java7.kt new file mode 100644 index 000000000..dcb27ed30 --- /dev/null +++ b/examples/src/main/kotlin/java7/Java7.kt @@ -0,0 +1,543 @@ +package java7 +import org.ucfs.grammar.combinator.Grammar +import org.ucfs.grammar.combinator.regexp.* + +class Java7 : Grammar() { + val CompilationUnit by Nt().asStart() + val Identifier by Nt() + val Literal by Nt() + val Type by Nt() + val PrimitiveType by Nt() + val ReferenceType by Nt() + val Annotation by Nt() + val NumericType by Nt() + val IntegralType by Nt() + val FloatingPointType by Nt() + val ClassOrInterfaceType by Nt() + val TypeVariable by Nt() + val ArrayType by Nt() + val ClassType by Nt() + val InterfaceType by Nt() + val TypeArguments by Nt() + val Dims by Nt() + val TypeParameter by Nt() + val TypeParameterModifier by Nt() + val TypeBound by Nt() + val AdditionalBound by Nt() + val TypeArgumentList by Nt() + val TypeArgument by Nt() + val Wildcard by Nt() + val WildcardBounds by Nt() + val TypeName by Nt() + val PackageOrTypeName by Nt() + val ExpressionName by Nt() + val AmbiguousName by Nt() + val MethodName by Nt() + val PackageName by Nt() + val Result by Nt() + val PackageDeclaration by Nt() + val ImportDeclaration by Nt() + val TypeDeclaration by Nt() + val PackageModifier by Nt() + val SingleTypeImportDeclaration by Nt() + val TypeImportOnDemandDeclaration by Nt() + val SingleStaticImportDeclaration by Nt() + val StaticImportOnDemandDeclaration by Nt() + val ClassDeclaration by Nt() + val InterfaceDeclaration by Nt() + val Throws by Nt() + val NormalClassDeclaration by Nt() + val EnumDeclaration by Nt() + val ClassModifier by Nt() + val TypeParameters by Nt() + val Superclass by Nt() + val Superinterfaces by Nt() + val ClassBody by Nt() + val TypeParameterList by Nt() + val InterfaceTypeList by Nt() + val ClassBodyDeclaration by Nt() + val ClassMemberDeclaration by Nt() + val InstanceInitializer by Nt() + val StaticInitializer by Nt() + val ConstructorDeclaration by Nt() + val FieldDeclaration by Nt() + val MethodDeclaration by Nt() + val FieldModifier by Nt() + val UnannType by Nt() + val VariableDeclaratorList by Nt() + val VariableDeclarator by Nt() + val VariableDeclaratorId by Nt() + val VariableInitializer by Nt() + val Expression by Nt() + val ArrayInitializer by Nt() + val UnannPrimitiveType by Nt() + val UnannReferenceType by Nt() + val UnannClassOrInterfaceType by Nt() + val UnannTypeVariable by Nt() + val UnannArrayType by Nt() + val UnannClassType by Nt() + val UnannInterfaceType by Nt() + val MethodModifier by Nt() + val MethodHeader by Nt() + val MethodBody by Nt() + val MethodDeclarator by Nt() + val FormalParameterList by Nt() + val ReceiverParameter by Nt() + val FormalParameters by Nt() + val LastFormalParameter by Nt() + val FormalParameter by Nt() + val VariableModifier by Nt() + val ExceptionTypeList by Nt() + val ExceptionType by Nt() + val Block by Nt() + val ConstructorModifier by Nt() + val ConstructorDeclarator by Nt() + val ConstructorBody by Nt() + val SimpleTypeName by Nt() + val ExplicitConstructorInvocation by Nt() + val EnumBody by Nt() + val EnumConstantList by Nt() + val EnumConstant by Nt() + val EnumConstantModifier by Nt() + val EnumBodyDeclarations by Nt() + val BlockStatements by Nt() + val ArgumentList by Nt() + val Primary by Nt() + val NormalInterfaceDeclaration by Nt() + val InterfaceModifier by Nt() + val ExtendsInterfaces by Nt() + val InterfaceBody by Nt() + val InterfaceMemberDeclaration by Nt() + val ConstantDeclaration by Nt() + val ConstantModifier by Nt() + val AnnotationTypeDeclaration by Nt() + val AnnotationTypeBody by Nt() + val AnnotationTypeMemberDeclaration by Nt() + val AnnotationTypeElementDeclaration by Nt() + val DefaultValue by Nt() + val NormalAnnotation by Nt() + val ElementValuePairList by Nt() + val ElementValuePair by Nt() + val ElementValue by Nt() + val ElementValueArrayInitializer by Nt() + val ElementValueList by Nt() + val MarkerAnnotation by Nt() + val SingleElementAnnotation by Nt() + val InterfaceMethodDeclaration by Nt() + val AnnotationTypeElementModifier by Nt() + val ConditionalExpression by Nt() + val VariableInitializerList by Nt() + val BlockStatement by Nt() + val LocalVariableDeclarationStatement by Nt() + val LocalVariableDeclaration by Nt() + val Statement by Nt() + val StatementNoShortIf by Nt() + val StatementWithoutTrailingSubstatement by Nt() + val EmptyStatement by Nt() + val LabeledStatement by Nt() + val LabeledStatementNoShortIf by Nt() + val ExpressionStatement by Nt() + val StatementExpression by Nt() + val IfThenStatement by Nt() + val IfThenElseStatement by Nt() + val IfThenElseStatementNoShortIf by Nt() + val AssertStatement by Nt() + val SwitchStatement by Nt() + val SwitchBlock by Nt() + val SwitchBlockStatementGroup by Nt() + val SwitchLabels by Nt() + val SwitchLabel by Nt() + val EnumConstantName by Nt() + val WhileStatement by Nt() + val WhileStatementNoShortIf by Nt() + val DoStatement by Nt() + val InterfaceMethodModifier by Nt() + val ForStatement by Nt() + val ForStatementNoShortIf by Nt() + val BasicForStatement by Nt() + val BasicForStatementNoShortIf by Nt() + val ForInit by Nt() + val ForUpdate by Nt() + val StatementExpressionList by Nt() + val EnhancedForStatement by Nt() + val EnhancedForStatementNoShortIf by Nt() + val BreakStatement by Nt() + val ContinueStatement by Nt() + val ReturnStatement by Nt() + val ThrowStatement by Nt() + val SynchronizedStatement by Nt() + val TryStatement by Nt() + val Catches by Nt() + val CatchClause by Nt() + val CatchFormalParameter by Nt() + val CatchType by Nt() + val Finally by Nt() + val TryWithResourcesStatement by Nt() + val ResourceSpecification by Nt() + val ResourceList by Nt() + val Resource by Nt() + val PrimaryNoNewArray by Nt() + val ClassLiteral by Nt() + val classOrInterfaceTypeToInstantiate by Nt() + val UnqualifiedClassInstanceCreationExpression by Nt() + val ClassInstanceCreationExpression by Nt() + val FieldAccess by Nt() + val TypeArgumentsOrDiamond by Nt() + val ArrayAccess by Nt() + val MethodInvocation by Nt() + val MethodReference by Nt() + val ArrayCreationExpression by Nt() + val DimExprs by Nt() + val DimExpr by Nt() + val LambdaExpression by Nt() + val LambdaParameters by Nt() + val InferredFormalParameterList by Nt() + val LambdaBody by Nt() + val AssignmentExpression by Nt() + val Assignment by Nt() + val LeftHandSide by Nt() + val AssignmentOperator by Nt() + val ConditionalOrExpression by Nt() + val ConditionalAndExpression by Nt() + val InclusiveOrExpression by Nt() + val ExclusiveOrExpression by Nt() + val AndExpression by Nt() + val EqualityExpression by Nt() + val RelationalExpression by Nt() + val ShiftExpression by Nt() + val AdditiveExpression by Nt() + val MultiplicativeExpression by Nt() + val PreIncrementExpression by Nt() + val PreDecrementExpression by Nt() + val UnaryExpressionNotPlusMinus by Nt() + val UnaryExpression by Nt() + val PostfixExpression by Nt() + val PostIncrementExpression by Nt() + val PostDecrementExpression by Nt() + val CastExpression by Nt() + val ConstantExpression by Nt() + + init { + Identifier /= JavaToken.ID + + Literal /= JavaToken.INTEGERLIT or JavaToken.FLOATINGLIT or JavaToken.BOOLEANLIT or + JavaToken.CHARLIT or JavaToken.STRINGLIT or JavaToken.NULLLIT + + /** + * Productions from §4 (Types, Values, and Variables) + */ + Type /= PrimitiveType or ReferenceType + PrimitiveType /= Many(Annotation) * NumericType or Many(Annotation) * JavaToken.BOOLEAN + NumericType /= IntegralType or FloatingPointType + IntegralType /= JavaToken.BYTE or JavaToken.SHORT or JavaToken.INT or JavaToken.LONG or JavaToken.CHAR + FloatingPointType /= JavaToken.FLOAT or JavaToken.DOUBLE + ReferenceType /= ClassOrInterfaceType or TypeVariable or ArrayType + ClassOrInterfaceType /= ClassType or InterfaceType + ClassType /= Many(Annotation) * Identifier * Option(TypeArguments) or + ClassOrInterfaceType * JavaToken.DOT * Many(Annotation) * Identifier * Option(TypeArguments) + InterfaceType /= ClassType + TypeVariable /= Many(Annotation) * Identifier + ArrayType /= PrimitiveType * Dims or ClassOrInterfaceType * Dims or TypeVariable * Dims + Dims /= some(Many(Annotation) * JavaToken.BRACKETLEFT * JavaToken.BRACKETRIGHT) + TypeParameter /= Many(TypeParameterModifier) * Identifier * Option(TypeBound) + TypeParameterModifier /= Annotation + TypeBound /= JavaToken.EXTENDS * TypeVariable or JavaToken.EXTENDS * ClassOrInterfaceType * Many(AdditionalBound) + AdditionalBound /= JavaToken.ANDBIT * InterfaceType + TypeArguments /= JavaToken.LT * TypeArgumentList * JavaToken.GT + TypeArgumentList /= TypeArgument * Many(JavaToken.COMMA * TypeArgument) + TypeArgument /= ReferenceType or Wildcard + Wildcard /= Many(Annotation) * JavaToken.QUESTIONMARK * Option(WildcardBounds) + WildcardBounds /= JavaToken.EXTENDS * ReferenceType or JavaToken.SUPER * ReferenceType + + /** + * Productions from §6 (Names) + */ + + TypeName /= Identifier or PackageOrTypeName * JavaToken.DOT * Identifier + PackageOrTypeName /= Identifier or PackageOrTypeName * JavaToken.DOT * Identifier + ExpressionName /= Identifier or AmbiguousName * JavaToken.DOT * Identifier + MethodName /= Identifier + PackageName /= Identifier or PackageName * JavaToken.DOT * Identifier + AmbiguousName /= Identifier or AmbiguousName * JavaToken.DOT * Identifier + + /** + * Productions from §7 (Packages) + */ + + CompilationUnit /= Option(PackageDeclaration) * Many(ImportDeclaration) * Many(TypeDeclaration) + PackageDeclaration /= Many(PackageModifier) * JavaToken.PACKAGE * Identifier * Many(JavaToken.DOT * Identifier) * JavaToken.SEMICOLON + PackageModifier /= Annotation + ImportDeclaration /= SingleTypeImportDeclaration or TypeImportOnDemandDeclaration or + SingleStaticImportDeclaration or StaticImportOnDemandDeclaration + SingleTypeImportDeclaration /= JavaToken.IMPORT * TypeName * JavaToken.SEMICOLON + TypeImportOnDemandDeclaration /= JavaToken.IMPORT * PackageOrTypeName * JavaToken.DOT * JavaToken.STAR * JavaToken.SEMICOLON + SingleStaticImportDeclaration /= JavaToken.IMPORT * JavaToken.STATIC * TypeName * JavaToken.DOT * Identifier * JavaToken.SEMICOLON + StaticImportOnDemandDeclaration /= JavaToken.IMPORT * JavaToken.STATIC * TypeName * JavaToken.DOT * JavaToken.STAR * JavaToken.SEMICOLON + TypeDeclaration /= ClassDeclaration or InterfaceDeclaration or JavaToken.SEMICOLON + + /** + * Productions from §8 (Classes) + */ + + ClassDeclaration /= NormalClassDeclaration or EnumDeclaration + NormalClassDeclaration /= Many(ClassModifier) * JavaToken.CLASS * Identifier * + Option(TypeParameters) * Option(Superclass) * Option(Superinterfaces) * ClassBody + ClassModifier /= Annotation or JavaToken.PUBLIC or JavaToken.PROTECTED or JavaToken.PRIVATE or + JavaToken.ABSTRACT or JavaToken.STATIC or JavaToken.FINAL or JavaToken.STRICTFP + TypeParameters /= JavaToken.LT * TypeParameterList * JavaToken.GT + TypeParameterList /= TypeParameter * Many(JavaToken.COMMA * TypeParameter) + Superclass /= JavaToken.EXTENDS * ClassType + Superinterfaces /= JavaToken.IMPLEMENTS * InterfaceTypeList + InterfaceTypeList /= InterfaceType * Many(JavaToken.COMMA * InterfaceType) + ClassBody /= JavaToken.CURLYLEFT * Many(ClassBodyDeclaration) * JavaToken.CURLYRIGHT + ClassBodyDeclaration /= ClassMemberDeclaration or InstanceInitializer or StaticInitializer or ConstructorDeclaration + ClassMemberDeclaration /= FieldDeclaration or MethodDeclaration or ClassDeclaration or InterfaceDeclaration or JavaToken.SEMICOLON + FieldDeclaration /= Many(FieldModifier) * UnannType * VariableDeclaratorList * JavaToken.SEMICOLON + FieldModifier /= Annotation or JavaToken.PUBLIC or JavaToken.PROTECTED or JavaToken.PRIVATE or JavaToken.STATIC or + JavaToken.FINAL or JavaToken.TRANSIENT or JavaToken.VOLATILE + VariableDeclaratorList /= VariableDeclarator * Many(JavaToken.COMMA * VariableDeclarator) + VariableDeclarator /= VariableDeclaratorId * Option(JavaToken.ASSIGN * VariableInitializer) + VariableDeclaratorId /= Identifier * Option(Dims) + VariableInitializer /= Expression or ArrayInitializer + UnannType /= UnannPrimitiveType or UnannReferenceType + UnannPrimitiveType /= NumericType or JavaToken.BOOLEAN + UnannReferenceType /= UnannClassOrInterfaceType or UnannTypeVariable or UnannArrayType + UnannClassOrInterfaceType /= UnannClassType or UnannInterfaceType + UnannClassType /= Identifier * Option(TypeArguments) or + UnannClassOrInterfaceType * JavaToken.DOT * Many(Annotation) * Identifier * Option(TypeArguments) + UnannInterfaceType /= UnannClassType + UnannTypeVariable /= Identifier + UnannArrayType /= UnannPrimitiveType * Dims or UnannClassOrInterfaceType * Dims or UnannTypeVariable * Dims + MethodDeclaration /= Many(MethodModifier) * MethodHeader * MethodBody + MethodModifier /= Annotation or JavaToken.PUBLIC or JavaToken.PROTECTED or JavaToken.PRIVATE or JavaToken.ABSTRACT or + JavaToken.STATIC or JavaToken.FINAL or JavaToken.SYNCHRONIZED or JavaToken.NATIVE or JavaToken.STRICTFP + MethodHeader /= Result * MethodDeclarator * Option(Throws) or + TypeParameters * Many(Annotation) * Result * MethodDeclarator * Option(Throws) + Result /= UnannType or JavaToken.VOID + MethodDeclarator /= Identifier * JavaToken.PARENTHLEFT * Option(FormalParameterList) * JavaToken.PARENTHRIGHT * Option(Dims) + FormalParameterList /= ReceiverParameter or FormalParameters * JavaToken.COMMA * LastFormalParameter or + LastFormalParameter + FormalParameters /= FormalParameter * Many(JavaToken.COMMA * FormalParameter) or + ReceiverParameter * Many(JavaToken.COMMA * FormalParameter) + FormalParameter /= Many(VariableModifier) * UnannType * VariableDeclaratorId + VariableModifier /= Annotation or JavaToken.FINAL + LastFormalParameter /= Many(VariableModifier) * UnannType * Many(Annotation) * JavaToken.ELLIPSIS * VariableDeclaratorId or FormalParameter + ReceiverParameter /= Many(Annotation) * UnannType * Option(Identifier * JavaToken.DOT) * JavaToken.THIS + Throws /= JavaToken.THROWS * ExceptionTypeList + ExceptionTypeList /= ExceptionType * Many(JavaToken.COMMA * ExceptionType) + ExceptionType /= ClassType or TypeVariable + MethodBody /= Block or JavaToken.SEMICOLON + InstanceInitializer /= Block + StaticInitializer /= JavaToken.STATIC * Block + ConstructorDeclaration /= Many(ConstructorModifier) * ConstructorDeclarator * Option(Throws) * ConstructorBody + ConstructorModifier /= Annotation or JavaToken.PUBLIC or JavaToken.PROTECTED or JavaToken.PRIVATE + ConstructorDeclarator /= Option(TypeParameters) * SimpleTypeName * JavaToken.PARENTHLEFT * Option(FormalParameterList) * JavaToken.PARENTHRIGHT + SimpleTypeName /= Identifier + ConstructorBody /= JavaToken.CURLYLEFT * Option(ExplicitConstructorInvocation) * Option(BlockStatements) * JavaToken.CURLYRIGHT + ExplicitConstructorInvocation /= Option(TypeArguments) * JavaToken.THIS * JavaToken.PARENTHLEFT * Option(ArgumentList) * JavaToken.PARENTHRIGHT * JavaToken.SEMICOLON or + Option(TypeArguments) * JavaToken.SUPER * JavaToken.PARENTHLEFT * Option(ArgumentList) * JavaToken.PARENTHRIGHT * JavaToken.SEMICOLON or + ExpressionName * JavaToken.DOT * Option(TypeArguments) * JavaToken.SUPER * JavaToken.PARENTHLEFT * Option(ArgumentList) * JavaToken.PARENTHRIGHT * JavaToken.SEMICOLON or + Primary * JavaToken.DOT * Option(TypeArguments) * JavaToken.SUPER * JavaToken.PARENTHLEFT * Option(ArgumentList) * JavaToken.PARENTHRIGHT * JavaToken.SEMICOLON + EnumDeclaration /= Many(ClassModifier) * JavaToken.ENUM * Identifier * Option(Superinterfaces) * EnumBody + EnumBody /= JavaToken.CURLYLEFT * Option(EnumConstantList) * Option(JavaToken.COMMA) * Option(EnumBodyDeclarations) * JavaToken.CURLYRIGHT + EnumConstantList /= EnumConstant * Many(JavaToken.COMMA * EnumConstant) + EnumConstant /= Many(EnumConstantModifier) * Identifier * Option(JavaToken.PARENTHLEFT * Option(ArgumentList) * JavaToken.PARENTHRIGHT * Option(ClassBody)) + EnumConstantModifier /= Annotation + EnumBodyDeclarations /= JavaToken.SEMICOLON * Many(ClassBodyDeclaration) + + /** + * Productions from §9 (Interfaces) + */ + + InterfaceDeclaration /= NormalInterfaceDeclaration or AnnotationTypeDeclaration + NormalInterfaceDeclaration /= + Many(InterfaceModifier) * JavaToken.INTERFACE * Identifier * Option(TypeParameters) * Option(ExtendsInterfaces) * InterfaceBody + InterfaceModifier /= Annotation or JavaToken.PUBLIC or JavaToken.PROTECTED or JavaToken.PRIVATE or + JavaToken.ABSTRACT or JavaToken.STATIC or JavaToken.STRICTFP + ExtendsInterfaces /= JavaToken.EXTENDS * InterfaceTypeList + InterfaceBody /= JavaToken.CURLYLEFT * Many(InterfaceMemberDeclaration) * JavaToken.CURLYRIGHT + InterfaceMemberDeclaration /= ConstantDeclaration or InterfaceMethodDeclaration or ClassDeclaration or InterfaceDeclaration or JavaToken.SEMICOLON + ConstantDeclaration /= Many(ConstantModifier) * UnannType * VariableDeclaratorList * JavaToken.SEMICOLON + ConstantModifier /= Annotation or JavaToken.PUBLIC or JavaToken.STATIC or JavaToken.FINAL + InterfaceMethodDeclaration /= Many(InterfaceMethodModifier) * MethodHeader * MethodBody + InterfaceMethodModifier /= Annotation or JavaToken.PUBLIC or JavaToken.ABSTRACT or JavaToken.DEFAULT or JavaToken.STATIC or JavaToken.STRICTFP + AnnotationTypeDeclaration /= Many(InterfaceModifier) * JavaToken.AT * JavaToken.INTERFACE * Identifier * AnnotationTypeBody + AnnotationTypeBody /= JavaToken.CURLYLEFT * Many(AnnotationTypeMemberDeclaration) * JavaToken.CURLYRIGHT + AnnotationTypeMemberDeclaration /= AnnotationTypeElementDeclaration or ConstantDeclaration or ClassDeclaration or InterfaceDeclaration or JavaToken.SEMICOLON + AnnotationTypeElementDeclaration /= + Many(AnnotationTypeElementModifier) * UnannType * Identifier * JavaToken.PARENTHLEFT * JavaToken.PARENTHRIGHT * Option(Dims) * Option(DefaultValue) * JavaToken.SEMICOLON + AnnotationTypeElementModifier /= Annotation or JavaToken.PUBLIC or JavaToken.ABSTRACT + DefaultValue /= JavaToken.DEFAULT * ElementValue + Annotation /= NormalAnnotation or MarkerAnnotation or SingleElementAnnotation + NormalAnnotation /= JavaToken.AT * TypeName * JavaToken.PARENTHLEFT * Option(ElementValuePairList) * JavaToken.PARENTHRIGHT + ElementValuePairList /= ElementValuePair * Many(JavaToken.COMMA * ElementValuePair) + ElementValuePair /= Identifier * JavaToken.ASSIGN * ElementValue + ElementValue /= ConditionalExpression or ElementValueArrayInitializer or Annotation + ElementValueArrayInitializer /= JavaToken.CURLYLEFT * Option(ElementValueList) * Option(JavaToken.COMMA) * JavaToken.CURLYRIGHT + ElementValueList /= ElementValue * Many(JavaToken.COMMA * ElementValue) + MarkerAnnotation /= JavaToken.AT * TypeName + SingleElementAnnotation /= JavaToken.AT * TypeName * JavaToken.PARENTHLEFT * ElementValue * JavaToken.PARENTHRIGHT + + /** + * Productions from §10 (Arrays) + */ + + ArrayInitializer /= JavaToken.CURLYLEFT * Option(VariableInitializerList) * Option(JavaToken.COMMA) * JavaToken.CURLYRIGHT + VariableInitializerList /= VariableInitializer * Many(JavaToken.COMMA * VariableInitializer) + + /** + * Productions from §14 (Blocks and Statements) + */ + + Block /= JavaToken.CURLYLEFT * Option(BlockStatements) * JavaToken.CURLYRIGHT + BlockStatements /= BlockStatement * Many(BlockStatement) + BlockStatement /= LocalVariableDeclarationStatement or ClassDeclaration or Statement + LocalVariableDeclarationStatement /= LocalVariableDeclaration * JavaToken.SEMICOLON + LocalVariableDeclaration /= Many(VariableModifier) * UnannType * VariableDeclaratorList + Statement /= StatementWithoutTrailingSubstatement or LabeledStatement or IfThenStatement or IfThenElseStatement or + WhileStatement or ForStatement + StatementNoShortIf /= StatementWithoutTrailingSubstatement or LabeledStatementNoShortIf or IfThenElseStatementNoShortIf or + WhileStatementNoShortIf or ForStatementNoShortIf + StatementWithoutTrailingSubstatement /= Block or EmptyStatement or ExpressionStatement or AssertStatement or + SwitchStatement or DoStatement or BreakStatement or ContinueStatement or ReturnStatement or SynchronizedStatement or + ThrowStatement or TryStatement + EmptyStatement /= JavaToken.SEMICOLON + LabeledStatement /= Identifier * JavaToken.COLON * Statement + LabeledStatementNoShortIf /= Identifier * JavaToken.COLON * StatementNoShortIf + ExpressionStatement /= StatementExpression * JavaToken.SEMICOLON + StatementExpression /= Assignment or PreIncrementExpression or PreDecrementExpression or PostIncrementExpression or + PostDecrementExpression or MethodInvocation or ClassInstanceCreationExpression + IfThenStatement /= JavaToken.IF * JavaToken.PARENTHLEFT * Expression * JavaToken.PARENTHRIGHT * Statement + IfThenElseStatement /= JavaToken.IF * JavaToken.PARENTHLEFT * Expression * JavaToken.PARENTHRIGHT * StatementNoShortIf * JavaToken.ELSE * Statement + IfThenElseStatementNoShortIf /= + JavaToken.IF * JavaToken.PARENTHLEFT * Expression * JavaToken.PARENTHRIGHT * StatementNoShortIf * JavaToken.ELSE * StatementNoShortIf + AssertStatement /= JavaToken.ASSERT * Expression * JavaToken.SEMICOLON or + JavaToken.ASSERT * Expression * JavaToken.COLON * Expression * JavaToken.SEMICOLON + SwitchStatement /= JavaToken.SWITCH * JavaToken.PARENTHLEFT * Expression * JavaToken.PARENTHRIGHT * SwitchBlock + SwitchBlock /= JavaToken.CURLYLEFT * Many(SwitchBlockStatementGroup) * Many(SwitchLabel) * JavaToken.CURLYRIGHT + SwitchBlockStatementGroup /= SwitchLabels * BlockStatements + SwitchLabels /= some(SwitchLabel) + SwitchLabel /= JavaToken.CASE * ConstantExpression * JavaToken.COLON or + JavaToken.CASE * EnumConstantName * JavaToken.COLON or JavaToken.DEFAULT * JavaToken.COLON + EnumConstantName /= Identifier + WhileStatement /= JavaToken.WHILE * JavaToken.PARENTHLEFT * Expression * JavaToken.PARENTHRIGHT * Statement + WhileStatementNoShortIf /= JavaToken.WHILE * JavaToken.PARENTHLEFT * Expression * JavaToken.PARENTHRIGHT * StatementNoShortIf + DoStatement /= JavaToken.DO * Statement * JavaToken.WHILE * JavaToken.PARENTHLEFT * Expression * JavaToken.PARENTHRIGHT * JavaToken.SEMICOLON + ForStatement /= BasicForStatement or EnhancedForStatement + ForStatementNoShortIf /= BasicForStatementNoShortIf or EnhancedForStatementNoShortIf + BasicForStatement /= JavaToken.FOR * JavaToken.PARENTHLEFT * Option(ForInit) * JavaToken.SEMICOLON * Option(Expression) * JavaToken.SEMICOLON * Option(ForUpdate) * JavaToken.PARENTHRIGHT * Statement + BasicForStatementNoShortIf /= JavaToken.FOR * JavaToken.PARENTHLEFT * Option(ForInit) * JavaToken.SEMICOLON * Option(Expression) * JavaToken.SEMICOLON * Option(ForUpdate) * JavaToken.PARENTHRIGHT * StatementNoShortIf + ForInit /= StatementExpressionList or LocalVariableDeclaration + ForUpdate /= StatementExpressionList + StatementExpressionList /= StatementExpression * Many(JavaToken.COMMA * StatementExpression) + EnhancedForStatement /= JavaToken.FOR * JavaToken.PARENTHLEFT * Many(VariableModifier) * UnannType * VariableDeclaratorId * JavaToken.COLON * Expression * JavaToken.PARENTHRIGHT * Statement + EnhancedForStatementNoShortIf /= JavaToken.FOR * JavaToken.PARENTHLEFT * Many(VariableModifier) * UnannType * VariableDeclaratorId * JavaToken.COLON * Expression * JavaToken.PARENTHRIGHT * StatementNoShortIf + BreakStatement /= JavaToken.BREAK * Option(Identifier) * JavaToken.SEMICOLON + ContinueStatement /= JavaToken.CONTINUE * Option(Identifier) * JavaToken.SEMICOLON + ReturnStatement /= JavaToken.RETURN * Option(Expression) * JavaToken.SEMICOLON + ThrowStatement /= JavaToken.THROW * Expression * JavaToken.SEMICOLON + SynchronizedStatement /= JavaToken.SYNCHRONIZED * JavaToken.PARENTHLEFT * Expression * JavaToken.PARENTHRIGHT * Block + TryStatement /= JavaToken.TRY * Block * Catches or JavaToken.TRY * Block * Option(Catches) * Finally or TryWithResourcesStatement + Catches /= some(CatchClause) + CatchClause /= JavaToken.CATCH * JavaToken.PARENTHLEFT * CatchFormalParameter * JavaToken.PARENTHRIGHT * Block + CatchFormalParameter /= Many(VariableModifier) * CatchType * VariableDeclaratorId + CatchType /= UnannClassType * Many(JavaToken.ORBIT * ClassType) + Finally /= JavaToken.FINALLY * Block + TryWithResourcesStatement /= JavaToken.TRY * ResourceSpecification * Block * Option(Catches) * Option(Finally) + ResourceSpecification /= JavaToken.PARENTHLEFT * ResourceList * Option(JavaToken.SEMICOLON) * JavaToken.PARENTHRIGHT + ResourceList /= Resource * Many(JavaToken.COMMA * Resource) + Resource /= Many(VariableModifier) * UnannType * VariableDeclaratorId * JavaToken.ASSIGN * Expression + + /** + * Productions from §15 (Expressions) + */ + + Primary /= PrimaryNoNewArray or ArrayCreationExpression + PrimaryNoNewArray /= Literal or ClassLiteral or JavaToken.THIS or TypeName * JavaToken.DOT * JavaToken.THIS or + JavaToken.PARENTHLEFT * Expression * JavaToken.PARENTHRIGHT or ClassInstanceCreationExpression or FieldAccess or + ArrayAccess or MethodInvocation or MethodReference + ClassLiteral /= TypeName * Many(JavaToken.BRACKETLEFT * JavaToken.BRACKETRIGHT) * JavaToken.DOT * JavaToken.CLASS or + NumericType * Many(JavaToken.BRACKETLEFT * JavaToken.BRACKETRIGHT) * JavaToken.DOT * JavaToken.CLASS or + JavaToken.BOOLEAN * Many(JavaToken.BRACKETLEFT * JavaToken.BRACKETRIGHT) * JavaToken.DOT * JavaToken.CLASS or + JavaToken.VOID * JavaToken.DOT * JavaToken.CLASS + ClassInstanceCreationExpression /= UnqualifiedClassInstanceCreationExpression or + ExpressionName * JavaToken.DOT * UnqualifiedClassInstanceCreationExpression or + Primary * JavaToken.DOT * UnqualifiedClassInstanceCreationExpression + UnqualifiedClassInstanceCreationExpression /= + JavaToken.NEW * Option(TypeArguments) * classOrInterfaceTypeToInstantiate * JavaToken.PARENTHLEFT * Option(ArgumentList) * JavaToken.PARENTHRIGHT * Option(ClassBody) + classOrInterfaceTypeToInstantiate /= Many(Annotation) * Identifier * Many(JavaToken.DOT * Many(Annotation) * Identifier) * Option(TypeArgumentsOrDiamond) + TypeArgumentsOrDiamond /= TypeArguments or JavaToken.LT * JavaToken.GT + FieldAccess /= Primary * JavaToken.DOT * Identifier or JavaToken.SUPER * JavaToken.DOT * Identifier or + TypeName * JavaToken.DOT * JavaToken.SUPER * JavaToken.DOT * Identifier + ArrayAccess /= ExpressionName * JavaToken.BRACKETLEFT * Expression * JavaToken.BRACKETRIGHT or + PrimaryNoNewArray * JavaToken.BRACKETLEFT * Expression * JavaToken.BRACKETRIGHT + MethodInvocation /= MethodName * JavaToken.PARENTHLEFT * Option(ArgumentList) * JavaToken.PARENTHRIGHT or + TypeName * JavaToken.DOT * Option(TypeArguments) * Identifier * JavaToken.PARENTHLEFT * Option(ArgumentList) * JavaToken.PARENTHRIGHT or + ExpressionName * JavaToken.DOT * Option(TypeArguments) * Identifier * JavaToken.PARENTHLEFT * Option(ArgumentList) * JavaToken.PARENTHRIGHT or + Primary * JavaToken.DOT * Option(TypeArguments) * Identifier * JavaToken.PARENTHLEFT * Option(ArgumentList) * JavaToken.PARENTHRIGHT or + JavaToken.SUPER * JavaToken.DOT * Option(TypeArguments) * Identifier * JavaToken.PARENTHLEFT * Option(ArgumentList) * JavaToken.PARENTHRIGHT or + TypeName * JavaToken.DOT * JavaToken.SUPER * JavaToken.DOT * Option(TypeArguments) * Identifier * JavaToken.PARENTHLEFT * Option(ArgumentList) * JavaToken.PARENTHRIGHT + ArgumentList /= Expression * Many(JavaToken.COMMA * Expression) + MethodReference /= ExpressionName * JavaToken.DOUBLECOLON * Option(TypeArguments) * Identifier or + ReferenceType * JavaToken.DOUBLECOLON * Option(TypeArguments) * Identifier or + Primary * JavaToken.DOUBLECOLON * Option(TypeArguments) * Identifier or + JavaToken.SUPER * JavaToken.DOUBLECOLON * Option(TypeArguments) * Identifier or + TypeName * JavaToken.DOT * JavaToken.SUPER * JavaToken.DOUBLECOLON * Option(TypeArguments) * Identifier or + ClassType * JavaToken.DOUBLECOLON * Option(TypeArguments) * JavaToken.NEW or + ArrayType * JavaToken.DOUBLECOLON * JavaToken.NEW + ArrayCreationExpression /= JavaToken.NEW * PrimitiveType * DimExprs * Option(Dims) or + JavaToken.NEW * ClassOrInterfaceType * DimExprs * Option(Dims) or + JavaToken.NEW * PrimitiveType * Dims * ArrayInitializer or + JavaToken.NEW * ClassOrInterfaceType * Dims * ArrayInitializer + DimExprs /= some(DimExpr) + DimExpr /= Many(Annotation) * JavaToken.BRACKETLEFT * Expression * JavaToken.BRACKETRIGHT + Expression /= LambdaExpression or AssignmentExpression + LambdaExpression /= LambdaParameters * JavaToken.ARROW * LambdaBody + LambdaParameters /= Identifier or JavaToken.PARENTHLEFT * Option(FormalParameterList) * JavaToken.PARENTHRIGHT or + JavaToken.PARENTHLEFT * InferredFormalParameterList * JavaToken.PARENTHRIGHT + InferredFormalParameterList /= Identifier * Many(JavaToken.COMMA * Identifier) + LambdaBody /= Expression or Block + AssignmentExpression /= ConditionalExpression or Assignment + Assignment /= LeftHandSide * AssignmentOperator * Expression + LeftHandSide /= ExpressionName or FieldAccess or ArrayAccess + AssignmentOperator /= JavaToken.ASSIGN or JavaToken.STARASSIGN or JavaToken.SLASHASSIGN or JavaToken.PERCENTASSIGN or JavaToken.PLUSASSIGN or JavaToken.MINUSASSIGN or + JavaToken.SHIFTLEFTASSIGN or JavaToken.SHIFTRIGHTASSIGN or JavaToken.USRIGHTSHIFTASSIGN or JavaToken.ANDASSIGN or JavaToken.XORASSIGN or JavaToken.ORASSIGN + ConditionalExpression /= ConditionalOrExpression or + ConditionalOrExpression * JavaToken.QUESTIONMARK * Expression * JavaToken.COLON * ConditionalExpression or + ConditionalOrExpression * JavaToken.QUESTIONMARK * Expression * JavaToken.COLON * LambdaExpression + ConditionalOrExpression /= ConditionalAndExpression or + ConditionalOrExpression * JavaToken.OR * ConditionalAndExpression + ConditionalAndExpression /= InclusiveOrExpression or + ConditionalAndExpression * JavaToken.AND * InclusiveOrExpression + InclusiveOrExpression /= ExclusiveOrExpression or + InclusiveOrExpression * JavaToken.ORBIT * ExclusiveOrExpression + ExclusiveOrExpression /= AndExpression or ExclusiveOrExpression * JavaToken.XORBIT * AndExpression + AndExpression /= EqualityExpression or AndExpression * JavaToken.ANDBIT * EqualityExpression + EqualityExpression /= RelationalExpression or EqualityExpression * JavaToken.EQ * RelationalExpression or + EqualityExpression * JavaToken.NOTEQ * RelationalExpression + RelationalExpression /= ShiftExpression or RelationalExpression * JavaToken.LT * ShiftExpression or + RelationalExpression * JavaToken.GT * ShiftExpression or RelationalExpression * JavaToken.LESSEQ * ShiftExpression or + RelationalExpression * JavaToken.GREATEQ * ShiftExpression or RelationalExpression * JavaToken.INSTANCEOF * ReferenceType + ShiftExpression /= AdditiveExpression or ShiftExpression * JavaToken.LT * JavaToken.LT * AdditiveExpression or + ShiftExpression * JavaToken.GT * JavaToken.GT * AdditiveExpression or + ShiftExpression * JavaToken.GT * JavaToken.GT * JavaToken.GT * AdditiveExpression + AdditiveExpression /= MultiplicativeExpression or AdditiveExpression * JavaToken.PLUS * MultiplicativeExpression or + AdditiveExpression * JavaToken.MINUS * MultiplicativeExpression + MultiplicativeExpression /= UnaryExpression or MultiplicativeExpression * JavaToken.STAR * UnaryExpression or + MultiplicativeExpression * JavaToken.SLASH * UnaryExpression or + MultiplicativeExpression * JavaToken.PERCENT * UnaryExpression + UnaryExpression /= PreIncrementExpression or PreDecrementExpression or JavaToken.PLUS * UnaryExpression or + JavaToken.MINUS * UnaryExpression or UnaryExpressionNotPlusMinus + PreIncrementExpression /= JavaToken.PLUSPLUS * UnaryExpression + PreDecrementExpression /= JavaToken.MINUSMINUS * UnaryExpression + UnaryExpressionNotPlusMinus /= PostfixExpression or JavaToken.TILDA * UnaryExpression or JavaToken.EXCLAMATIONMARK * UnaryExpression or + CastExpression + PostfixExpression /= Primary or ExpressionName or PostIncrementExpression or PostDecrementExpression + PostIncrementExpression /= PostfixExpression * JavaToken.PLUSPLUS + PostDecrementExpression /= PostfixExpression * JavaToken.MINUSMINUS + CastExpression /= JavaToken.PARENTHLEFT * PrimitiveType * JavaToken.PARENTHRIGHT * UnaryExpression or + JavaToken.PARENTHLEFT * ReferenceType * Many(AdditionalBound) * JavaToken.PARENTHRIGHT * UnaryExpressionNotPlusMinus or + JavaToken.PARENTHLEFT * ReferenceType * Many(AdditionalBound) * JavaToken.PARENTHRIGHT * LambdaExpression + ConstantExpression /= Expression + } +} \ No newline at end of file diff --git a/benchmarks/src/jmh/kotlin/lexers/JavaToken.kt b/examples/src/main/kotlin/java7/JavaToken.kt similarity index 99% rename from benchmarks/src/jmh/kotlin/lexers/JavaToken.kt rename to examples/src/main/kotlin/java7/JavaToken.kt index 80d2dec46..ef7afb958 100644 --- a/benchmarks/src/jmh/kotlin/lexers/JavaToken.kt +++ b/examples/src/main/kotlin/java7/JavaToken.kt @@ -1,4 +1,4 @@ -package lexers +package java7 import org.ucfs.parser.ParsingException import org.ucfs.rsm.symbol.ITerminal diff --git a/generator/src/main/kotlin/org/ucfs/IGeneratorFromGrammar.kt b/generator/src/main/kotlin/org/ucfs/IGeneratorFromGrammar.kt index b5ac7773e..47dcbe4f6 100644 --- a/generator/src/main/kotlin/org/ucfs/IGeneratorFromGrammar.kt +++ b/generator/src/main/kotlin/org/ucfs/IGeneratorFromGrammar.kt @@ -5,7 +5,6 @@ import com.squareup.kotlinpoet.ClassName import com.squareup.kotlinpoet.FileSpec import com.squareup.kotlinpoet.TypeName import org.ucfs.grammar.combinator.Grammar -import java.nio.file.Path /** * Common logic for generators that use a Grammar class @@ -27,8 +26,6 @@ interface IGeneratorFromGrammar { } throw GeneratorException(GeneratorException.GRAMMAR_EXPECTED) } - - fun generate(location: Path, pkg: String) } internal fun FileSpec.Builder.suppressWarningTypes(vararg types: String) { diff --git a/generator/src/main/kotlin/org/ucfs/ast/AstExtractor.kt b/generator/src/main/kotlin/org/ucfs/ast/AstExtractor.kt index f56d92f16..eb0e2c9f8 100644 --- a/generator/src/main/kotlin/org/ucfs/ast/AstExtractor.kt +++ b/generator/src/main/kotlin/org/ucfs/ast/AstExtractor.kt @@ -44,6 +44,7 @@ class AstExtractor(val pkg: String) { val ctor = nodeClass.getConstructor(Node::class.java, Int::class.java) val node: Node = ctor.newInstance(parent, getOffset(left, parent)) as Node + node.isRecovered = sppf.weight > 0 node.left = left parent.children.add(node) @@ -57,6 +58,7 @@ class AstExtractor(val pkg: String) { is TerminalSppfNode<*> -> { val node = TerminalNode(parent, getOffset(left, parent), sppf.terminal, left) + node.isRecovered = sppf.weight > 0 parent.children.add(node) parent.length += sppf.terminal.toString().length return node diff --git a/generator/src/main/kotlin/org/ucfs/ast/DotWriter.kt b/generator/src/main/kotlin/org/ucfs/ast/DotWriter.kt index 04c005db9..f023fad6c 100644 --- a/generator/src/main/kotlin/org/ucfs/ast/DotWriter.kt +++ b/generator/src/main/kotlin/org/ucfs/ast/DotWriter.kt @@ -39,7 +39,12 @@ class DotWriter { private fun getNodeView(node: Node): StringBuilder { val view = StringBuilder("\n${getId(node)} [ ${getNodeLabel(node)}") if (node is TerminalNode<*>) { - view.append(", color = green") + if(node.isRecovered) { + view.append(", color = red") + } + else{ + view.append(", color = green") + } } view.append("]") return view diff --git a/generator/src/main/kotlin/org/ucfs/ast/Node.kt b/generator/src/main/kotlin/org/ucfs/ast/Node.kt index 27dfdbdb2..9a82c34b5 100644 --- a/generator/src/main/kotlin/org/ucfs/ast/Node.kt +++ b/generator/src/main/kotlin/org/ucfs/ast/Node.kt @@ -13,4 +13,5 @@ open class Node( open var left: Node? = null var right: Node? = null var children: ArrayList = ArrayList() + var isRecovered: Boolean = false } \ No newline at end of file diff --git a/generator/src/main/kotlin/org/ucfs/ast/NodeClassesGenerator.kt b/generator/src/main/kotlin/org/ucfs/ast/NodeClassesGenerator.kt index 9521aa1ce..9e8980f8b 100644 --- a/generator/src/main/kotlin/org/ucfs/ast/NodeClassesGenerator.kt +++ b/generator/src/main/kotlin/org/ucfs/ast/NodeClassesGenerator.kt @@ -34,7 +34,7 @@ class NodeClassesGenerator(override val grammarClazz: Class<*>) : /** * Generate class for each nonterminal in grammar */ - override fun generate(location: Path, pkg: String) { + fun generate(location: Path, pkg: String) { for (nt in grammar.nonTerms) { val file = generateClassFile(nt, pkg) file.writeTo(location) diff --git a/generator/src/main/kotlin/org/ucfs/examples/dyck/DyckGrammar.kt b/generator/src/main/kotlin/org/ucfs/examples/dyck/DyckGrammar.kt index e94a65b9b..96a9ee3c9 100644 --- a/generator/src/main/kotlin/org/ucfs/examples/dyck/DyckGrammar.kt +++ b/generator/src/main/kotlin/org/ucfs/examples/dyck/DyckGrammar.kt @@ -7,16 +7,12 @@ import org.ucfs.grammar.combinator.regexp.many import org.ucfs.grammar.combinator.regexp.or class DyckGrammar : Grammar() { - var S by Nt() - var Round by Nt() - var Quadrat by Nt() - var Curly by Nt() + val S by Nt().asStart() + val Round by Nt("(" * S * ")") + val Quadrat by Nt("[" * S * "]") + val Curly by Nt("{" * S * "}") init { - setStart(S) - S = many(Round or Quadrat or Curly) - Round = "(" * S * ")" - Quadrat = "[" * S * "]" - Curly = "{" * S * "}" + S /= many(Round or Quadrat or Curly) } } diff --git a/generator/src/main/kotlin/org/ucfs/examples/golang/SimpleGolang.kt b/generator/src/main/kotlin/org/ucfs/examples/golang/SimpleGolang.kt index 967f2e169..59bb2217f 100644 --- a/generator/src/main/kotlin/org/ucfs/examples/golang/SimpleGolang.kt +++ b/generator/src/main/kotlin/org/ucfs/examples/golang/SimpleGolang.kt @@ -1,4 +1,4 @@ -package org.ucfs.examples.golang +package org.ucfs.examples.golang import org.ucfs.grammar.combinator.Grammar import org.ucfs.grammar.combinator.extension.StringExtension.or @@ -8,16 +8,8 @@ import org.ucfs.grammar.combinator.regexp.Nt import org.ucfs.grammar.combinator.regexp.or class SimpleGolang : Grammar() { - var Program by Nt() - var Block by Nt() - var Statement by Nt() - var IntExpr by Nt() - - init { - setStart(Program) - Program = Block - Block = Many(Statement) - Statement = IntExpr * ";" or "r" * IntExpr * ";" - IntExpr = "1" or "1" * "+" * "1" - } + val IntExpr by Nt("1" or "1" * "+" * "1") + val Statement by Nt(IntExpr * ";" or "r" * IntExpr * ";") + val Block by Nt(Many(Statement)) + val Program by Nt(Block).asStart() } diff --git a/generator/src/main/kotlin/org/ucfs/parser/IParserGenerator.kt b/generator/src/main/kotlin/org/ucfs/parser/AbstractParserGenerator.kt similarity index 64% rename from generator/src/main/kotlin/org/ucfs/parser/IParserGenerator.kt rename to generator/src/main/kotlin/org/ucfs/parser/AbstractParserGenerator.kt index 9a0a87e9a..7b85f170e 100644 --- a/generator/src/main/kotlin/org/ucfs/parser/IParserGenerator.kt +++ b/generator/src/main/kotlin/org/ucfs/parser/AbstractParserGenerator.kt @@ -7,8 +7,10 @@ import org.ucfs.IGeneratorFromGrammar import org.ucfs.descriptors.Descriptor import org.ucfs.grammar.combinator.Grammar import org.ucfs.grammar.combinator.regexp.Nt +import org.ucfs.input.IInputGraph import org.ucfs.input.ILabel import org.ucfs.nullable +import org.ucfs.parser.context.Context import org.ucfs.parser.context.IContext import org.ucfs.rsm.RsmState import org.ucfs.rsm.symbol.ITerminal @@ -18,25 +20,35 @@ import org.ucfs.suppressWarningTypes import java.nio.file.Path import java.util.stream.Collectors.toList -interface IParserGenerator : IGeneratorFromGrammar { - val grammar: Grammar + +abstract class AbstractParserGenerator(final override val grammarClazz: Class<*>) : IGeneratorFromGrammar { + val grammar: Grammar = buildGrammar(grammarClazz) companion object { - private const val PARSER = "Parser" + /** + * Types + */ val vertexType = TypeVariableName("VertexType") val labelType = TypeVariableName("LabelType", ILabel::class.java) val superClass = GeneratedParser::class.asTypeName().parameterizedBy(vertexType, labelType) - const val CTX_NAME = "ctx" - const val GRAMMAR_NAME = "grammar" - const val FUNCS_NAME = "ntFuncs" val descriptorType = Descriptor::class.asTypeName().parameterizedBy(vertexType) val sppfType = SppfNode::class.asTypeName().parameterizedBy(vertexType).nullable() + + /** + * Variable identifiers + */ + const val PARSER = "Parser" + const val RECOVERY = "Recovery" + const val VALUE_NAME = "value" + const val CTX_NAME = "ctx" + const val GRAMMAR_NAME = "grammar" const val DESCRIPTOR = "descriptor" const val SPPF_NODE = "curSppfNode" const val RSM_FIELD = "rsmState" + const val RSM_GRAMMAR_FIELD = "rsm" const val POS_FIELD = "inputPosition" - const val INPUT_FIELD = "input" - const val GET_NONTERMINAL = "getNonterminal" + const val INPUT_NAME = "input" + const val NONTERMINAL = "nonterm" const val GET_TERMINALS = "getTerminals" const val TERMINALS = "terminals" const val HANDLE_TERMINAL = "handleTerminal" @@ -44,26 +56,31 @@ interface IParserGenerator : IGeneratorFromGrammar { const val ID_FIELD_NAME = "id" const val POS_VAR_NAME = "pos" const val INPUT_EDGE_NAME = "inputEdge" + const val MAIN_PARSE_FUNC = "parse" + + /** + * Common methods + */ + fun getParseFunName(nonterminalName: String): String = "parse${nonterminalName}" - fun getParserClassName(grammarSimpleName: String): String { - return grammarSimpleName + PARSER - } } - /** * Generate all parser properties and methods */ - override fun generate(location: Path, pkg: String) { + fun generate(location: Path, pkg: String) { val file = getFileBuilder(pkg).build() file.writeTo(location) } + open fun getParserClassName(): String { + return grammarClazz.simpleName + PARSER + } /** * Build file builder */ - fun getFileBuilder(pkg: String): FileSpec.Builder { - val fileName = getParserClassName(grammarClazz.simpleName) + protected open fun getFileBuilder(pkg: String): FileSpec.Builder { + val fileName = getParserClassName() val parserClass = ClassName(pkg, fileName).parameterizedBy(vertexType, labelType) val parserClassBuilder = TypeSpec.classBuilder(parserClass.rawType.simpleName) @@ -71,6 +88,7 @@ interface IParserGenerator : IGeneratorFromGrammar { .addTypeVariable(labelType) .superclass(superClass) .addProperties(generateProperties()) + .addNtMapping() .addFunctions(generateParseFunctions()) val fileBuilder = FileSpec @@ -83,21 +101,26 @@ interface IParserGenerator : IGeneratorFromGrammar { return fileBuilder } + fun TypeSpec.Builder.addNtMapping(): TypeSpec.Builder { + addFunction(generateCallNtFuncs()) + return this + } + /** * Add properties in Parser class */ - fun generateProperties(): Iterable { + open fun generateProperties(): Iterable { return listOf( generateCtxProperty(), - generateGrammarProperty(grammarClazz) - ) + generateNonterminalsSpec() + - generateNtFuncsProperty() + generateGrammarProperty(grammarClazz), + generateInputProperty() + ) + generateNonterminalsSpec() } /** * Generate overriding of ctx property */ - fun generateCtxProperty(): PropertySpec { + private fun generateCtxProperty(): PropertySpec { val ctxType = IContext::class.asTypeName().parameterizedBy(vertexType, labelType) return PropertySpec.builder(CTX_NAME, ctxType, KModifier.LATEINIT, KModifier.OVERRIDE) .mutable() @@ -108,7 +131,7 @@ interface IParserGenerator : IGeneratorFromGrammar { * Generate overriding of grammar property * Anr it's initialization of corresponding @Grammar class */ - fun generateGrammarProperty(grammarClazz: Class<*>): PropertySpec { + private fun generateGrammarProperty(grammarClazz: Class<*>): PropertySpec { return PropertySpec .builder(GRAMMAR_NAME, grammarClazz, KModifier.OVERRIDE) .initializer( @@ -117,54 +140,41 @@ interface IParserGenerator : IGeneratorFromGrammar { .build() } - /** - * Generate overriding of property that map nonterminal to it's handling function. - * And initialize it. - */ - fun generateNtFuncsProperty(): PropertySpec { - val funcType = LambdaTypeName.get( - parameters = arrayOf( - ParameterSpec("descriptor", descriptorType), - ParameterSpec("sppf", sppfType.copy(nullable = true)) - ), - returnType = Unit::class.asTypeName() - ) - val mapType = HashMap::class - .asTypeName() - .parameterizedBy(Nonterminal::class.asTypeName(), funcType) - val mapInitializer = CodeBlock.builder() - .addStatement("hashMapOf(") + private fun generateCallNtFuncs(): FunSpec { + val funSpec = FunSpec.builder("callNtFuncs") + funSpec.addModifiers(KModifier.OVERRIDE) + .addParameter("nt", Nonterminal::class.asTypeName()) + .addParameter(DESCRIPTOR, descriptorType) + .addParameter(SPPF_NODE, sppfType) + .beginControlFlow("when(nt.name)", STATE_NAME, ID_FIELD_NAME) for (nt in grammar.nonTerms) { val ntName = nt.nonterm.name ?: throw GeneratorException("Unnamed nonterminal in grammar ${grammarClazz.simpleName}") - mapInitializer.addStatement("%L to ::%L,", ntName, getParseFunName(ntName)) + funSpec.addStatement("%S -> %L($DESCRIPTOR, $SPPF_NODE)", ntName, getParseFunName(ntName)) } - mapInitializer.addStatement(")") - - return PropertySpec - .builder(FUNCS_NAME, mapType, KModifier.OVERRIDE) - .initializer(mapInitializer.build()) - .build() + funSpec.endControlFlow() + return funSpec.build() } + /** * Generate Parse methods for all nonterminals */ - fun generateParseFunctions(): Iterable { + protected open fun generateParseFunctions(): Iterable { return grammar.nonTerms.map { generateParseFunction(it) } } /** * Generate Parse method for concrete nonterminal */ - fun generateParseFunction(nt: Nt): FunSpec { + private fun generateParseFunction(nt: Nt): FunSpec { val funSpec = FunSpec.builder(getParseFunName(nt.nonterm.name!!)) funSpec.addModifiers(KModifier.PRIVATE) .addParameter(DESCRIPTOR, descriptorType) .addParameter(SPPF_NODE, sppfType) .addStatement("val %L = %L.%L", STATE_NAME, DESCRIPTOR, RSM_FIELD) .addStatement("val %L = %L.%L", POS_VAR_NAME, DESCRIPTOR, POS_FIELD) - .beginControlFlow("when(%L.%L)", STATE_NAME, ID_FIELD_NAME) + .beginControlFlow("when(%L.%L)", STATE_NAME, "numId") for (state in nt.nonterm.getStates()) { generateParseForState(state, funSpec) @@ -179,7 +189,7 @@ interface IParserGenerator : IGeneratorFromGrammar { * (handle parsing for concrete state) */ fun generateParseForState(state: RsmState, funSpec: FunSpec.Builder) { - funSpec.addStatement("%S -> ", state.id) + funSpec.addStatement("%L -> ", state.numId) funSpec.beginControlFlow("") generateTerminalParsing(state, funSpec) generateNonterminalParsing(state, funSpec) @@ -189,14 +199,14 @@ interface IParserGenerator : IGeneratorFromGrammar { /** * Generate and add to funSpec method that parse all terminals edge from current state */ - fun generateTerminalParsing(state: RsmState, funSpec: FunSpec.Builder) { + private fun generateTerminalParsing(state: RsmState, funSpec: FunSpec.Builder) { if (state.terminalEdges.isNotEmpty()) { funSpec.addComment("handle terminal edges") funSpec.beginControlFlow( "for (%L in %L.%L.getEdges(%L))", INPUT_EDGE_NAME, CTX_NAME, - INPUT_FIELD, + INPUT_NAME, POS_VAR_NAME ) for (term in state.terminalEdges.keys) { @@ -209,14 +219,14 @@ interface IParserGenerator : IGeneratorFromGrammar { /** * Generate code for handle one Edge with Terminal<*> label */ - fun generateTerminalHandling(terminal: ITerminal): CodeBlock + abstract fun generateTerminalHandling(terminal: ITerminal): CodeBlock /** * Generate code for parsing all edges with Nonterminal label * from given @RsmState state */ - fun generateNonterminalParsing(state: RsmState, funSpec: FunSpec.Builder) { + private fun generateNonterminalParsing(state: RsmState, funSpec: FunSpec.Builder) { if (state.nonterminalEdges.isNotEmpty()) { funSpec.addComment("handle nonterminal edges") for (edge in state.nonterminalEdges) { @@ -237,7 +247,7 @@ interface IParserGenerator : IGeneratorFromGrammar { * Generate definition and initialization for all Nonterminals * as parser fields (with correspond nonterminal names) */ - fun generateNonterminalsSpec(): Iterable { + private fun generateNonterminalsSpec(): Iterable { return grammar.nonTerms.stream().map { generateNonterminalSpec(it) }.collect(toList()) } @@ -245,13 +255,44 @@ interface IParserGenerator : IGeneratorFromGrammar { * Generate definition and initialization for concrete Nonterminal * as parser field (with correspond nonterminal name) */ - fun generateNonterminalSpec(nt: Nt): PropertySpec { + private fun generateNonterminalSpec(nt: Nt): PropertySpec { val ntName = nt.nonterm.name!! val propertyBuilder = PropertySpec.builder(ntName, Nonterminal::class.asTypeName()) .addModifiers(KModifier.PRIVATE) - .initializer("%L.%L.%L()!!", GRAMMAR_NAME, ntName, GET_NONTERMINAL) + .initializer("%L.%L.%L", GRAMMAR_NAME, ntName, NONTERMINAL) return propertyBuilder.build() } + + protected open fun generateInputProperty(): PropertySpec { + return generateInputProperty( + Context::class.asTypeName().parameterizedBy(vertexType, labelType) + ) + } + + protected fun generateInputProperty(ctxType: ParameterizedTypeName): PropertySpec { + val inputType = IInputGraph::class.asTypeName().parameterizedBy(vertexType, labelType) + return PropertySpec.builder(INPUT_NAME, inputType, KModifier.OVERRIDE) + .mutable() + .getter( + FunSpec.getterBuilder() + .addStatement("return %L.%L", CTX_NAME, INPUT_NAME) + .build() + ) + .setter( + FunSpec.setterBuilder() + .addParameter(VALUE_NAME, inputType) + .addStatement( + "%L = %L(%L.%L, %L)", + CTX_NAME, + ctxType.rawType, + GRAMMAR_NAME, + RSM_GRAMMAR_FIELD, + VALUE_NAME + ) + .build() + ) + .build() + } } diff --git a/generator/src/main/kotlin/org/ucfs/parser/GeneratedParser.kt b/generator/src/main/kotlin/org/ucfs/parser/GeneratedParser.kt index 1c58efbac..1310d3ac8 100644 --- a/generator/src/main/kotlin/org/ucfs/parser/GeneratedParser.kt +++ b/generator/src/main/kotlin/org/ucfs/parser/GeneratedParser.kt @@ -5,38 +5,34 @@ import org.ucfs.grammar.combinator.Grammar import org.ucfs.input.Edge import org.ucfs.input.IInputGraph import org.ucfs.input.ILabel -import org.ucfs.parser.context.Context import org.ucfs.rsm.RsmState import org.ucfs.rsm.symbol.ITerminal import org.ucfs.rsm.symbol.Nonterminal import org.ucfs.sppf.node.SppfNode + abstract class GeneratedParser : IGll { abstract val grammar: Grammar - var input: IInputGraph - get() { - return ctx.input - } - set(value) { - ctx = Context(grammar.rsm, value) - } + abstract var input: IInputGraph - protected abstract val ntFuncs: HashMap, SppfNode?) -> Unit> + /** + * Processes faster than map from nonterminal to method (proved experimentally) + */ + protected abstract fun callNtFuncs( + nt: Nonterminal, + descriptor: Descriptor, + curSppfNode: SppfNode? + ): Unit override fun parse(descriptor: Descriptor) { val state = descriptor.rsmState val nt = state.nonterminal - val handleEdges = ntFuncs[nt] ?: throw ParsingException("Nonterminal ${nt.name} is absent from the grammar!") - val pos = descriptor.inputPosition - - ctx.descriptors.addToHandled(descriptor) val curSppfNode = descriptor.sppfNode val epsilonSppfNode = ctx.sppf.getEpsilonSppfNode(descriptor) - val leftExtent = curSppfNode?.leftExtent val rightExtent = curSppfNode?.rightExtent @@ -44,23 +40,19 @@ abstract class GeneratedParser : pop(descriptor.gssNode, curSppfNode ?: epsilonSppfNode, pos) } + ctx.descriptors.addToHandled(descriptor) + if (state.isStart && state.isFinal) { checkAcceptance( epsilonSppfNode, epsilonSppfNode!!.leftExtent, epsilonSppfNode!!.rightExtent, - state.nonterminal + nt ) } - checkAcceptance(curSppfNode, leftExtent, rightExtent, state.nonterminal) + checkAcceptance(curSppfNode, leftExtent, rightExtent, nt) - for (inputEdge in ctx.input.getEdges(pos)) { - if (inputEdge.label.terminal == null) { - handleTerminalOrEpsilonEdge(descriptor, curSppfNode, null, descriptor.rsmState, inputEdge.head, 0) - continue - } - } - handleEdges(descriptor, curSppfNode) + callNtFuncs(nt, descriptor, curSppfNode) } protected fun handleTerminal( @@ -71,14 +63,13 @@ abstract class GeneratedParser : curSppfNode: SppfNode? ) { - val newStates = state.terminalEdges[terminal] ?: throw ParsingException( - "State $state does not contains edges " + - "\nby terminal $terminal" + - "\naccessible edges: ${state.terminalEdges}\n" - ) - if (inputEdge.label.terminal == terminal) { + val newStates = state.terminalEdges[terminal] ?: throw ParsingException( + "State $state does not contains edges " + + "\nby terminal $terminal" + + "\naccessible edges: ${state.terminalEdges}\n" + ) for (target in newStates) { handleTerminalOrEpsilonEdge( descriptor, diff --git a/generator/src/main/kotlin/org/ucfs/parser/ParserGenerator.kt b/generator/src/main/kotlin/org/ucfs/parser/ParserGenerator.kt index 48dcc3120..d552fcec4 100644 --- a/generator/src/main/kotlin/org/ucfs/parser/ParserGenerator.kt +++ b/generator/src/main/kotlin/org/ucfs/parser/ParserGenerator.kt @@ -2,40 +2,26 @@ package org.ucfs.parser import com.squareup.kotlinpoet.CodeBlock import com.squareup.kotlinpoet.FileSpec -import org.ucfs.grammar.combinator.Grammar import org.ucfs.rsm.symbol.ITerminal -import java.nio.file.Path /** * Generator for a parser that uses a third-party lexer. * Unlike the scannerless parser , it uses scanner enumeration objects as terminals. - * @see ScanerlessParserGenerator */ -class ParserGenerator(override val grammarClazz: Class<*>, private val terminalsEnum: Class<*>) : IParserGenerator { - - init { - buildGrammar(grammarClazz) - } - +open class ParserGenerator(grammarClazz: Class<*>, private val terminalsEnum: Class<*>) : + AbstractParserGenerator(grammarClazz) { override fun generateTerminalHandling(terminal: ITerminal): CodeBlock { val terminalName = "${terminalsEnum.simpleName}.$terminal" return CodeBlock.of( - "%L(%L, %L, %L, %L, %L)", - IParserGenerator.HANDLE_TERMINAL, - terminalName, - IParserGenerator.STATE_NAME, - IParserGenerator.INPUT_EDGE_NAME, - IParserGenerator.DESCRIPTOR, - IParserGenerator.SPPF_NODE + "%L(%L, %L, %L, %L, %L)", HANDLE_TERMINAL, terminalName, STATE_NAME, INPUT_EDGE_NAME, DESCRIPTOR, SPPF_NODE ) } - private fun getFileBuilder(location: Path, pkg: String): FileSpec.Builder { + override fun getFileBuilder(pkg: String): FileSpec.Builder { val builder = super.getFileBuilder(pkg) builder.addImport(terminalsEnum.packageName, terminalsEnum.simpleName) return builder } - override val grammar: Grammar = buildGrammar(grammarClazz) } diff --git a/generator/src/main/kotlin/org/ucfs/parser/RecoveryParserGenerator.kt b/generator/src/main/kotlin/org/ucfs/parser/RecoveryParserGenerator.kt new file mode 100644 index 000000000..46d7802d8 --- /dev/null +++ b/generator/src/main/kotlin/org/ucfs/parser/RecoveryParserGenerator.kt @@ -0,0 +1,41 @@ +package org.ucfs.parser + +import com.squareup.kotlinpoet.FunSpec +import com.squareup.kotlinpoet.KModifier +import com.squareup.kotlinpoet.ParameterizedTypeName.Companion.parameterizedBy +import com.squareup.kotlinpoet.PropertySpec +import com.squareup.kotlinpoet.asTypeName +import org.ucfs.intersection.RecoveryIntersection +import org.ucfs.parser.context.RecoveryContext + +/** + * Generator for a parser with error-recovery that uses a third-party lexer. + */ +class RecoveryParserGenerator(grammarClazz: Class<*>, terminalsEnum: Class<*>) : + ParserGenerator(grammarClazz, terminalsEnum) { + companion object { + val recoveryEngineType = RecoveryIntersection::class.java.asTypeName() + const val RECOVERY_METHOD_NAME = "handleRecoveryEdges" + } + + override fun generateInputProperty(): PropertySpec { + return generateInputProperty( + RecoveryContext::class.asTypeName().parameterizedBy(vertexType, labelType) + ) + } + + override fun generateParseFunctions(): Iterable { + return super.generateParseFunctions() + generateMainLoopFunction() + } + + private fun generateMainLoopFunction(): FunSpec { + return FunSpec.builder(MAIN_PARSE_FUNC).addModifiers(KModifier.OVERRIDE).addParameter( + DESCRIPTOR, descriptorType + ).addStatement("super.%L()", MAIN_PARSE_FUNC) + .addStatement("%L.%L(this, %L)", recoveryEngineType, RECOVERY_METHOD_NAME, DESCRIPTOR).build() + } + override fun getParserClassName(): String { + return super.getParserClassName() + RECOVERY + } + +} diff --git a/generator/src/main/kotlin/org/ucfs/parser/ScanerlessParserGenerator.kt b/generator/src/main/kotlin/org/ucfs/parser/ScanerlessParserGenerator.kt index 12073173b..4e1ea5805 100644 --- a/generator/src/main/kotlin/org/ucfs/parser/ScanerlessParserGenerator.kt +++ b/generator/src/main/kotlin/org/ucfs/parser/ScanerlessParserGenerator.kt @@ -5,16 +5,13 @@ import com.squareup.kotlinpoet.KModifier import com.squareup.kotlinpoet.ParameterizedTypeName.Companion.parameterizedBy import com.squareup.kotlinpoet.PropertySpec import com.squareup.kotlinpoet.asTypeName -import org.ucfs.grammar.combinator.Grammar -import org.ucfs.parser.IParserGenerator.Companion.INPUT_EDGE_NAME import org.ucfs.rsm.symbol.ITerminal /** * Scanerless parser generator * Store @Grammar terminals as list of @Terminal<*> type */ -class ScanerlessParserGenerator(override val grammarClazz: Class<*>) : IParserGenerator { - override val grammar: Grammar = buildGrammar(grammarClazz) +class ScanerlessParserGenerator(grammarClazz: Class<*>) : AbstractParserGenerator(grammarClazz) { private val terminals: List = grammar.getTerminals().toList() override fun generateProperties(): Iterable { @@ -26,13 +23,13 @@ class ScanerlessParserGenerator(override val grammarClazz: Class<*>) : IParserGe ): CodeBlock { return CodeBlock.of( "%L(%L[%L], %L, %L, %L, %L)", - IParserGenerator.HANDLE_TERMINAL, - IParserGenerator.TERMINALS, + HANDLE_TERMINAL, + TERMINALS, terminals.indexOf(terminal), - IParserGenerator.STATE_NAME, + STATE_NAME, INPUT_EDGE_NAME, - IParserGenerator.DESCRIPTOR, - IParserGenerator.SPPF_NODE + DESCRIPTOR, + SPPF_NODE ) } @@ -41,14 +38,17 @@ class ScanerlessParserGenerator(override val grammarClazz: Class<*>) : IParserGe * filed in parser */ private fun generateTerminalsSpec(): PropertySpec { - val termListType = List::class.asTypeName() - .parameterizedBy( - ITerminal::class.asTypeName() - ) + val termListType = List::class.asTypeName().parameterizedBy( + ITerminal::class.asTypeName() + ) val propertyBuilder = - PropertySpec.builder(IParserGenerator.TERMINALS, termListType) - .addModifiers(KModifier.PRIVATE) - .initializer("%L.%L().%L()", IParserGenerator.GRAMMAR_NAME, IParserGenerator.GET_TERMINALS, "toList") + PropertySpec.builder(TERMINALS, termListType).addModifiers(KModifier.PRIVATE) + .initializer( + "%L.%L().%L()", + GRAMMAR_NAME, + GET_TERMINALS, + "toList" + ) return propertyBuilder.build() } diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index 249e5832f..e6441136f 100644 Binary files a/gradle/wrapper/gradle-wrapper.jar and b/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 06febab41..b82aa23a4 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,7 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.2-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip +networkTimeout=10000 +validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME -zipStorePath=wrapper/dists \ No newline at end of file +zipStorePath=wrapper/dists diff --git a/gradlew b/gradlew index 1b6c78733..1aa94a426 100755 --- a/gradlew +++ b/gradlew @@ -55,7 +55,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. @@ -80,13 +80,11 @@ do esac done -APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit - -APP_NAME="Gradle" +# This is normally unused +# shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} - -# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' +# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) +APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum @@ -133,22 +131,29 @@ location of your Java installation." fi else JAVACMD=java - which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + if ! command -v java >/dev/null 2>&1 + then + die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. Please set the JAVA_HOME variable in your environment to match the location of your Java installation." + fi fi # Increase the maximum file descriptors if we can. if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then case $MAX_FD in #( max*) + # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC2039,SC3045 MAX_FD=$( ulimit -H -n ) || warn "Could not query maximum file descriptor limit" esac case $MAX_FD in #( '' | soft) :;; #( *) + # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC2039,SC3045 ulimit -n "$MAX_FD" || warn "Could not set maximum file descriptor limit to $MAX_FD" esac @@ -193,11 +198,15 @@ if "$cygwin" || "$msys" ; then done fi -# Collect all arguments for the java command; -# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of -# shell script including quotes and variable substitutions, so put them in -# double quotes to make sure that they get re-expanded; and -# * put everything else in single quotes, so that it's not re-expanded. + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Collect all arguments for the java command: +# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# and any embedded shellness will be escaped. +# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be +# treated as '${Hostname}' itself on the command line. set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ @@ -205,6 +214,12 @@ set -- \ org.gradle.wrapper.GradleWrapperMain \ "$@" +# Stop when "xargs" is not available. +if ! command -v xargs >/dev/null 2>&1 +then + die "xargs is not available" +fi + # Use "xargs" to parse quoted args. # # With -n1 it outputs one arg per line, with the quotes and backslashes removed. diff --git a/gradlew.bat b/gradlew.bat index ac1b06f93..7101f8e46 100644 --- a/gradlew.bat +++ b/gradlew.bat @@ -14,7 +14,7 @@ @rem limitations under the License. @rem -@if "%DEBUG%" == "" @echo off +@if "%DEBUG%"=="" @echo off @rem ########################################################################## @rem @rem Gradle startup script for Windows @@ -25,7 +25,8 @@ if "%OS%"=="Windows_NT" setlocal set DIRNAME=%~dp0 -if "%DIRNAME%" == "" set DIRNAME=. +if "%DIRNAME%"=="" set DIRNAME=. +@rem This is normally unused set APP_BASE_NAME=%~n0 set APP_HOME=%DIRNAME% @@ -40,13 +41,13 @@ if defined JAVA_HOME goto findJavaFromJavaHome set JAVA_EXE=java.exe %JAVA_EXE% -version >NUL 2>&1 -if "%ERRORLEVEL%" == "0" goto execute +if %ERRORLEVEL% equ 0 goto execute -echo. -echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. +echo. 1>&2 +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 goto fail @@ -56,11 +57,11 @@ set JAVA_EXE=%JAVA_HOME%/bin/java.exe if exist "%JAVA_EXE%" goto execute -echo. -echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. +echo. 1>&2 +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 goto fail @@ -75,13 +76,15 @@ set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar :end @rem End local scope for the variables with windows NT shell -if "%ERRORLEVEL%"=="0" goto mainEnd +if %ERRORLEVEL% equ 0 goto mainEnd :fail rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of rem the _cmd.exe /c_ return code! -if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 -exit /b 1 +set EXIT_CODE=%ERRORLEVEL% +if %EXIT_CODE% equ 0 set EXIT_CODE=1 +if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% +exit /b %EXIT_CODE% :mainEnd if "%OS%"=="Windows_NT" endlocal diff --git a/scripts/generate_all.sh b/scripts/generate_all.sh new file mode 100755 index 000000000..2dd7e7437 --- /dev/null +++ b/scripts/generate_all.sh @@ -0,0 +1,30 @@ +#!/bin/bash +shopt -s nullglob #ingore failed patterns +rootPrj=$(pwd) +parserDest="../benchmarks/src/main/kotlin/" +antlrSrc="benchmarks/src/main/java/org/antlr" +lexerSrc="examples/src/main/java/java7" + +printf "\n\nINSTALL PACKAGES\n" +apt-get install jflex +apt-get install antlr4 + +printf "\n\nGENERATE FILES\n" + +printf "\nGenerate ANTLR4 files" +cd $antlrSrc +antlr4 Java8.g4 +cd $rootPrj + +printf "\nGenerate lexers" +cd $lexerSrc +for lexer_name in *.jflex *.jlex *.lex *.flex *.x +do + jflex $lexer_name +done +cd $rootPrj + + +printf "\nGenerate UCFS parser files at" +echo $parserDest +./gradlew :examples:run --args=$parserDest \ No newline at end of file diff --git a/scripts/run_bench.sh b/scripts/run_bench.sh new file mode 100755 index 000000000..473dccba2 --- /dev/null +++ b/scripts/run_bench.sh @@ -0,0 +1,14 @@ +#!/bin/bash +shopt -s nullglob #ingore failed patterns +rootPrj=$(pwd) + +printf "\n\nRUN BENCHMARKS\n" +mkdir -p benchmarks/logs +for dataset in #/home/olga/gllgen/java7/junit #/home/olga/gllgen/dataset_black_box/too_little +do + for tool in Recovery #Antlr Online Offline + do + echo "running $tool on $dataset, start at $(date)" + ./gradlew benchmark -PtoolName=$tool -Pdataset=$dataset >> benchmarks/logs/stdout_$tool.txt 2>> benchmarks/logs/stderr_$tool.txt + done +done diff --git a/settings.gradle.kts b/settings.gradle.kts index f244834c7..9d660d937 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -6,3 +6,4 @@ include("solver") include("benchmarks") include("generator") include("test-shared") +include("examples") diff --git a/solver/src/main/kotlin/org/ucfs/descriptors/Descriptor.kt b/solver/src/main/kotlin/org/ucfs/descriptors/Descriptor.kt index 1ec7648a1..90bc3c8dd 100644 --- a/solver/src/main/kotlin/org/ucfs/descriptors/Descriptor.kt +++ b/solver/src/main/kotlin/org/ucfs/descriptors/Descriptor.kt @@ -46,6 +46,10 @@ open class Descriptor( return true } + + override fun toString(): String { + return "Descriptor(${rsmState.nonterminal}, inputPosition=$inputPosition)" + } } diff --git a/solver/src/main/kotlin/org/ucfs/grammar/combinator/Grammar.kt b/solver/src/main/kotlin/org/ucfs/grammar/combinator/Grammar.kt index d27655f65..dc9b58020 100644 --- a/solver/src/main/kotlin/org/ucfs/grammar/combinator/Grammar.kt +++ b/solver/src/main/kotlin/org/ucfs/grammar/combinator/Grammar.kt @@ -27,15 +27,22 @@ open class Grammar { } else throw IllegalArgumentException("Only NT object can be start state for Grammar") } + fun Nt.asStart(): Nt { + if (this@Grammar::startNt.isInitialized) { + throw Exception("Nonterminal ${nonterm.name} is already initialized") + } + startNt = this + return this + } + /** * Builds a Rsm for the grammar */ private fun buildRsm(): RsmState { nonTerms.forEach { it.buildRsmBox() } - val startState = startNt.getNonterminal()?.startState //if nonterminal not initialized -- it will be checked in buildRsmBox() - return startState!! + return startNt.nonterm.startState } /** diff --git a/solver/src/main/kotlin/org/ucfs/grammar/combinator/regexp/DerivedSymbol.kt b/solver/src/main/kotlin/org/ucfs/grammar/combinator/regexp/DerivedSymbol.kt index d4b550892..cfcbe0926 100644 --- a/solver/src/main/kotlin/org/ucfs/grammar/combinator/regexp/DerivedSymbol.kt +++ b/solver/src/main/kotlin/org/ucfs/grammar/combinator/regexp/DerivedSymbol.kt @@ -1,6 +1,7 @@ package org.ucfs.grammar.combinator.regexp interface DerivedSymbol : Regexp { + override fun derive(symbol: DerivedSymbol): Regexp { return if (this == symbol) Epsilon else Empty } diff --git a/solver/src/main/kotlin/org/ucfs/grammar/combinator/regexp/Many.kt b/solver/src/main/kotlin/org/ucfs/grammar/combinator/regexp/Many.kt index e7a6bcee5..949bce2ac 100644 --- a/solver/src/main/kotlin/org/ucfs/grammar/combinator/regexp/Many.kt +++ b/solver/src/main/kotlin/org/ucfs/grammar/combinator/regexp/Many.kt @@ -20,4 +20,4 @@ fun many(some: Regexp): Many { val Regexp.many: Many get() = Many(this) -fun Some(exp: Regexp) = exp * Many(exp) \ No newline at end of file +fun some(exp: Regexp) = exp * Many(exp) \ No newline at end of file diff --git a/solver/src/main/kotlin/org/ucfs/grammar/combinator/regexp/Nt.kt b/solver/src/main/kotlin/org/ucfs/grammar/combinator/regexp/Nt.kt index f1b1dd527..a9d5f6949 100644 --- a/solver/src/main/kotlin/org/ucfs/grammar/combinator/regexp/Nt.kt +++ b/solver/src/main/kotlin/org/ucfs/grammar/combinator/regexp/Nt.kt @@ -5,35 +5,41 @@ import org.ucfs.rsm.RsmState import org.ucfs.rsm.symbol.Nonterminal import kotlin.reflect.KProperty -open class Nt : DerivedSymbol { +open class Nt() : DerivedSymbol { + private lateinit var name : String + constructor(lhs: Regexp) : this() { + rsmDescription = lhs + } + lateinit var nonterm: Nonterminal private set private lateinit var rsmDescription: Regexp fun isInitialized(): Boolean { - return ::nonterm.isInitialized + return ::rsmDescription.isInitialized } fun buildRsmBox() { + nonterm.startState = RsmState(nonterm, isStart = true, rsmDescription.acceptEpsilon()) nonterm.startState.buildRsmBox(rsmDescription) } - override fun getNonterminal(): Nonterminal? { - return nonterm - } + operator fun getValue(grammar: Grammar, property: KProperty<*>): Nt = this - operator fun setValue(grammar: Grammar, property: KProperty<*>, lrh: Regexp) { - if (!this::nonterm.isInitialized) { - nonterm = Nonterminal(property.name) - grammar.nonTerms.add(this) - rsmDescription = lrh - nonterm.startState = RsmState(nonterm, isStart = true, rsmDescription.acceptEpsilon()) - } else { - throw Exception("Nonterminal ${property.name} is already initialized") + operator fun divAssign(lhs: Regexp) { + if (isInitialized()) { + throw Exception("Nonterminal '${nonterm.name}' is already initialized") } - + rsmDescription = lhs } - operator fun getValue(grammar: Grammar, property: KProperty<*>): Regexp = this -} \ No newline at end of file + operator fun provideDelegate( + grammar: Grammar, property: KProperty<*> + ): Nt { + name = property.name + nonterm = Nonterminal(property.name) + grammar.nonTerms.add(this) + return this + } +} diff --git a/solver/src/main/kotlin/org/ucfs/grammar/combinator/regexp/Regexp.kt b/solver/src/main/kotlin/org/ucfs/grammar/combinator/regexp/Regexp.kt index 4e052892e..c4559ab09 100644 --- a/solver/src/main/kotlin/org/ucfs/grammar/combinator/regexp/Regexp.kt +++ b/solver/src/main/kotlin/org/ucfs/grammar/combinator/regexp/Regexp.kt @@ -1,14 +1,11 @@ package org.ucfs.grammar.combinator.regexp -import org.ucfs.rsm.symbol.Nonterminal - sealed interface Regexp { /* Based on Brzozowski derivative */ fun derive(symbol: DerivedSymbol): Regexp - fun getNonterminal(): Nonterminal? = null /* Does the expression accept an epsilon diff --git a/solver/src/main/kotlin/org/ucfs/gss/GssNode.kt b/solver/src/main/kotlin/org/ucfs/gss/GssNode.kt index b5b8315d8..86d74c6f3 100644 --- a/solver/src/main/kotlin/org/ucfs/gss/GssNode.kt +++ b/solver/src/main/kotlin/org/ucfs/gss/GssNode.kt @@ -45,9 +45,7 @@ class GssNode( fun addEdge(rsmState: RsmState, sppfNode: SppfNode?, gssNode: GssNode): Boolean { val label = Pair(rsmState, sppfNode) - if (!edges.containsKey(label)) edges[label] = HashSet() - - return edges.getValue(label).add(gssNode) + return edges.computeIfAbsent(label) { HashSet() }.add(gssNode) } override fun toString() = "GSSNode(nonterminal=$nonterminal, inputPosition=$inputPosition)" diff --git a/solver/src/main/kotlin/org/ucfs/input/IInputGraph.kt b/solver/src/main/kotlin/org/ucfs/input/IInputGraph.kt index 73f5fe9e1..fcf0f00ad 100644 --- a/solver/src/main/kotlin/org/ucfs/input/IInputGraph.kt +++ b/solver/src/main/kotlin/org/ucfs/input/IInputGraph.kt @@ -1,18 +1,12 @@ package org.ucfs.input -import org.ucfs.descriptors.Descriptor -import org.ucfs.parser.context.IContext -import org.ucfs.rsm.RsmState -import org.ucfs.rsm.symbol.ITerminal -import org.ucfs.rsm.symbol.Nonterminal -import org.ucfs.sppf.node.SppfNode - /** * Input graph interface * @param VertexType - type of vertex in input graph * @param LabelType - type of label on edges in input graph */ interface IInputGraph { + /** * Collection of all vertices in graph */ @@ -91,55 +85,4 @@ interface IInputGraph { */ fun isFinal(vertex: VertexType): Boolean - /** - * Process outgoing edges from input position in given descriptor, according to processing logic, represented as - * separate functions for both outgoing terminal and nonterminal edges from rsmState in descriptor - * @param handleTerminalOrEpsilonEdge - function for processing terminal and epsilon edges in RSM - * @param handleNonterminalEdge - function for processing nonterminal edges in RSM - * @param ctx - configuration of Gll parser instance - * @param descriptor - descriptor, represents current parsing stage - * @param sppfNode - root node of derivation tree, corresponds to already parsed portion of input - */ - fun handleEdges( - handleTerminalOrEpsilonEdge: ( - descriptor: Descriptor, - sppfNode: SppfNode?, - terminal: ITerminal?, - targetState: RsmState, - targetVertex: VertexType, - targetWeight: Int, - ) -> Unit, - handleNonterminalEdge: ( - descriptor: Descriptor, - nonterminal: Nonterminal, - targetStates: HashSet, - sppfNode: SppfNode? - ) -> Unit, - ctx: IContext, - descriptor: Descriptor, - sppfNode: SppfNode? - ) { - val rsmState = descriptor.rsmState - val inputPosition = descriptor.inputPosition - val terminalEdges = rsmState.terminalEdges - val nonterminalEdges = rsmState.nonterminalEdges - - for (inputEdge in ctx.input.getEdges(inputPosition)) { - if (inputEdge.label.terminal == null) { - handleTerminalOrEpsilonEdge(descriptor, sppfNode, null, descriptor.rsmState, inputEdge.head, 0) - continue - } - for ((edgeTerminal, targetStates) in terminalEdges) { - if (inputEdge.label.terminal == edgeTerminal) { - for (target in targetStates) { - handleTerminalOrEpsilonEdge(descriptor, sppfNode, edgeTerminal, target, inputEdge.head, 0) - } - } - } - } - - for ((edgeNonterminal, targetStates) in nonterminalEdges) { - handleNonterminalEdge(descriptor, edgeNonterminal, targetStates, sppfNode) - } - } } \ No newline at end of file diff --git a/solver/src/main/kotlin/org/ucfs/input/RecoveryLinearInput.kt b/solver/src/main/kotlin/org/ucfs/input/RecoveryLinearInput.kt deleted file mode 100644 index d0e7b704c..000000000 --- a/solver/src/main/kotlin/org/ucfs/input/RecoveryLinearInput.kt +++ /dev/null @@ -1,27 +0,0 @@ -package org.ucfs.input - -import org.ucfs.rsm.symbol.Term - -class RecoveryLinearInput - : LinearInput(), IRecoveryInputGraph { - companion object { - /** - * Split CharSequence into stream of strings, separated by space symbol - */ - fun buildFromString(input: String): IRecoveryInputGraph { - val inputGraph = RecoveryLinearInput() - var curVertexId = 0 - - inputGraph.addStartVertex(curVertexId) - inputGraph.addVertex(curVertexId) - - for (x in input.trim().split(' ')) { - if (x.isNotEmpty()) { - inputGraph.addEdge(curVertexId, LinearInputLabel(Term(x)), ++curVertexId) - inputGraph.addVertex(curVertexId) - } - } - return inputGraph - } - } -} \ No newline at end of file diff --git a/solver/src/main/kotlin/org/ucfs/intersection/IIntersectionEngine.kt b/solver/src/main/kotlin/org/ucfs/intersection/IIntersectionEngine.kt new file mode 100644 index 000000000..44d5b0583 --- /dev/null +++ b/solver/src/main/kotlin/org/ucfs/intersection/IIntersectionEngine.kt @@ -0,0 +1,14 @@ +package org.ucfs.intersection + +import org.ucfs.descriptors.Descriptor +import org.ucfs.input.ILabel +import org.ucfs.parser.IGll +import org.ucfs.sppf.node.SppfNode + +interface IIntersectionEngine { + fun handleEdges( + gll: IGll, + descriptor: Descriptor, + sppfNode: SppfNode? + ) +} \ No newline at end of file diff --git a/solver/src/main/kotlin/org/ucfs/intersection/IntersectionEngine.kt b/solver/src/main/kotlin/org/ucfs/intersection/IntersectionEngine.kt new file mode 100644 index 000000000..00a056bad --- /dev/null +++ b/solver/src/main/kotlin/org/ucfs/intersection/IntersectionEngine.kt @@ -0,0 +1,44 @@ +package org.ucfs.intersection + +import org.ucfs.descriptors.Descriptor +import org.ucfs.input.ILabel +import org.ucfs.parser.IGll +import org.ucfs.sppf.node.SppfNode + +object IntersectionEngine : IIntersectionEngine { + + /** + * Process outgoing edges from input position in given descriptor, according to processing logic, represented as + * separate functions for both outgoing terminal and nonterminal edges from rsmState in descriptor + * @param gll - Gll parser instance + * @param descriptor - descriptor, represents current parsing stage + * @param sppfNode - root node of derivation tree, corresponds to already parsed portion of input + */ + override fun handleEdges( + gll: IGll, + descriptor: Descriptor, + sppfNode: SppfNode? + ) { + val rsmState = descriptor.rsmState + val inputPosition = descriptor.inputPosition + val terminalEdges = rsmState.terminalEdges + val nonterminalEdges = rsmState.nonterminalEdges + for (inputEdge in gll.ctx.input.getEdges(inputPosition)) { + if (inputEdge.label.terminal == null) { + gll.handleTerminalOrEpsilonEdge(descriptor, sppfNode, null, descriptor.rsmState, inputEdge.head, 0) + continue + } + for ((edgeTerminal, targetStates) in terminalEdges) { + if (inputEdge.label.terminal == edgeTerminal) { + for (target in targetStates) { + gll.handleTerminalOrEpsilonEdge(descriptor, sppfNode, edgeTerminal, target, inputEdge.head, 0) + } + } + } + } + + for ((edgeNonterminal, targetStates) in nonterminalEdges) { + gll.handleNonterminalEdge(descriptor, edgeNonterminal, targetStates, sppfNode) + } + } +} \ No newline at end of file diff --git a/solver/src/main/kotlin/org/ucfs/input/IRecoveryInputGraph.kt b/solver/src/main/kotlin/org/ucfs/intersection/RecoveryIntersection.kt similarity index 58% rename from solver/src/main/kotlin/org/ucfs/input/IRecoveryInputGraph.kt rename to solver/src/main/kotlin/org/ucfs/intersection/RecoveryIntersection.kt index 58491f632..4741bb0af 100644 --- a/solver/src/main/kotlin/org/ucfs/input/IRecoveryInputGraph.kt +++ b/solver/src/main/kotlin/org/ucfs/intersection/RecoveryIntersection.kt @@ -1,56 +1,29 @@ -package org.ucfs.input +package org.ucfs.intersection import org.ucfs.descriptors.Descriptor -import org.ucfs.parser.context.IContext +import org.ucfs.input.Edge +import org.ucfs.input.ILabel +import org.ucfs.input.RecoveryEdge +import org.ucfs.parser.IGll import org.ucfs.rsm.RsmState import org.ucfs.rsm.symbol.ITerminal -import org.ucfs.rsm.symbol.Nonterminal import org.ucfs.sppf.node.SppfNode -/** - * Part of error recovery mechanism. - * Input graph interface with additional methods to support error recovery logic - * @param VertexType - type of vertex in input graph - * @param LabelType - type of label on edges in input graph - */ -interface IRecoveryInputGraph : IInputGraph { +object RecoveryIntersection : IIntersectionEngine{ /** * Process outgoing edges from input position in given descriptor, according to processing logic, represented as * separate functions for processing both outgoing terminal and nonterminal edges from rsmState in descriptor. * Additionally, considers error recovering edges in input graph. Those are the edges that were not present in * initial graph, but could be useful later to successfully parse input - * @param handleTerminalOrEpsilonEdge - function for processing terminal and epsilon edges in RSM - * @param handleNonterminalEdge - function for processing nonterminal edges in RSM - * @param ctx - configuration of Gll parser instance + * @param gll - Gll parser instance * @param descriptor - descriptor, represents current parsing stage * @param sppfNode - root node of derivation tree, corresponds to already parsed portion of input */ - override fun handleEdges( - handleTerminalOrEpsilonEdge: ( - curDescriptor: Descriptor, - curSppfNode: SppfNode?, - terminal: ITerminal?, - targetState: RsmState, - targetVertex: VertexType, - targetWeight: Int, - ) -> Unit, - handleNonterminalEdge: ( - descriptor: Descriptor, - nonterminal: Nonterminal, - targetStates: HashSet, - sppfNode: SppfNode? - ) -> Unit, - ctx: IContext, - descriptor: Descriptor, - sppfNode: SppfNode? + override fun handleEdges( + gll: IGll, descriptor: Descriptor, sppfNode: SppfNode? ) { - super.handleEdges(handleTerminalOrEpsilonEdge, handleNonterminalEdge, ctx, descriptor, sppfNode) - val errorRecoveryEdges = createRecoveryEdges(descriptor) - handleRecoveryEdges( - errorRecoveryEdges, - handleTerminalOrEpsilonEdge, - descriptor - ) + IntersectionEngine.handleEdges(gll, descriptor, sppfNode) + handleRecoveryEdges(gll, descriptor) } /** @@ -58,13 +31,15 @@ interface IRecoveryInputGraph : IInputGraph (destination, weight) */ - private fun createRecoveryEdges(descriptor: Descriptor): HashSet> { + private fun createRecoveryEdges( + gll: IGll, descriptor: Descriptor + ): HashSet> { val inputPosition = descriptor.inputPosition val rsmState = descriptor.rsmState val terminalEdges = rsmState.terminalEdges val errorRecoveryEdges = HashSet>() - val currentEdges = getEdges(inputPosition) + val currentEdges = gll.ctx.input.getEdges(inputPosition) if (currentEdges.isNotEmpty()) { addTerminalRecoveryEdges(terminalEdges, errorRecoveryEdges, inputPosition, rsmState, currentEdges) @@ -82,7 +57,7 @@ interface IRecoveryInputGraph : IInputGraph addEpsilonRecoveryEdges( terminalEdges: HashMap>, errorRecoveryEdges: HashSet>, inputPosition: VertexType, @@ -103,7 +78,7 @@ interface IRecoveryInputGraph : IInputGraph addTerminalRecoveryEdges( terminalEdges: HashMap>, errorRecoveryEdges: HashSet>, inputPosition: VertexType, @@ -126,29 +101,19 @@ interface IRecoveryInputGraph : IInputGraph>, - handleTerminalOrEpsilonEdge: ( - descriptor: Descriptor, - sppfNode: SppfNode?, - terminal: ITerminal?, - targetState: RsmState, - targetVertex: VertexType, - targetWeight: Int, - ) -> Unit, - descriptor: Descriptor + fun handleRecoveryEdges( + gll: IGll, descriptor: Descriptor ) { + val errorRecoveryEdges: HashSet> = createRecoveryEdges(gll, descriptor) val terminalEdges = descriptor.rsmState.terminalEdges for (errorRecoveryEdge in errorRecoveryEdges) { @@ -157,23 +122,13 @@ interface IRecoveryInputGraph : IInputGraph : IInputGraph private constructor( - override var ctx: IContext, + override var ctx: IContext, val engine: IIntersectionEngine ) : IGll { companion object { @@ -28,10 +30,9 @@ class Gll private constructor( * @return default instance of gll parser */ fun gll( - startState: RsmState, - inputGraph: IInputGraph + startState: RsmState, inputGraph: IInputGraph ): Gll { - return Gll(Context(startState, inputGraph)) + return Gll(Context(startState, inputGraph), IntersectionEngine) } /** @@ -42,10 +43,9 @@ class Gll private constructor( * @return recovery instance of gll parser */ fun recoveryGll( - startState: RsmState, - inputGraph: IRecoveryInputGraph + startState: RsmState, inputGraph: IInputGraph ): Gll { - return Gll(RecoveryContext(startState, inputGraph)) + return Gll(RecoveryContext(startState, inputGraph), RecoveryIntersection) } } @@ -78,21 +78,16 @@ class Gll private constructor( pop(descriptor.gssNode, sppfNode ?: epsilonSppfNode, pos) } - ctx.descriptors.addToHandled(descriptor) if (state.isStart && state.isFinal) { - checkAcceptance(epsilonSppfNode, epsilonSppfNode!!.leftExtent, epsilonSppfNode!!.rightExtent, state.nonterminal) + checkAcceptance( + epsilonSppfNode, epsilonSppfNode!!.leftExtent, epsilonSppfNode!!.rightExtent, state.nonterminal + ) } checkAcceptance(sppfNode, leftExtent, rightExtent, state.nonterminal) - ctx.input.handleEdges( - this::handleTerminalOrEpsilonEdge, - this::handleNonterminalEdge, - ctx, - descriptor, - sppfNode - ) + engine.handleEdges(this, descriptor, sppfNode) } } diff --git a/solver/src/main/kotlin/org/ucfs/parser/IGll.kt b/solver/src/main/kotlin/org/ucfs/parser/IGll.kt index 1f4435a78..e2b9309a4 100644 --- a/solver/src/main/kotlin/org/ucfs/parser/IGll.kt +++ b/solver/src/main/kotlin/org/ucfs/parser/IGll.kt @@ -74,14 +74,11 @@ interface IGll { weight: Int, ): GssNode { val gssNode = GssNode(nonterminal, inputPosition, weight) - - if (ctx.createdGssNodes.containsKey(gssNode)) { - if (ctx.createdGssNodes.getValue(gssNode).minWeightOfLeftPart > weight) { - ctx.createdGssNodes.getValue(gssNode).minWeightOfLeftPart = weight - } - } else ctx.createdGssNodes[gssNode] = gssNode - - return ctx.createdGssNodes.getValue(gssNode) + val storedNode = ctx.createdGssNodes.computeIfAbsent(gssNode) { gssNode } + if (storedNode.minWeightOfLeftPart > weight) { + storedNode.minWeightOfLeftPart = weight + } + return storedNode } /** @@ -99,8 +96,9 @@ interface IGll { sppfNode: SppfNode?, inputPosition: VertexType, ): GssNode { - val newNode = - getOrCreateGssNode(nonterminal, inputPosition, weight = gssNode.minWeightOfLeftPart + (sppfNode?.weight ?: 0)) + val newNode = getOrCreateGssNode( + nonterminal, inputPosition, weight = gssNode.minWeightOfLeftPart + (sppfNode?.weight ?: 0) + ) if (newNode.addEdge(rsmState, sppfNode, gssNode)) { if (ctx.poppedGssNodes.containsKey(newNode)) { @@ -154,15 +152,11 @@ interface IGll { * @param nonterminal - nonterminal, which defines language we check belonging to */ fun checkAcceptance( - sppfNode: SppfNode?, - leftExtent: VertexType?, - rightExtent: VertexType?, - nonterminal: Nonterminal + sppfNode: SppfNode?, leftExtent: VertexType?, rightExtent: VertexType?, nonterminal: Nonterminal ) { - if (sppfNode is SymbolSppfNode - && nonterminal == ctx.startState.nonterminal - && ctx.input.isStart(leftExtent!!) - && ctx.input.isFinal(rightExtent!!) + if (sppfNode is SymbolSppfNode && nonterminal == ctx.startState.nonterminal && ctx.input.isStart( + leftExtent!! + ) && ctx.input.isFinal(rightExtent!!) ) { if (ctx.parseResult == null || ctx.parseResult!!.weight > sppfNode.weight) { ctx.parseResult = sppfNode @@ -172,12 +166,11 @@ interface IGll { val pair = Pair(leftExtent, rightExtent) val distance = ctx.sppf.minDistance(sppfNode) - ctx.reachabilityPairs[pair] = - if (ctx.reachabilityPairs.containsKey(pair)) { - minOf(distance, ctx.reachabilityPairs[pair]!!) - } else { - distance - } + ctx.reachabilityPairs[pair] = if (ctx.reachabilityPairs.containsKey(pair)) { + minOf(distance, ctx.reachabilityPairs[pair]!!) + } else { + distance + } } } diff --git a/solver/src/main/kotlin/org/ucfs/parser/context/Context.kt b/solver/src/main/kotlin/org/ucfs/parser/context/Context.kt index dbd7a163c..6498b5539 100644 --- a/solver/src/main/kotlin/org/ucfs/parser/context/Context.kt +++ b/solver/src/main/kotlin/org/ucfs/parser/context/Context.kt @@ -14,8 +14,7 @@ import org.ucfs.sppf.node.SppfNode * @param LabelType - type of label on edges in input graph */ class Context( - override val startState: RsmState, - override val input: IInputGraph + override val startState: RsmState, override val input: IInputGraph ) : IContext { override val descriptors: DescriptorsStorage = DescriptorsStorage() override val sppf: Sppf = Sppf() diff --git a/solver/src/main/kotlin/org/ucfs/parser/context/IContext.kt b/solver/src/main/kotlin/org/ucfs/parser/context/IContext.kt index d622f1f03..821a047f3 100644 --- a/solver/src/main/kotlin/org/ucfs/parser/context/IContext.kt +++ b/solver/src/main/kotlin/org/ucfs/parser/context/IContext.kt @@ -73,8 +73,9 @@ interface IContext { val leftExtent = sppfNode?.leftExtent val rightExtent = sppfNode?.rightExtent - if (parseResult == null && sppfNode is SymbolSppfNode<*> && state.nonterminal == startState.nonterminal && - input.isStart(leftExtent!!) && input.isFinal(rightExtent!!) + if (parseResult == null && sppfNode is SymbolSppfNode<*> && state.nonterminal == startState.nonterminal && input.isStart( + leftExtent!! + ) && input.isFinal(rightExtent!!) ) { descriptors.removeFromHandled(descriptor) } diff --git a/solver/src/main/kotlin/org/ucfs/parser/context/RecoveryContext.kt b/solver/src/main/kotlin/org/ucfs/parser/context/RecoveryContext.kt index e965ea025..d4b77bd36 100644 --- a/solver/src/main/kotlin/org/ucfs/parser/context/RecoveryContext.kt +++ b/solver/src/main/kotlin/org/ucfs/parser/context/RecoveryContext.kt @@ -3,8 +3,8 @@ package org.ucfs.parser.context import org.ucfs.descriptors.Descriptor import org.ucfs.descriptors.RecoveringDescriptorsStorage import org.ucfs.gss.GssNode +import org.ucfs.input.IInputGraph import org.ucfs.input.ILabel -import org.ucfs.input.IRecoveryInputGraph import org.ucfs.rsm.RsmState import org.ucfs.sppf.RecoverySppf import org.ucfs.sppf.node.SppfNode @@ -15,8 +15,7 @@ import org.ucfs.sppf.node.SppfNode * @param LabelType - type of label on edges in input graph */ class RecoveryContext( - override val startState: RsmState, - override val input: IRecoveryInputGraph + override val startState: RsmState, override val input: IInputGraph ) : IContext { override val descriptors: RecoveringDescriptorsStorage = RecoveringDescriptorsStorage() override val sppf: RecoverySppf = RecoverySppf() diff --git a/solver/src/main/kotlin/org/ucfs/rsm/RsmState.kt b/solver/src/main/kotlin/org/ucfs/rsm/RsmState.kt index a9f57f516..a3e219e17 100644 --- a/solver/src/main/kotlin/org/ucfs/rsm/RsmState.kt +++ b/solver/src/main/kotlin/org/ucfs/rsm/RsmState.kt @@ -13,16 +13,8 @@ open class RsmState( val isStart: Boolean = false, val isFinal: Boolean = false, ) { - val id: String = getId(nonterminal) - - companion object { - private val counters = HashMap() - private fun getId(nt: Nonterminal): String { - val id = counters.getOrPut(nt) { 0 } - counters[nt] = id + 1 - return "${nt.name}_${(id)}" - } - } + val numId: Int = nonterminal.getNextRsmStateId() + val id: String = "${nonterminal.name}_${(numId)}" val outgoingEdges get() = terminalEdges.plus(nonterminalEdges) diff --git a/solver/src/main/kotlin/org/ucfs/rsm/symbol/Nonterminal.kt b/solver/src/main/kotlin/org/ucfs/rsm/symbol/Nonterminal.kt index 895806e16..c68da6e16 100644 --- a/solver/src/main/kotlin/org/ucfs/rsm/symbol/Nonterminal.kt +++ b/solver/src/main/kotlin/org/ucfs/rsm/symbol/Nonterminal.kt @@ -3,10 +3,17 @@ package org.ucfs.rsm.symbol import org.ucfs.rsm.RsmState import java.util.* -class Nonterminal(val name: String?) : Symbol { +data class Nonterminal(val name: String?) : Symbol { lateinit var startState: RsmState + private var rsmStateLastId = 0 override fun toString() = "Nonterminal(${name ?: this.hashCode()})" + fun getNextRsmStateId(): Int { + val id = rsmStateLastId + rsmStateLastId++ + return id + } + /** * Get all states from RSM for current nonterminal */ diff --git a/solver/src/test/kotlin/rsm/api/TerminalsEqualsTest.kt b/solver/src/test/kotlin/rsm/api/TerminalsEqualsTest.kt index 7e7a4ea23..7965bd6e5 100644 --- a/solver/src/test/kotlin/rsm/api/TerminalsEqualsTest.kt +++ b/solver/src/test/kotlin/rsm/api/TerminalsEqualsTest.kt @@ -3,29 +3,27 @@ package rsm.api import org.junit.jupiter.api.Test import org.ucfs.grammar.combinator.Grammar import org.ucfs.grammar.combinator.regexp.Nt -import org.ucfs.rsm.symbol.Term import org.ucfs.grammar.combinator.regexp.or import org.ucfs.grammar.combinator.regexp.times +import org.ucfs.rsm.symbol.Term import rsm.RsmTest import kotlin.test.assertTrue class TerminalsEqualsTest : RsmTest { class AStarTerms : Grammar() { - var S by Nt() + val S by Nt().asStart() init { - setStart(S) - S = Term("a") or Term("a") * S or S * S + S /= Term("a") or Term("a") * S or S * S } } class AStar : Grammar() { - var S by Nt() + val S by Nt().asStart() val A = Term("a") init { - setStart(S) - S = A or A * S or S * S + S /= A or A * S or S * S } } diff --git a/solver/src/test/kotlin/rsm/builder/AStarTest.kt b/solver/src/test/kotlin/rsm/builder/AStarTest.kt index fecf6799e..0805e2aa8 100644 --- a/solver/src/test/kotlin/rsm/builder/AStarTest.kt +++ b/solver/src/test/kotlin/rsm/builder/AStarTest.kt @@ -3,27 +3,26 @@ package rsm.builder import org.junit.jupiter.api.Test import org.ucfs.grammar.combinator.Grammar import org.ucfs.grammar.combinator.regexp.Nt -import org.ucfs.rsm.symbol.Term import org.ucfs.grammar.combinator.regexp.or import org.ucfs.grammar.combinator.regexp.times +import org.ucfs.rsm.symbol.Term import rsm.RsmTest import kotlin.test.assertNotNull import kotlin.test.assertTrue class AStarTest : RsmTest { class AStar : Grammar() { - var S by Nt() + val S by Nt().asStart() init { - setStart(S) - S = Term("a") or Term("a") * S or S * S + S /= Term("a") or Term("a") * S or S * S } } @Test fun testRsm() { val grammar = AStar() - assertNotNull(grammar.S.getNonterminal()) + assertNotNull(grammar.S.nonterm) assertTrue { equalsByNtName(getAStarRsm("S"), grammar.rsm) } } } \ No newline at end of file diff --git a/test-shared/src/test/kotlin/parser/generated/RuntimeCompiler.kt b/test-shared/src/test/kotlin/parser/generated/RuntimeCompiler.kt index 97808077c..084dbd068 100644 --- a/test-shared/src/test/kotlin/parser/generated/RuntimeCompiler.kt +++ b/test-shared/src/test/kotlin/parser/generated/RuntimeCompiler.kt @@ -5,7 +5,6 @@ import com.tschuchort.compiletesting.SourceFile import org.ucfs.GeneratorException import org.ucfs.input.LinearInputLabel import org.ucfs.parser.GeneratedParser -import org.ucfs.parser.IParserGenerator import org.ucfs.parser.ParserGenerator import org.ucfs.parser.ScanerlessParserGenerator import parser.generated.GllGeneratedTest.Companion.DSL_FILE_NAME @@ -38,20 +37,21 @@ object RuntimeCompiler { @Suppress("UNCHECKED_CAST") fun loadScanerlessParser(grammarFolderFile: File): Class<*> { val grammarName = grammarFolderFile.name - val parserName = IParserGenerator.getParserClassName(SCANERLESS_DSL_FILE_NAME) + //val parserName = ScanerlessParserGenerator().getParserClassName(SCANERLESS_DSL_FILE_NAME) - fun generateParserCode(): KotlinCompilation.Result { + fun generateParserCode(): Pair { val grammar = getKtSource(grammarFolderFile, SCANERLESS_DSL_FILE_NAME) val compilationResult = compileClasses(listOf(grammar)) val classLoader = compilationResult.classLoader val grammarClass = classLoader.loadFromGrammar(SCANERLESS_DSL_FILE_NAME, grammarName) - ScanerlessParserGenerator(grammarClass).generate(parsersFolder, getParserPkg(grammarName)) - return compilationResult + val generator = ScanerlessParserGenerator(grammarClass) + generator.generate(parsersFolder, getParserPkg(grammarName)) + return Pair(compilationResult, generator.getParserClassName()) } - var compilationResult = generateParserCode() + var (compilationResult, parserName) = generateParserCode() val parser = getKtSource(generationPath.resolve(grammarName).toFile(), parserName) compilationResult = compileClasses( @@ -76,9 +76,8 @@ object RuntimeCompiler { @Suppress("UNCHECKED_CAST") fun loadParser(grammarFolderFile: File): ParsingClasses { val grammarName = grammarFolderFile.name - val parserName = IParserGenerator.getParserClassName(DSL_FILE_NAME) - fun generateParserCode(): KotlinCompilation.Result { + fun generateParserCode(): Pair { val token = getKtSource(grammarFolderFile, TOKENS) val grammar = getKtSource(grammarFolderFile, DSL_FILE_NAME) val compilationResult = compileClasses(listOf(token, grammar)) @@ -87,11 +86,12 @@ object RuntimeCompiler { val grammarClass = classLoader.loadFromGrammar(DSL_FILE_NAME, grammarName) val tokenClass = classLoader.loadFromGrammar(TOKENS, grammarName) - ParserGenerator(grammarClass, tokenClass).generate(parsersFolder, getParserPkg(grammarName)) - return compilationResult + val generator = ParserGenerator(grammarClass, tokenClass) + generator.generate(parsersFolder, getParserPkg(grammarName)) + return Pair(compilationResult, generator.getParserClassName()) } - var compilationResult = generateParserCode() + var (compilationResult, parserName) = generateParserCode() val lexer = getKtSource(grammarFolderFile, LEXER_NAME) val parser = getKtSource(generationPath.resolve(grammarName).toFile(), parserName) @@ -131,7 +131,7 @@ object RuntimeCompiler { /** * Compile all files for given sources */ - fun compileClasses(sourceFiles: List, classpath: List = emptyList()): KotlinCompilation.Result { + private fun compileClasses(sourceFiles: List, classpath: List = emptyList()): KotlinCompilation.Result { val compileResult = KotlinCompilation().apply { sources = sourceFiles //use application classpath diff --git a/test-shared/src/test/resources/grammars/a/ScanerlessGrammarDsl.kt b/test-shared/src/test/resources/grammars/a/ScanerlessGrammarDsl.kt index 4f571948e..cbdcb0490 100644 --- a/test-shared/src/test/resources/grammars/a/ScanerlessGrammarDsl.kt +++ b/test-shared/src/test/resources/grammars/a/ScanerlessGrammarDsl.kt @@ -5,10 +5,5 @@ import org.ucfs.grammar.combinator.regexp.Nt import org.ucfs.rsm.symbol.Term class ScanerlessGrammarDsl : Grammar() { - var S by Nt() - - init { - setStart(S) - S = Term("a") - } + val S by Nt(Term("a")).asStart() } \ No newline at end of file diff --git a/test-shared/src/test/resources/grammars/aBStar/ScanerlessGrammarDsl.kt b/test-shared/src/test/resources/grammars/aBStar/ScanerlessGrammarDsl.kt index 001837da3..d2b31d29b 100644 --- a/test-shared/src/test/resources/grammars/aBStar/ScanerlessGrammarDsl.kt +++ b/test-shared/src/test/resources/grammars/aBStar/ScanerlessGrammarDsl.kt @@ -5,11 +5,5 @@ import org.ucfs.grammar.combinator.extension.StringExtension.many import org.ucfs.grammar.combinator.regexp.Nt class ScanerlessGrammarDsl : Grammar() { - var S by Nt() - - init { - setStart(S) - S = many("ab") - } - + val S by Nt(many("ab")).asStart() } \ No newline at end of file diff --git a/test-shared/src/test/resources/grammars/aStar/ScanerlessGrammarDsl.kt b/test-shared/src/test/resources/grammars/aStar/ScanerlessGrammarDsl.kt index 34bcb8295..d90138d27 100644 --- a/test-shared/src/test/resources/grammars/aStar/ScanerlessGrammarDsl.kt +++ b/test-shared/src/test/resources/grammars/aStar/ScanerlessGrammarDsl.kt @@ -5,10 +5,5 @@ import org.ucfs.grammar.combinator.extension.StringExtension.many import org.ucfs.grammar.combinator.regexp.Nt class ScanerlessGrammarDsl : Grammar() { - var S by Nt() - - init { - setStart(S) - S = many("a") - } + val S by Nt(many("a")).asStart() } \ No newline at end of file diff --git a/test-shared/src/test/resources/grammars/ab/ScanerlessGrammarDsl.kt b/test-shared/src/test/resources/grammars/ab/ScanerlessGrammarDsl.kt index 65470f834..c58ef9e75 100644 --- a/test-shared/src/test/resources/grammars/ab/ScanerlessGrammarDsl.kt +++ b/test-shared/src/test/resources/grammars/ab/ScanerlessGrammarDsl.kt @@ -4,11 +4,6 @@ import org.ucfs.grammar.combinator.Grammar import org.ucfs.grammar.combinator.extension.StringExtension.times import org.ucfs.grammar.combinator.regexp.Nt -class ScanerlessGrammarDsl: Grammar() { - var S by Nt() - - init { - setStart(S) - S = "a" * "b" - } +class ScanerlessGrammarDsl : Grammar() { + val S by Nt("a" * "b").asStart() } \ No newline at end of file diff --git a/test-shared/src/test/resources/grammars/abc/ScanerlessGrammarDsl.kt b/test-shared/src/test/resources/grammars/abc/ScanerlessGrammarDsl.kt index 5ed08add0..89e5fc4cc 100644 --- a/test-shared/src/test/resources/grammars/abc/ScanerlessGrammarDsl.kt +++ b/test-shared/src/test/resources/grammars/abc/ScanerlessGrammarDsl.kt @@ -6,14 +6,7 @@ import org.ucfs.grammar.combinator.regexp.* import org.ucfs.rsm.symbol.Term class ScanerlessGrammarDsl: Grammar() { - var S by Nt() - var A by Nt() - var B by Nt() - - init { - setStart(S) - S = "a" * B * "c" or A * "c" - A = "a" * "b" - B = Term("b") - } + val A by Nt("a" * "b") + val B by Nt(Term("b")) + val S by Nt("a" * B * "c" or A * "c").asStart() } \ No newline at end of file diff --git a/test-shared/src/test/resources/grammars/ambiguous/ScanerlessGrammarDsl.kt b/test-shared/src/test/resources/grammars/ambiguous/ScanerlessGrammarDsl.kt index 0620486c1..f1a5994af 100644 --- a/test-shared/src/test/resources/grammars/ambiguous/ScanerlessGrammarDsl.kt +++ b/test-shared/src/test/resources/grammars/ambiguous/ScanerlessGrammarDsl.kt @@ -5,10 +5,9 @@ import org.ucfs.grammar.combinator.extension.StringExtension.or import org.ucfs.grammar.combinator.regexp.* class ScanerlessGrammarDsl: Grammar() { - var S by Nt() + val S by Nt().asStart() init { - setStart(S) - S = "a" or S or S * S or S * S * S + S /= "a" or S or S * S or S * S * S } } \ No newline at end of file diff --git a/test-shared/src/test/resources/grammars/bracket_star_x/ScanerlessGrammarDsl.kt b/test-shared/src/test/resources/grammars/bracket_star_x/ScanerlessGrammarDsl.kt index 1f58819e3..61cd06766 100644 --- a/test-shared/src/test/resources/grammars/bracket_star_x/ScanerlessGrammarDsl.kt +++ b/test-shared/src/test/resources/grammars/bracket_star_x/ScanerlessGrammarDsl.kt @@ -6,12 +6,10 @@ import org.ucfs.grammar.combinator.extension.StringExtension.times import org.ucfs.grammar.combinator.regexp.Nt class ScanerlessGrammarDsl : Grammar() { - var List by Nt() - var Elem by Nt() + val List by Nt().asStart() + val Elem by Nt("x" or List) init { - setStart(List) - List = "[" * Elem - Elem = "x" or List + List /= "[" * Elem } } \ No newline at end of file diff --git a/test-shared/src/test/resources/grammars/cAPlusBStar/ScanerlessGrammarDsl.kt b/test-shared/src/test/resources/grammars/cAPlusBStar/ScanerlessGrammarDsl.kt index df87254c2..b322316ec 100644 --- a/test-shared/src/test/resources/grammars/cAPlusBStar/ScanerlessGrammarDsl.kt +++ b/test-shared/src/test/resources/grammars/cAPlusBStar/ScanerlessGrammarDsl.kt @@ -1,15 +1,12 @@ package grammars.cAPlusBStar import org.ucfs.grammar.combinator.Grammar -import org.ucfs.grammar.combinator.regexp.* +import org.ucfs.grammar.combinator.regexp.many +import org.ucfs.grammar.combinator.regexp.Nt +import org.ucfs.grammar.combinator.regexp.some +import org.ucfs.grammar.combinator.regexp.times import org.ucfs.rsm.symbol.Term class ScanerlessGrammarDsl : Grammar() { - var S by Nt() - - init { - setStart(S) - S = Term("c") * Some(Term("a")) * Many(Term("b")) - } - + val S by Nt(Term("c") * some(Term("a")) * many(Term("b"))).asStart() } \ No newline at end of file diff --git a/test-shared/src/test/resources/grammars/c_a_star_b_star/ScanerlessGrammarDsl.kt b/test-shared/src/test/resources/grammars/c_a_star_b_star/ScanerlessGrammarDsl.kt index 9d159c4c5..389baa6f6 100644 --- a/test-shared/src/test/resources/grammars/c_a_star_b_star/ScanerlessGrammarDsl.kt +++ b/test-shared/src/test/resources/grammars/c_a_star_b_star/ScanerlessGrammarDsl.kt @@ -3,15 +3,10 @@ package grammars.c_a_star_b_star import org.ucfs.grammar.combinator.Grammar import org.ucfs.grammar.combinator.extension.StringExtension.many import org.ucfs.grammar.combinator.extension.StringExtension.times -import org.ucfs.grammar.combinator.regexp.times import org.ucfs.grammar.combinator.regexp.Nt +import org.ucfs.grammar.combinator.regexp.times -class ScanerlessGrammarDsl: Grammar() { - var S by Nt() - - init { - setStart(S) - S = "c" * many("a") * many("b") - } +class ScanerlessGrammarDsl : Grammar() { + val S by Nt("c" * many("a") * many("b")).asStart() } \ No newline at end of file diff --git a/test-shared/src/test/resources/grammars/dyck/ScanerlessGrammarDsl.kt b/test-shared/src/test/resources/grammars/dyck/ScanerlessGrammarDsl.kt index a355ebd66..31ec62d11 100644 --- a/test-shared/src/test/resources/grammars/dyck/ScanerlessGrammarDsl.kt +++ b/test-shared/src/test/resources/grammars/dyck/ScanerlessGrammarDsl.kt @@ -5,10 +5,9 @@ import org.ucfs.grammar.combinator.extension.StringExtension.times import org.ucfs.grammar.combinator.regexp.* class ScanerlessGrammarDsl: Grammar() { - var S by Nt() + val S by Nt().asStart() init { - setStart(S) - S = Epsilon or "(" * S * ")" * S + S /= Epsilon or "(" * S * ")" * S } } \ No newline at end of file diff --git a/test-shared/src/test/resources/grammars/g1/ScanerlessGrammarDsl.kt b/test-shared/src/test/resources/grammars/g1/ScanerlessGrammarDsl.kt index ed27f613f..81c88b793 100644 --- a/test-shared/src/test/resources/grammars/g1/ScanerlessGrammarDsl.kt +++ b/test-shared/src/test/resources/grammars/g1/ScanerlessGrammarDsl.kt @@ -2,14 +2,15 @@ package grammars.g1 import org.ucfs.grammar.combinator.Grammar import org.ucfs.grammar.combinator.extension.StringExtension.times -import org.ucfs.grammar.combinator.regexp.* +import org.ucfs.grammar.combinator.regexp.Nt +import org.ucfs.grammar.combinator.regexp.Option +import org.ucfs.grammar.combinator.regexp.or -class ScanerlessGrammarDsl: Grammar() { - var S by Nt() +class ScanerlessGrammarDsl : Grammar() { + val S by Nt().asStart() init { - setStart(S) - S = "subClassOf_r" * Option(S) * "subClassOf" or + S /= "subClassOf_r" * Option(S) * "subClassOf" or "type_r" * Option(S) * "type" } } \ No newline at end of file diff --git a/test-shared/src/test/resources/grammars/g2/ScanerlessGrammarDsl.kt b/test-shared/src/test/resources/grammars/g2/ScanerlessGrammarDsl.kt index e3a974b90..6c95899c3 100644 --- a/test-shared/src/test/resources/grammars/g2/ScanerlessGrammarDsl.kt +++ b/test-shared/src/test/resources/grammars/g2/ScanerlessGrammarDsl.kt @@ -3,13 +3,12 @@ package grammars.g2 import org.ucfs.grammar.combinator.Grammar import org.ucfs.grammar.combinator.extension.StringExtension.or import org.ucfs.grammar.combinator.extension.StringExtension.times -import org.ucfs.grammar.combinator.regexp.* +import org.ucfs.grammar.combinator.regexp.Nt -class ScanerlessGrammarDsl: Grammar() { - var S by Nt() +class ScanerlessGrammarDsl : Grammar() { + val S by Nt().asStart() init { - setStart(S) - S = "subClassOf" or "subClassOf_r" * S * "subClassOf" + S /= "subClassOf" or "subClassOf_r" * S * "subClassOf" } } \ No newline at end of file diff --git a/test-shared/src/test/resources/grammars/geo/ScanerlessGrammarDsl.kt b/test-shared/src/test/resources/grammars/geo/ScanerlessGrammarDsl.kt index 5f8cf2632..081d96493 100644 --- a/test-shared/src/test/resources/grammars/geo/ScanerlessGrammarDsl.kt +++ b/test-shared/src/test/resources/grammars/geo/ScanerlessGrammarDsl.kt @@ -2,13 +2,13 @@ package grammars.geo import org.ucfs.grammar.combinator.Grammar import org.ucfs.grammar.combinator.extension.StringExtension.times -import org.ucfs.grammar.combinator.regexp.* +import org.ucfs.grammar.combinator.regexp.Nt +import org.ucfs.grammar.combinator.regexp.Option -class ScanerlessGrammarDsl: Grammar() { - var S by Nt() +class ScanerlessGrammarDsl : Grammar() { + val S by Nt().asStart() init { - setStart(S) - S = "broaderTransitive" * Option(S) * "broaderTransitive_r" + S /= "broaderTransitive" * Option(S) * "broaderTransitive_r" } } \ No newline at end of file diff --git a/test-shared/src/test/resources/grammars/multi_dyck/ScanerlessGrammarDsl.kt b/test-shared/src/test/resources/grammars/multi_dyck/ScanerlessGrammarDsl.kt index 7075dbb05..c071badd4 100644 --- a/test-shared/src/test/resources/grammars/multi_dyck/ScanerlessGrammarDsl.kt +++ b/test-shared/src/test/resources/grammars/multi_dyck/ScanerlessGrammarDsl.kt @@ -5,16 +5,12 @@ import org.ucfs.grammar.combinator.extension.StringExtension.times import org.ucfs.grammar.combinator.regexp.* class ScanerlessGrammarDsl: Grammar() { - var S by Nt() - var S1 by Nt() - var S2 by Nt() - var S3 by Nt() + val S by Nt().asStart() + val S1 by Nt("(" * S * ")" * S) + val S2 by Nt("{" * S * "}" * S) + val S3 by Nt("[" * S * "]" * S) init { - setStart(S) - S = Epsilon or S1 or S2 or S3 - S1 = "(" * S * ")" * S - S2 = "{" * S * "}" * S - S3 = "[" * S * "]" * S + S /= Epsilon or S1 or S2 or S3 } } \ No newline at end of file diff --git a/test-shared/src/test/resources/grammars/simple_golang/ScanerlessGrammarDsl.kt b/test-shared/src/test/resources/grammars/simple_golang/ScanerlessGrammarDsl.kt index fb61ca6b2..2d12dfd8a 100644 --- a/test-shared/src/test/resources/grammars/simple_golang/ScanerlessGrammarDsl.kt +++ b/test-shared/src/test/resources/grammars/simple_golang/ScanerlessGrammarDsl.kt @@ -3,19 +3,13 @@ package grammars.simple_golang import org.ucfs.grammar.combinator.Grammar import org.ucfs.grammar.combinator.extension.StringExtension.or import org.ucfs.grammar.combinator.extension.StringExtension.times -import org.ucfs.grammar.combinator.regexp.* +import org.ucfs.grammar.combinator.regexp.Many +import org.ucfs.grammar.combinator.regexp.Nt +import org.ucfs.grammar.combinator.regexp.or -class ScanerlessGrammarDsl: Grammar() { - var Program by Nt() - var Block by Nt() - var Statement by Nt() - var IntExpr by Nt() - - init { - setStart(Program) - Program = Block - Block = Many(Statement) - Statement = IntExpr * ";" or "r" * IntExpr * ";" - IntExpr = "1" or "1" * "+" * "1" - } +class ScanerlessGrammarDsl : Grammar() { + val IntExpr by Nt("1" or "1" * "+" * "1") + val Statement by Nt(IntExpr * ";" or "r" * IntExpr * ";") + val Block by Nt(Many(Statement)) + val Program by Nt(Block).asStart() } \ No newline at end of file