From 04ebf034cc9233499d63bcefc703b00e2a348213 Mon Sep 17 00:00:00 2001 From: Anton Savienko Date: Thu, 7 Dec 2023 14:29:18 -0700 Subject: [PATCH 1/5] hot fix (#3857) --- web/pages/index.md | 1 + 1 file changed, 1 insertion(+) diff --git a/web/pages/index.md b/web/pages/index.md index 07fd8c62480..1d767391f62 100644 --- a/web/pages/index.md +++ b/web/pages/index.md @@ -40,6 +40,7 @@ call/cc. ## Resources +- K Approach and Vision: [slide presentation](https://drive.google.com/file/d/1iXda2NyGzKVWxkd02IlXj5Tq5cOM_gNd/view) - A set of reference implementations and tutorials for common programming language features and paradigms is available, although parts of these implementations may not be fully up to date with modern K features. - Read some papers about K on the [Formal Systems Laboratory (FSL)](https://fsl.cs.illinois.edu/publications/). - [Matching logic](http://matching-logic.org/) webpage at UIUC (USA). From 4269d27cdb901cc779f4d719f4fb035985718008 Mon Sep 17 00:00:00 2001 From: Scott Guest Date: Thu, 7 Dec 2023 23:26:30 -0500 Subject: [PATCH 2/5] Adopt scalafmt for Scala code style (#3841) Closes #3827. This PR adopts [scalafmt](https://scalameta.org/scalafmt/) for Scala code formatting. Specifically, - Both `google-java-format` and `scalafmt` are now handled by the `spotless` Maven plugin - Run `mvn spotless:check` to check formatting (or `mvn verify`) - Run `mvn spotless:apply` to auto-format all source files (or `mvn process-sources` or `mvn package`) - CI runs `mvn spotless:check` to enforce formatting Intellij has built-in support for `scalafmt`. Enable it by opening `Settings > Editor > Code Style > Scala` and setting - Formatter: `Scalafmt` - Configuration: `k/src/main/config/.scalafmt.conf` The documentation on the different configuration options can be found here: https://scalameta.org/scalafmt/docs/configuration.html. Currently, I've formatted with my preferred settings, but committed two versions: - [506616c](https://github.com/runtimeverification/k/pull/3841/commits/506616cb75c8378503393b5503ce0a15d2d3c017), which does not enforce vertical alignment - [602fd2e](https://github.com/runtimeverification/k/pull/3841/commits/602fd2e47ae4fbd97b1be4430a48428fd76345ff), which does enforce vertical alignment I'd appreciate if everyone who works on the frontend could skim through the files and let me know your thoughts! --------- Co-authored-by: rv-jenkins Co-authored-by: Bruce Collie Co-authored-by: Jost Berthold --- .github/workflows/test-pr.yml | 15 +- flake.nix | 2 +- .../backend/kore/ClaimAttributes.scala | 29 +- .../kframework/backend/kore/KoreTest.scala | 123 +-- .../kframework/backend/kore/NoAppendIT.scala | 12 +- kore/build.sbt | 6 +- kore/project/build.sbt | 2 +- .../src/main/scala/org/kframework/POSet.scala | 92 ++- .../scala/org/kframework/RewriterResult.scala | 8 +- .../main/scala/org/kframework/Strategy.scala | 100 ++- .../org/kframework/TopologicalSort.scala | 6 +- .../scala/org/kframework/attributes/Att.scala | 474 ++++++----- .../org/kframework/attributes/Location.scala | 11 +- .../scala/org/kframework/builtin/Sorts.scala | 46 +- .../scala/org/kframework/collections.scala | 59 +- ...ottomSortForListsWithIdenticalLabels.scala | 40 +- .../kframework/compile/AssocCommToAssoc.scala | 99 ++- .../compile/ConfigurationInfoFromModule.scala | 162 ++-- .../compile/LabelInfoFromModule.scala | 17 +- .../org/kframework/compile/MergeRules.scala | 152 ++-- .../kframework/compile/NormalizeAssoc.scala | 37 +- .../kframework/compile/NormalizeKSeq.scala | 19 +- .../org/kframework/compile/RewriteToTop.scala | 82 +- .../kframework/definition/Constructors.scala | 82 +- .../org/kframework/definition/outer-ext.scala | 92 ++- .../definition/outer-to-string.scala | 38 +- .../org/kframework/definition/outer.scala | 764 +++++++++++------- .../kframework/definition/transformers.scala | 173 ++-- .../main/scala/org/kframework/kore/ADT.scala | 71 +- .../scala/org/kframework/kore/Assoc.scala | 19 +- .../org/kframework/kore/Constructors.scala | 23 +- .../main/scala/org/kframework/kore/KORE.scala | 41 +- .../main/scala/org/kframework/kore/Rich.scala | 5 +- .../org/kframework/kore/ScalaSugar.scala | 29 +- .../scala/org/kframework/kore/Unapply.scala | 2 +- .../scala/org/kframework/kore/interface.scala | 111 +-- .../org/kframework/kore/transformers.scala | 46 +- .../org/kframework/parser/Transformer.scala | 101 +-- .../kframework/parser/TreeNodesToKORE.scala | 105 ++- .../org/kframework/parser/kore/Default.scala | 151 ++-- .../kframework/parser/kore/Interface.scala | 261 +++--- .../parser/kore/parser/KoreToK.scala | 104 +-- .../parser/kore/parser/Scanner.scala | 116 +-- .../parser/kore/parser/TextToKore.scala | 282 +++---- .../org/kframework/parser/treeNodes.scala | 16 +- .../org/kframework/rewriter/Rewriter.scala | 55 +- .../kframework/unparser/KOREToTreeNodes.scala | 71 +- .../org/kframework/unparser/Unparse.scala | 84 +- .../test/scala/org/kframework/POSetTest.scala | 5 +- .../org/kframework/definition/OuterTest.scala | 225 ++++-- .../kframework/definition/VisitorTest.scala | 9 +- .../parser/kore/InterfaceTest.scala | 6 +- .../parser/kore/parser/TextToKoreTest.scala | 56 +- .../org/kframework/unparser/UnparseTest.scala | 54 +- pom.xml | 59 +- src/main/config/.scalafmt.conf | 27 + 56 files changed, 2888 insertions(+), 1988 deletions(-) create mode 100644 src/main/config/.scalafmt.conf diff --git a/.github/workflows/test-pr.yml b/.github/workflows/test-pr.yml index af9ae782c35..17b6058967e 100644 --- a/.github/workflows/test-pr.yml +++ b/.github/workflows/test-pr.yml @@ -30,26 +30,23 @@ jobs: fi format-check: - name: 'Check Java code formatting' + name: 'Check code formatting' runs-on: ubuntu-latest needs: version-sync steps: - name: 'Check out code' uses: actions/checkout@v3 with: - token: ${{ secrets.JENKINS_GITHUB_PAT }} - # fetch-depth 0 means deep clone the repo - fetch-depth: 0 + submodules: recursive - name: 'Set up Java 17' uses: actions/setup-java@v3 with: distribution: 'zulu' java-version: 17 + - name: 'Install Maven' + run: sudo apt-get update && sudo apt-get install --yes maven - name: 'Check code is formatted correctly' - uses: axel-op/googlejavaformat-action@v3 - with: - version: v1.18.1 - args: "--dry-run --set-exit-if-changed" + run: mvn spotless:check --batch-mode -U test-k: name: 'K Tests' @@ -68,7 +65,7 @@ jobs: distro: jammy llvm: 15 - name: 'Build and Test K' - run: docker exec -t k-ci-${GITHUB_SHA} /bin/bash -c 'mvn verify --batch-mode -U' + run: docker exec -t k-ci-${GITHUB_SHA} /bin/bash -c 'mvn verify -Dspotless.check.skip=true --batch-mode -U' - name: 'Check out k-exercises' uses: actions/checkout@v3 with: diff --git a/flake.nix b/flake.nix index bf14f47d6e7..2d3e5c9d06d 100644 --- a/flake.nix +++ b/flake.nix @@ -62,7 +62,7 @@ k-framework = { haskell-backend-bins, llvm-kompile-libs }: prev.callPackage ./nix/k.nix { - mvnHash = "sha256-515qtUCNyqq+PchTLObbb4FtlHjtmTAnI+MDidjiENE="; + mvnHash = "sha256-AMxXqu1bbpnmsmLTizNw1n2llSdvx6AuNZRGUHqPn14="; manualMvnArtifacts = [ "org.scala-lang:scala-compiler:2.12.18" "ant-contrib:ant-contrib:1.0b3" diff --git a/k-distribution/src/test/scala/org/kframework/backend/kore/ClaimAttributes.scala b/k-distribution/src/test/scala/org/kframework/backend/kore/ClaimAttributes.scala index 30138ad4525..41318e093e3 100644 --- a/k-distribution/src/test/scala/org/kframework/backend/kore/ClaimAttributes.scala +++ b/k-distribution/src/test/scala/org/kframework/backend/kore/ClaimAttributes.scala @@ -10,24 +10,31 @@ import org.kframework.parser.kore._ class ClaimAttributes extends KoreTest { @Test def test() { - val definition = this.kompile("module TEST [all-path] configuration $PGM:K syntax Exp ::= \"a\" | \"b\" " + - "rule a => b [one-path] " + - "rule a => b [all-path] " + - "rule a => b " + - "endmodule") + val definition = this.kompile( + "module TEST [all-path] configuration $PGM:K syntax Exp ::= \"a\" | \"b\" " + + "rule a => b [one-path] " + + "rule a => b [all-path] " + + "rule a => b " + + "endmodule" + ) val claims = this.claims(definition) assertEquals(3, claims.size) var one_path = 0 var all_path = 0 - for (claim <- claims) { + for (claim <- claims) if (this.hasAttribute(claim.att, Att.ONE_PATH.key)) { - one_path=one_path+1; - assertEquals(KLabels.RL_wEF.name, claim.pattern.asInstanceOf[Implies]._2.asInstanceOf[Application].head.ctr); + one_path = one_path + 1; + assertEquals( + KLabels.RL_wEF.name, + claim.pattern.asInstanceOf[Implies]._2.asInstanceOf[Application].head.ctr + ); } else { - assertEquals(KLabels.RL_wAF.name, claim.pattern.asInstanceOf[Implies]._2.asInstanceOf[Application].head.ctr); - all_path=all_path+1; + assertEquals( + KLabels.RL_wAF.name, + claim.pattern.asInstanceOf[Implies]._2.asInstanceOf[Application].head.ctr + ); + all_path = all_path + 1; } - } assertEquals(1, one_path); assertEquals(2, all_path); } diff --git a/k-distribution/src/test/scala/org/kframework/backend/kore/KoreTest.scala b/k-distribution/src/test/scala/org/kframework/backend/kore/KoreTest.scala index d6804496815..d0e9c9c0501 100644 --- a/k-distribution/src/test/scala/org/kframework/backend/kore/KoreTest.scala +++ b/k-distribution/src/test/scala/org/kframework/backend/kore/KoreTest.scala @@ -1,22 +1,21 @@ // Copyright (c) K Team. All Rights Reserved. package org.kframework.backend.kore +import java.io.File +import java.nio.file.Files import org.kframework.compile.Backend import org.kframework.kompile.Kompile import org.kframework.kompile.KompileOptions import org.kframework.main.GlobalOptions import org.kframework.main.Tool +import org.kframework.parser.kore._ +import org.kframework.parser.kore.implementation.{ DefaultBuilders => B } +import org.kframework.parser.kore.parser.TextToKore import org.kframework.utils.errorsystem.KExceptionManager import org.kframework.utils.file.FileUtil +import org.kframework.utils.options.InnerParsingOptions import org.kframework.utils.options.OuterParsingOptions -import org.kframework.parser.kore._ -import org.kframework.parser.kore.implementation.{DefaultBuilders => B} -import org.kframework.parser.kore.parser.TextToKore import org.kframework.utils.Stopwatch -import org.kframework.utils.options.InnerParsingOptions - -import java.io.File -import java.nio.file.Files class KoreTest { @@ -24,7 +23,7 @@ class KoreTest { val files: FileUtil = { val tempRoot = Files.createTempDirectory("kore-test").toFile - val tempDir = new File(tempRoot, "tmp") + val tempDir = new File(tempRoot, "tmp") tempDir.mkdirs() val kompiledDir = new File(tempRoot, "kompiled") kompiledDir.mkdirs() @@ -41,29 +40,45 @@ class KoreTest { def kompile(k: String): Definition = { val go = new GlobalOptions(); - val compiler = new Kompile(options, new OuterParsingOptions(), new InnerParsingOptions(), go, files, kem, new Stopwatch(go), false) + val compiler = new Kompile( + options, + new OuterParsingOptions(), + new InnerParsingOptions(), + go, + files, + kem, + new Stopwatch(go), + false + ) val backend = new KoreBackend(options, files, kem, Tool.KOMPILE) files.saveToDefinitionDirectory("test.k", k) - val defn = compiler.run(files.resolveDefinitionDirectory("test.k"), "TEST", "TEST", backend.steps, backend.excludedModuleTags) + val defn = compiler.run( + files.resolveDefinitionDirectory("test.k"), + "TEST", + "TEST", + backend.steps, + backend.excludedModuleTags + ) backend.accept(new Backend.Holder(defn)) new TextToKore().parse(files.resolveDefinitionDirectory("test.kore")) } - def axioms(defn: Definition): Seq[AxiomDeclaration] = { - defn.modules.flatMap(_.decls.filter(_.isInstanceOf[AxiomDeclaration]).map(_.asInstanceOf[AxiomDeclaration])) - } + def axioms(defn: Definition): Seq[AxiomDeclaration] = + defn.modules.flatMap( + _.decls.filter(_.isInstanceOf[AxiomDeclaration]).map(_.asInstanceOf[AxiomDeclaration]) + ) def axioms(k: String): Seq[AxiomDeclaration] = axioms(kompile(k)) - def claims(defn: Definition): Seq[ClaimDeclaration] = { - defn.modules.flatMap(_.decls.filter(_.isInstanceOf[ClaimDeclaration]).map(_.asInstanceOf[ClaimDeclaration])) - } + def claims(defn: Definition): Seq[ClaimDeclaration] = + defn.modules.flatMap( + _.decls.filter(_.isInstanceOf[ClaimDeclaration]).map(_.asInstanceOf[ClaimDeclaration]) + ) def claims(k: String): Seq[ClaimDeclaration] = claims(kompile(k)) - def hasAttribute(attributes: Attributes, name : String) : Boolean = { + def hasAttribute(attributes: Attributes, name: String): Boolean = attributes.patterns.exists { case p: Application => p.head.ctr == name } - } // get the rewrite associated with a rule or equational axiom // @@ -77,47 +92,65 @@ class KoreTest { // \implies(\and(_, \top), \and(\equals(lhs, rhs), _)) // \equals(lhs, rhs) def getRewrite(axiom: AxiomDeclaration): Option[GeneralizedRewrite] = { - def go(pattern: Pattern): Option[GeneralizedRewrite] = { + def go(pattern: Pattern): Option[GeneralizedRewrite] = pattern match { - case And(_, Equals(_, _, _, _) +: And(_, _ +: (rw @ Rewrites(_, _, _)) +: Seq()) +: Seq()) => Some(rw) + case And( + _, + Equals(_, _, _, _) +: And(_, _ +: (rw @ Rewrites(_, _, _)) +: Seq()) +: Seq() + ) => + Some(rw) case And(_, Top(_) +: And(_, _ +: (rw @ Rewrites(_, _, _)) +: Seq()) +: Seq()) => Some(rw) - case Rewrites(s, And(_, Equals(_, _, _, _) +: l +: Seq()), And(_, _ +: r +: Seq())) => Some(B.Rewrites(s, l, r)) - case Rewrites(s, And(_, Top(_) +: l +: Seq()), And(_, _ +: r +: Seq())) => Some(B.Rewrites(s, l, r)) - case Implies(_, Equals(_, _, _, _), And(_, (eq @ Equals(_, _, Application(_, _), _)) +: _ +: Seq())) => Some(eq) - case Implies(_, Top(_), And(_, (eq @ Equals(_, _, Application(_, _), _)) +: _ +: Seq())) => Some(eq) - case Implies(_, And(_, _ +: Equals(_, _, _, _) +: Seq()), And(_, (eq @ Equals(_, _, Application(_, _), _)) +: _ +: Seq())) => Some(eq) - case Implies(_, And(_, _ +: Top(_) +: Seq()), And(_, (eq @ Equals(_, _, Application(_, _), _)) +: _ +: Seq())) => Some(eq) + case Rewrites(s, And(_, Equals(_, _, _, _) +: l +: Seq()), And(_, _ +: r +: Seq())) => + Some(B.Rewrites(s, l, r)) + case Rewrites(s, And(_, Top(_) +: l +: Seq()), And(_, _ +: r +: Seq())) => + Some(B.Rewrites(s, l, r)) + case Implies( + _, + Equals(_, _, _, _), + And(_, (eq @ Equals(_, _, Application(_, _), _)) +: _ +: Seq()) + ) => + Some(eq) + case Implies(_, Top(_), And(_, (eq @ Equals(_, _, Application(_, _), _)) +: _ +: Seq())) => + Some(eq) + case Implies( + _, + And(_, _ +: Equals(_, _, _, _) +: Seq()), + And(_, (eq @ Equals(_, _, Application(_, _), _)) +: _ +: Seq()) + ) => + Some(eq) + case Implies( + _, + And(_, _ +: Top(_) +: Seq()), + And(_, (eq @ Equals(_, _, Application(_, _), _)) +: _ +: Seq()) + ) => + Some(eq) case eq @ Equals(_, _, Application(_, _), _) => Some(eq) - case _ => None + case _ => None } - } go(axiom.pattern) } - private def isConcrete(symbol: SymbolOrAlias) : Boolean = { + private def isConcrete(symbol: SymbolOrAlias): Boolean = symbol.params.forall(_.isInstanceOf[CompoundSort]) - } - def symbols(pat: Pattern): Seq[SymbolOrAlias] = { + def symbols(pat: Pattern): Seq[SymbolOrAlias] = pat match { - case And(_, ps) => ps.flatMap(symbols) - case Application(s, ps) => Seq(s).filter(isConcrete) ++ ps.flatMap(symbols) - case Ceil(_, _, p) => symbols(p) + case And(_, ps) => ps.flatMap(symbols) + case Application(s, ps) => Seq(s).filter(isConcrete) ++ ps.flatMap(symbols) + case Ceil(_, _, p) => symbols(p) case Equals(_, _, p1, p2) => symbols(p1) ++ symbols(p2) - case Exists(_, _, p) => symbols(p) - case Floor(_, _, p) => symbols(p) - case Forall(_, _, p) => symbols(p) - case Iff(_, p1, p2) => symbols(p1) ++ symbols(p2) - case Implies(_, p1, p2) => symbols(p1) ++ symbols(p2) - case Mem(_, _, p1, p2) => symbols(p1) ++ symbols(p2) + case Exists(_, _, p) => symbols(p) + case Floor(_, _, p) => symbols(p) + case Forall(_, _, p) => symbols(p) + case Iff(_, p1, p2) => symbols(p1) ++ symbols(p2) + case Implies(_, p1, p2) => symbols(p1) ++ symbols(p2) + case Mem(_, _, p1, p2) => symbols(p1) ++ symbols(p2) // case Next(_, p) => symbols(p) - case Not(_, p) => symbols(p) - case Or(_, ps) => ps.flatMap(symbols) + case Not(_, p) => symbols(p) + case Or(_, ps) => ps.flatMap(symbols) case Rewrites(_, p1, p2) => symbols(p1) ++ symbols(p2) - case _ => Seq() + case _ => Seq() } - } - } diff --git a/k-distribution/src/test/scala/org/kframework/backend/kore/NoAppendIT.scala b/k-distribution/src/test/scala/org/kframework/backend/kore/NoAppendIT.scala index 155e6dc5c02..78c9a25015c 100644 --- a/k-distribution/src/test/scala/org/kframework/backend/kore/NoAppendIT.scala +++ b/k-distribution/src/test/scala/org/kframework/backend/kore/NoAppendIT.scala @@ -1,22 +1,22 @@ // Copyright (c) K Team. All Rights Reserved. package org.kframework.backend.kore -import org.kframework.parser.kore.implementation.{DefaultBuilders => B} - -import org.junit.Test import org.junit.Assert._ +import org.junit.Test +import org.kframework.parser.kore.implementation.{ DefaultBuilders => B } class NoAppendIT extends KoreTest { @Test def test() { - val axioms = this.axioms("module TEST imports K-EQUAL imports DEFAULT-STRATEGY configuration $PGM:K endmodule") + val axioms = this.axioms( + "module TEST imports K-EQUAL imports DEFAULT-STRATEGY configuration $PGM:K endmodule" + ) for (axiom <- axioms) { val rewrite = getRewrite(axiom) if (rewrite.isDefined) { val lhs = rewrite.get.getLeftHandSide - for (pat <- lhs) { + for (pat <- lhs) assertFalse(symbols(pat).contains(B.SymbolOrAlias("append", Seq()))) - } } } } diff --git a/kore/build.sbt b/kore/build.sbt index 3dff694b14d..2a39947d48c 100644 --- a/kore/build.sbt +++ b/kore/build.sbt @@ -3,9 +3,9 @@ net.virtualvoid.sbt.graph.Plugin.graphSettings libraryDependencies ++= Seq( - "org.scalacheck" %% "scalacheck" % "1.11.4" % "test", - "com.novocode" % "junit-interface" % "0.9" % "test", - "junit" % "junit" % "4.11" % "test" + "org.scalacheck" %% "scalacheck" % "1.11.4" % "test", + "com.novocode" % "junit-interface" % "0.9" % "test", + "junit" % "junit" % "4.11" % "test" ) EclipseKeys.withSource := true diff --git a/kore/project/build.sbt b/kore/project/build.sbt index a391092bfa8..7687d6a5252 100644 --- a/kore/project/build.sbt +++ b/kore/project/build.sbt @@ -1,6 +1,6 @@ // Copyright (c) 2014-2019 K Team. All Rights Reserved. -resolvers += "Sonatype snapshots" at "https://oss.sonatype.org/content/repositories/snapshots/" +resolvers += "Sonatype snapshots".at("https://oss.sonatype.org/content/repositories/snapshots/") addSbtPlugin("com.github.shivawu" %% "sbt-maven-plugin" % "0.1.3-SNAPSHOT") diff --git a/kore/src/main/scala/org/kframework/POSet.scala b/kore/src/main/scala/org/kframework/POSet.scala index 73467b0e117..a2c2e2f5d82 100644 --- a/kore/src/main/scala/org/kframework/POSet.scala +++ b/kore/src/main/scala/org/kframework/POSet.scala @@ -1,10 +1,9 @@ // Copyright (c) K Team. All Rights Reserved. package org.kframework -import org.kframework.utils.errorsystem.KEMException - -import java.util import collection._ +import java.util +import org.kframework.utils.errorsystem.KEMException import scala.annotation.tailrec /** @@ -12,27 +11,29 @@ import scala.annotation.tailrec */ class POSet[T](val directRelations: Set[(T, T)]) extends Serializable { // convert the input set of relations to Map form for performance - private val directRelationsMap: Map[T, Set[T]] = directRelations groupBy { _._1 } mapValues { _ map { _._2 } toSet } map identity + private val directRelationsMap: Map[T, Set[T]] = + directRelations.groupBy(_._1).mapValues(_.map(_._2) toSet).map(identity) lazy val elements: Set[T] = directRelations.flatMap(a => Set(a._1, a._2)) - lazy val sortedElements: scala.collection.immutable.List[T] = TopologicalSort.tsort(directRelations).toList + lazy val sortedElements: scala.collection.immutable.List[T] = + TopologicalSort.tsort(directRelations).toList /** - * Internal private method. Computes the transitive closer of the initial relations. - * It also checks for cycles during construction and throws an exception if it finds any. + * Internal private method. Computes the transitive closer of the initial relations. It also + * checks for cycles during construction and throws an exception if it finds any. * * The implementation is simple. It links each element to the successors of its successors. + * * TODO: there may be a more efficient algorithm (low priority) */ @tailrec private def transitiveClosure(relations: Map[T, Set[T]]): Map[T, Set[T]] = { - val newRelations = relations map { - case (start, succ) => - val newSucc = succ flatMap { relations.getOrElse(_, Set()) } - if (newSucc.contains(start)) - constructAndThrowCycleException(start, start, Seq()) - (start, succ | newSucc) + val newRelations = relations.map { case (start, succ) => + val newSucc = succ.flatMap(relations.getOrElse(_, Set())) + if (newSucc.contains(start)) + constructAndThrowCycleException(start, start, Seq()) + (start, succ | newSucc) } if (relations != newRelations) transitiveClosure(newRelations) else relations } @@ -40,17 +41,22 @@ class POSet[T](val directRelations: Set[(T, T)]) extends Serializable { /** * Recursive method constructing and throwing and the cycle exception. * - * @param start (or tail) element to look for when constructing the cycle - * @param current element - * @param path so far + * @param start + * (or tail) element to look for when constructing the cycle + * @param current + * element + * @param path + * so far */ private def constructAndThrowCycleException(start: T, current: T, path: Seq[T]): Unit = { val currentPath = path :+ current - val succs = directRelationsMap.getOrElse(current, Set()) + val succs = directRelationsMap.getOrElse(current, Set()) if (succs.contains(start)) { - throw KEMException.compilerError("Illegal circular relation: " + (currentPath :+ start).mkString(" < ")) + throw KEMException.compilerError( + "Illegal circular relation: " + (currentPath :+ start).mkString(" < ") + ) } - succs foreach { constructAndThrowCycleException(start, _, currentPath) } + succs.foreach(constructAndThrowCycleException(start, _, currentPath)) } /** @@ -64,7 +70,11 @@ class POSet[T](val directRelations: Set[(T, T)]) extends Serializable { * A map from each element of the poset to the set of elements less than it. */ lazy val relationsOp: Map[T, Set[T]] = - relations.toSet[(T, Set[T])].flatMap { case (x, ys) => ys.map(_ -> x) }.groupBy(_._1).mapValues(_.map(_._2)) + relations + .toSet[(T, Set[T])] + .flatMap { case (x, ys) => ys.map(_ -> x) } + .groupBy(_._1) + .mapValues(_.map(_._2)) def <(x: T, y: T): Boolean = relations.get(x).exists(_.contains(y)) def >(x: T, y: T): Boolean = relations.get(y).exists(_.contains(x)) @@ -73,19 +83,21 @@ class POSet[T](val directRelations: Set[(T, T)]) extends Serializable { /** * Returns true if x < y */ - def lessThan(x: T, y: T): Boolean = <(x, y) - def lessThanEq(x: T, y: T): Boolean = x == y || <(x, y) + def lessThan(x: T, y: T): Boolean = <(x, y) + def lessThanEq(x: T, y: T): Boolean = x == y || <(x, y) def directlyLessThan(x: T, y: T): Boolean = directRelationsMap.get(x).exists(_.contains(y)) + /** * Returns true if y < x */ - def greaterThan(x: T, y: T): Boolean = >(x, y) - def greaterThanEq(x: T, y: T): Boolean = x == y || >(x, y) + def greaterThan(x: T, y: T): Boolean = >(x, y) + def greaterThanEq(x: T, y: T): Boolean = x == y || >(x, y) def directlyGreaterThan(x: T, y: T): Boolean = directRelationsMap.get(y).exists(_.contains(x)) + /** * Returns true if y < x or y < x */ - def inSomeRelation(x: T, y: T): Boolean = this.~(x, y) + def inSomeRelation(x: T, y: T): Boolean = this.~(x, y) def inSomeRelationEq(x: T, y: T): Boolean = x == y || this.~(x, y) /** @@ -116,43 +128,43 @@ class POSet[T](val directRelations: Set[(T, T)]) extends Serializable { lazy val minimum: Option[T] = if (minimalElements.size == 1) Some(minimalElements.head) else None - lazy val asOrdering: Ordering[T] = (x: T, y: T) => if (lessThanEq(x, y)) -1 else if (lessThanEq(y, x)) 1 else 0 + lazy val asOrdering: Ordering[T] = (x: T, y: T) => + if (lessThanEq(x, y)) -1 else if (lessThanEq(y, x)) 1 else 0 /** - * Return the subset of items from the argument which are not - * less than any other item. - */ + * Return the subset of items from the argument which are not less than any other item. + */ def maximal(sorts: Iterable[T]): Set[T] = - sorts.filter(s1 => !sorts.exists(s2 => lessThan(s1,s2))).toSet + sorts.filter(s1 => !sorts.exists(s2 => lessThan(s1, s2))).toSet def maximal(sorts: util.Collection[T]): util.Set[T] = Collections.mutable(maximal(Collections.immutable(sorts))) /** - * Return the subset of items from the argument which are not - * greater than any other item. - */ + * Return the subset of items from the argument which are not greater than any other item. + */ def minimal(sorts: Iterable[T]): Set[T] = - sorts.filter(s1 => !sorts.exists(s2 => >(s1,s2))).toSet + sorts.filter(s1 => !sorts.exists(s2 => >(s1, s2))).toSet def minimal(sorts: util.Collection[T]): util.Set[T] = Collections.mutable(minimal(Collections.immutable(sorts))) - override def toString: String = { - "POSet(" + (relations flatMap { case (from, tos) => tos map { to => from + "<" + to } }).mkString(",") + ")" - } + override def toString: String = + "POSet(" + relations + .flatMap { case (from, tos) => tos.map(to => from + "<" + to) } + .mkString(",") + ")" override def hashCode: Int = relations.hashCode() override def equals(that: Any): Boolean = that match { case that: POSet[_] => relations == that.relations - case _ => false + case _ => false } } object POSet { def apply[T](relations: (T, T)*) = new POSet(relations.toSet) - def apply[T](s: Set[(T, T)]) = new POSet(s) + def apply[T](s: Set[(T, T)]) = new POSet(s) /** * Import this for Scala syntactic sugar. @@ -167,5 +179,5 @@ object POSet { * using the provided relations map. Input must be non-empty. */ private def upperBounds[T](sorts: Iterable[T], relations: Map[T, Set[T]]): Set[T] = - sorts map { s => relations.getOrElse(s, Set.empty) + s } reduce { (a, b) => a & b } + sorts.map(s => relations.getOrElse(s, Set.empty) + s).reduce((a, b) => a & b) } diff --git a/kore/src/main/scala/org/kframework/RewriterResult.scala b/kore/src/main/scala/org/kframework/RewriterResult.scala index bb5fb5c6176..50119bfef89 100644 --- a/kore/src/main/scala/org/kframework/RewriterResult.scala +++ b/kore/src/main/scala/org/kframework/RewriterResult.scala @@ -6,6 +6,8 @@ import java.util.Optional /** * Created by manasvi on 8/13/15. */ -class RewriterResult(val rewriteSteps: Optional[Integer], val exitCode: Optional[Integer], val k: kore.K) { - -} +class RewriterResult( + val rewriteSteps: Optional[Integer], + val exitCode: Optional[Integer], + val k: kore.K +) {} diff --git a/kore/src/main/scala/org/kframework/Strategy.scala b/kore/src/main/scala/org/kframework/Strategy.scala index 9d25de102dd..c3c349ac65b 100644 --- a/kore/src/main/scala/org/kframework/Strategy.scala +++ b/kore/src/main/scala/org/kframework/Strategy.scala @@ -6,52 +6,60 @@ import org.kframework.builtin.BooleanUtils import org.kframework.builtin.KLabels import org.kframework.builtin.Sorts import org.kframework.compile.RewriteToTop -import org.kframework.definition.{DefinitionTransformer, ModuleTransformer, Module, Rule, Definition} +import org.kframework.definition.Definition +import org.kframework.definition.DefinitionTransformer +import org.kframework.definition.Module +import org.kframework.definition.ModuleTransformer +import org.kframework.definition.Rule import org.kframework.kore.ExistsK import org.kframework.kore.KApply import org.kframework.kore.KORE import org.kframework.kore.Sort -import org.kframework.kore.Unapply.{KApply, KLabel} +import org.kframework.kore.Unapply.KApply +import org.kframework.kore.Unapply.KLabel object Strategy { - val strategyCellName = "" + val strategyCellName = "" val strategyCellLabel = KORE.KLabel(strategyCellName) - def addStrategyRuleToMainModule(mainModuleName: String) = { - DefinitionTransformer( - module => - if (module.name != mainModuleName || !module.importedModuleNames.contains("STRATEGY")) { - module - } else { - Module(module.name, module.imports, module.localSentences + Rule( - KORE.KApply(KLabels.STRATEGY_CELL, + def addStrategyRuleToMainModule(mainModuleName: String) = + DefinitionTransformer(module => + if (module.name != mainModuleName || !module.importedModuleNames.contains("STRATEGY")) { + module + } else { + Module( + module.name, + module.imports, + module.localSentences + Rule( + KORE.KApply( + KLabels.STRATEGY_CELL, KORE.KApply(KLabels.NO_DOTS), KORE.KRewrite( KORE.KVariable("S", Att.empty.add(classOf[Sort], Sorts.KItem)), KORE.KSequence( KORE.KApply(KORE.KLabel("#STUCK")), - KORE.KVariable("S", Att.empty.add(classOf[Sort], Sorts.KItem)), + KORE.KVariable("S", Att.empty.add(classOf[Sort], Sorts.KItem)) ) ), KORE.KApply(KLabels.DOTS) ), KORE.KApply( - KLabels.NOT_EQUALS_K, + KLabels.NOT_EQUALS_K, KORE.KVariable("S", Att.empty.add(classOf[Sort], Sorts.KItem)), - KORE.KApply(KORE.KLabel("#STUCK")), + KORE.KApply(KORE.KLabel("#STUCK")) ), BooleanUtils.TRUE, Att.empty.add(Att.OWISE) - ), module.att) - } + ), + module.att + ) + } ) - } } class ContainsSCell extends ExistsK { - override def apply(k: KApply): java.lang.Boolean = { + override def apply(k: KApply): java.lang.Boolean = k.klabel == KLabels.STRATEGY_CELL || super.apply(k) - } } class Strategy() { @@ -59,34 +67,51 @@ class Strategy() { def addStrategyCellToRulesTransformer(defn: Definition) = DefinitionTransformer( - ModuleTransformer.fromSentenceTransformer({ - (module, r) => + ModuleTransformer.fromSentenceTransformer( + { (module, r) => val rich = kore.Rich(module) - def isFunctionRhs(body: kore.K): Boolean = { + def isFunctionRhs(body: kore.K): Boolean = RewriteToTop.toRight(body) match { - case KApply(klabel, _) if module.attributesFor.contains(klabel) && module.attributesFor(klabel).contains(Att.FUNCTION) => true + case KApply(klabel, _) + if module.attributesFor + .contains(klabel) && module.attributesFor(klabel).contains(Att.FUNCTION) => + true case _ => false } - } import rich._ - - if (!defn.mainModule.importedModuleNames.contains("STRATEGY") || r.att.contains(Att.ANYWHERE) || r.att.contains(Att.MACRO) || r.att.contains(Att.ALIAS) || r.att.contains(Att.MACRO_REC) || r.att.contains(Att.ALIAS_REC)) { + + if ( + !defn.mainModule.importedModuleNames.contains("STRATEGY") || r.att + .contains(Att.ANYWHERE) || r.att.contains(Att.MACRO) || r.att + .contains(Att.ALIAS) || r.att.contains(Att.MACRO_REC) || r.att.contains(Att.ALIAS_REC) + ) { r } else r match { case r: Rule if !new ContainsSCell().apply(r.body) => val newBody = RewriteToTop.toLeft(r.body) match { - case KApply(klabel, _) if !isFunctionRhs(r.body) && (!module.attributesFor.contains(klabel) || !module.attributesFor(klabel).contains(Att.FUNCTION)) => + case KApply(klabel, _) + if !isFunctionRhs(r.body) && (!module.attributesFor.contains( + klabel + ) || !module.attributesFor(klabel).contains(Att.FUNCTION)) => // todo: "!module.attributesFor.contains(klabel) ||" when #1723 is fixed def makeRewrite(tag: String) = KORE.KSequence( KORE.KRewrite( - KORE.KApply(KORE.KLabel("#applyRule"), KORE.KToken(tag, KORE.Sort("#RuleTag"))), - KORE.KApply(KORE.KLabel("#appliedRule"), KORE.KToken(tag, KORE.Sort("#RuleTag")))), - KORE.KVariable("SREST")) + KORE.KApply( + KORE.KLabel("#applyRule"), + KORE.KToken(tag, KORE.Sort("#RuleTag")) + ), + KORE.KApply( + KORE.KLabel("#appliedRule"), + KORE.KToken(tag, KORE.Sort("#RuleTag")) + ) + ), + KORE.KVariable("SREST") + ) val strategy = if (r.att.contains(Att.TAG)) { @@ -95,17 +120,24 @@ class Strategy() { makeRewrite("regular") } - KORE.KApply(KLabels.CELLS, r.body, - KORE.KApply(KLabels.STRATEGY_CELL, + KORE.KApply( + KLabels.CELLS, + r.body, + KORE.KApply( + KLabels.STRATEGY_CELL, KORE.KApply(KLabels.NO_DOTS), strategy, KORE.KApply(KLabels.NO_DOTS) - )) + ) + ) case _ => r.body } Rule(newBody, r.requires, r.ensures, r.att) case r => r } - }, "add strategy cell to rules")) + }, + "add strategy cell to rules" + ) + ) } diff --git a/kore/src/main/scala/org/kframework/TopologicalSort.scala b/kore/src/main/scala/org/kframework/TopologicalSort.scala index 32b337f64f0..8d1254c0ccc 100644 --- a/kore/src/main/scala/org/kframework/TopologicalSort.scala +++ b/kore/src/main/scala/org/kframework/TopologicalSort.scala @@ -10,12 +10,12 @@ object TopologicalSort { def tsort[A](edges: Traversable[(A, A)]): Iterable[A] = { @tailrec def tsort(toPreds: Map[A, Set[A]], done: Iterable[A]): Iterable[A] = { - val (noPreds, hasPreds) = toPreds.partition { _._2.isEmpty } + val (noPreds, hasPreds) = toPreds.partition(_._2.isEmpty) if (noPreds.isEmpty) { if (hasPreds.isEmpty) done else sys.error(hasPreds.toString) } else { - val found = noPreds.map { _._1 } - tsort(hasPreds.mapValues { _ -- found }, done ++ found) + val found = noPreds.map(_._1) + tsort(hasPreds.mapValues(_ -- found), done ++ found) } } diff --git a/kore/src/main/scala/org/kframework/attributes/Att.scala b/kore/src/main/scala/org/kframework/attributes/Att.scala index d3c3685d33f..83854a24fc3 100644 --- a/kore/src/main/scala/org/kframework/attributes/Att.scala +++ b/kore/src/main/scala/org/kframework/attributes/Att.scala @@ -1,24 +1,22 @@ // Copyright (c) K Team. All Rights Reserved. package org.kframework.attributes -import java.util.Optional import java.util.regex.Pattern -import org.kframework.Collections._ +import java.util.Optional import org.kframework.definition._ import org.kframework.kore.Sort import org.kframework.utils.errorsystem.KEMException - +import org.kframework.Collections._ import scala.collection.Set -import scala.reflect.ClassTag import scala.reflect.classTag +import scala.reflect.ClassTag /** * Marker class for objects that can be stored as the value of an attribute. * - * So far this trait implements no methods, but in the future it may - * include some methods relating to serialization/deserialization that - * all inheritors must implement. It may depend on what serialization library - * we choose to use going forward. + * So far this trait implements no methods, but in the future it may include some methods relating + * to serialization/deserialization that all inheritors must implement. It may depend on what + * serialization library we choose to use going forward. */ trait AttValue @@ -26,28 +24,32 @@ trait AttValue * Conceptually, attributes are a mapping from String keys to values of any type. * * However, there are two caveats: - * - We store the type of the value in the key. That is, a key is a pair (s1, s2) where the corresponding value must - * have type class.forName(s2). - * - We use a wrapper Att.Key(String,KeyType) rather than a raw String key. This helps to enforce access controls and - * allows for easier IDE navigation to where each attribute is used. + * - We store the type of the value in the key. That is, a key is a pair (s1, s2) where the + * corresponding value must have type class.forName(s2). + * - We use a wrapper Att.Key(String,KeyType) rather than a raw String key. This helps to enforce + * access controls and allows for easier IDE navigation to where each attribute is used. * * New attributes should be added as a Key field Att.MY_NEW_ATT in the object below. * * To obtain an appropriate Key, use - * - Att.MY_ATT, if you statically know the key you want - * - Att.getBuiltInKeyOptional(myAttStr), if checking a user-supplied attribute string. Be sure to report an error - * if the lookup fails - * - Att.getInternalKeyOptional(myAttStr), if expecting an internal key - * - Att.getUserGroupOptional(myAttStr), if expecting a user-group, enforcing that it is not a built-in - * - * During parsing, you may also use Att.unrecognizedKey(myAttStr) to delay error reporting on an unrecognized attribute + * - Att.MY_ATT, if you statically know the key you want + * - Att.getBuiltInKeyOptional(myAttStr), if checking a user-supplied attribute string. Be sure to + * report an error if the lookup fails + * - Att.getInternalKeyOptional(myAttStr), if expecting an internal key + * - Att.getUserGroupOptional(myAttStr), if expecting a user-group, enforcing that it is not a + * built-in + * + * During parsing, you may also use Att.unrecognizedKey(myAttStr) to delay error reporting on an + * unrecognized attribute */ -class Att private (val att: Map[(Att.Key, String), Any]) extends AttributesToString with Serializable { +class Att private (val att: Map[(Att.Key, String), Any]) + extends AttributesToString + with Serializable { override lazy val hashCode: Int = att.hashCode() override def equals(that: Any): Boolean = that match { case a: Att => a.att == att - case _ => false + case _ => false } // Remove all UserGroups and replace them with a group(_) attribute @@ -78,8 +80,10 @@ class Att private (val att: Map[(Att.Key, String), Any]) extends AttributesToStr if (groupKey.isEmpty) return Left("User-defined group '" + group + "' conflicts with a built-in attribute.") if (!group.matches("[a-z][a-zA-Z0-9-]*")) - return Left("Invalid argument '" + group + "' in group(_) attribute. " + - "Expected a lower case letter followed by any number of alphanumeric or '-' characters.") + return Left( + "Invalid argument '" + group + "' in group(_) attribute. " + + "Expected a lower case letter followed by any number of alphanumeric or '-' characters." + ) att = att.add(groupKey.get) } Right(att.remove(Att.GROUP)) @@ -88,7 +92,7 @@ class Att private (val att: Map[(Att.Key, String), Any]) extends AttributesToStr att.map(_._1._1).filter(_.keyType.equals(Att.KeyType.Unrecognized)).toSet def getMacro: Option[Att.Key] = { - if (contains(Att.MACRO)){ + if (contains(Att.MACRO)) { return Some(Att.MACRO) } if (contains(Att.MACRO_REC)) { @@ -103,50 +107,59 @@ class Att private (val att: Map[(Att.Key, String), Any]) extends AttributesToStr None } - def contains(cls: Class[_]): Boolean = att.contains((Att.getInternalKeyOrAssert(cls.getName), cls.getName)) - def contains(key: Att.Key): Boolean = att.contains((key, Att.stringClassName)) + def contains(cls: Class[_]): Boolean = + att.contains((Att.getInternalKeyOrAssert(cls.getName), cls.getName)) + def contains(key: Att.Key): Boolean = att.contains((key, Att.stringClassName)) def contains(key: Att.Key, cls: Class[_]): Boolean = att.contains((key, cls.getName)) - def get[T](key: Class[T]): T = getOption(key).get - def get(key: Att.Key): String = getOption(key).get + def get[T](key: Class[T]): T = getOption(key).get + def get(key: Att.Key): String = getOption(key).get def get[T](key: Att.Key, cls: Class[T]): T = getOption(key, cls).get - def getOption(key: Att.Key): Option[String] = att.get((key, Att.stringClassName)).asInstanceOf[Option[String]] - def getOption[T](key: Class[T]): Option[T] = att.get((Att.getInternalKeyOrAssert(key.getName), key.getName)).asInstanceOf[Option[T]] - def getOption[T](key: Att.Key, cls: Class[T]): Option[T] = att.get((key, cls.getName)).asInstanceOf[Option[T]] + def getOption(key: Att.Key): Option[String] = + att.get((key, Att.stringClassName)).asInstanceOf[Option[String]] + def getOption[T](key: Class[T]): Option[T] = + att.get((Att.getInternalKeyOrAssert(key.getName), key.getName)).asInstanceOf[Option[T]] + def getOption[T](key: Att.Key, cls: Class[T]): Option[T] = + att.get((key, cls.getName)).asInstanceOf[Option[T]] def getOptional(key: Att.Key): Optional[String] = optionToOptional(getOption(key)) - def getOptional[T](key: Class[T]): Optional[T] = optionToOptional(getOption(key)) - def getOptional[T](key: Att.Key, cls: Class[T]): Optional[T] = optionToOptional(getOption(key, cls)) + def getOptional[T](key: Class[T]): Optional[T] = optionToOptional(getOption(key)) + def getOptional[T](key: Att.Key, cls: Class[T]): Optional[T] = optionToOptional( + getOption(key, cls) + ) private def optionToOptional[T](option: Option[T]): Optional[T] = - option match {case None => Optional.empty(); case Some(x) => Optional.of(x);} + option match { case None => Optional.empty(); case Some(x) => Optional.of(x); } - def add(key: Att.Key): Att = add(key, "") + def add(key: Att.Key): Att = add(key, "") def add(key: Att.Key, value: String): Att = add(key, Att.stringClassName, value) - def add(key: Att.Key, value: Int): Att = add(key, Att.intClassName, value) - def add[T <: AttValue](key: Class[T], value: T): Att = add(Att.getInternalKeyOrAssert(key.getName), key.getName, value) + def add(key: Att.Key, value: Int): Att = add(key, Att.intClassName, value) + def add[T <: AttValue](key: Class[T], value: T): Att = + add(Att.getInternalKeyOrAssert(key.getName), key.getName, value) def add[T <: AttValue](key: Att.Key, cls: Class[T], value: T): Att = add(key, cls.getName, value) private def add[T <: AttValue](key: Att.Key, clsStr: String, value: T): Att = key.keyParam match { case Att.KeyParameter.Forbidden => throwForbidden(key) - case _ => Att(att + ((key, clsStr) -> value)) + case _ => Att(att + ((key, clsStr) -> value)) } private def add(key: Att.Key, clsStr: String, value: String): Att = key.keyParam match { case Att.KeyParameter.Forbidden if value != "" => throwForbidden(key) - case Att.KeyParameter.Required if value == "" => throwRequired(key) - case _ => Att(att + ((key, clsStr) -> value)) + case Att.KeyParameter.Required if value == "" => throwRequired(key) + case _ => Att(att + ((key, clsStr) -> value)) } private def add(key: Att.Key, clsStr: String, value: Int): Att = key.keyParam match { case Att.KeyParameter.Forbidden => throwForbidden(key) - case _ => Att(att + ((key, clsStr) -> value)) + case _ => Att(att + ((key, clsStr) -> value)) } - private def throwRequired(key: Att.Key) = throw KEMException.compilerError("Parameters for the attribute '" + key + "' are required.") - private def throwForbidden(key: Att.Key) = throw KEMException.compilerError("Parameters for the attribute '" + key + "' are forbidden.") + private def throwRequired(key: Att.Key) = + throw KEMException.compilerError("Parameters for the attribute '" + key + "' are required.") + private def throwForbidden(key: Att.Key) = + throw KEMException.compilerError("Parameters for the attribute '" + key + "' are forbidden.") - def addAll(thatAtt: Att): Att = Att(att ++ thatAtt.att) - def remove(key: Att.Key): Att = remove(key, Att.stringClassName) + def addAll(thatAtt: Att): Att = Att(att ++ thatAtt.att) + def remove(key: Att.Key): Att = remove(key, Att.stringClassName) def remove(key: Class[_]): Att = remove(Att.getInternalKeyOrAssert(key.getName), key.getName) - def remove(key: Att.Key, cls: Class[_]): Att = remove(key, cls.getName) + def remove(key: Att.Key, cls: Class[_]): Att = remove(key, cls.getName) private def remove(key: Att.Key, clsStr: String): Att = Att(att - ((key, clsStr))) } @@ -161,11 +174,13 @@ object Att { // Attributes which represent user-defined groups via group(_). // // WARNING: Although we treat the arguments to group(_) as individual attributes internally, - // for any external interface (emitting KORE, JSON, etc.), we must re-emit them under the group(_) attribute, + // for any external interface (emitting KORE, JSON, etc.), we must re-emit them under the + // group(_) attribute, // else there will be conflicts when a user group has the same name as an internal attribute. case object UserGroup extends KeyType; // Attributes from user source code which are not recognized as built-ins - // This is only used to delay error reporting until after parsing, allowing us to report multiple errors + // This is only used to delay error reporting until after parsing, allowing us to report + // multiple errors case object Unrecognized extends KeyType; } @@ -182,17 +197,33 @@ object Att { /* The Key class can only be constructed within Att. To enforce this, we must * - Make the constructor private * - Manually declare apply() and make it private, lest a public one is generated - * - Manually declare copy() and make it private, preventing constructions like Att.GOOD_KEY.copy(key="bad-att") - */ - case class Key private[Att](key: String, keyType: KeyType, keyParam: KeyParameter, allowedSentences: Set[Class[_]]) extends Serializable { + * - Manually declare copy() and make it private, preventing constructions like + * Att.GOOD_KEY.copy(key="bad-att") */ + case class Key private[Att] ( + key: String, + keyType: KeyType, + keyParam: KeyParameter, + allowedSentences: Set[Class[_]] + ) extends Serializable { override def toString: String = key private[Key] def copy(): Unit = () } object Key { - private[Att] def apply(key: String, keyType: KeyType): Key = Key(key, keyType, KeyParameter.Optional) - private[Att] def apply(key: String, keyType: KeyType, keyParam: KeyParameter): Key = Key(key, keyType, keyParam, onlyon[AnyRef]) - private[Att] def apply(key: String, keyType: KeyType, keyParam: KeyParameter, allowedSentences: Set[Class[_]]): Key = new Key(key, keyType, keyParam, allowedSentences) - private[Att] def builtin(key: String, keyParam: KeyParameter, allowedSentences: Set[Class[_]]): Key = Key(key, KeyType.BuiltIn, keyParam, allowedSentences) + private[Att] def apply(key: String, keyType: KeyType): Key = + Key(key, keyType, KeyParameter.Optional) + private[Att] def apply(key: String, keyType: KeyType, keyParam: KeyParameter): Key = + Key(key, keyType, keyParam, onlyon[AnyRef]) + private[Att] def apply( + key: String, + keyType: KeyType, + keyParam: KeyParameter, + allowedSentences: Set[Class[_]] + ): Key = new Key(key, keyType, keyParam, allowedSentences) + private[Att] def builtin( + key: String, + keyParam: KeyParameter, + allowedSentences: Set[Class[_]] + ): Key = Key(key, KeyType.BuiltIn, keyParam, allowedSentences) } def unrecognizedKey(key: String): Att.Key = @@ -202,165 +233,176 @@ object Att { // Some helpers with scala reflection to make declaring class object sets more compact // If these break for some reason, replace their usage with Set(classOf[T1], classOf[T2], ...) - private def onlyon[T: ClassTag](): Set[Class[_]] = Set(classTag[T].runtimeClass) + private def onlyon[T: ClassTag](): Set[Class[_]] = Set(classTag[T].runtimeClass) private def onlyon2[T1: ClassTag, T2: ClassTag](): Set[Class[_]] = onlyon[T1] ++ onlyon[T2] - private def onlyon3[T1: ClassTag, T2: ClassTag, T3: ClassTag](): Set[Class[_]] = onlyon2[T1, T2] ++ onlyon[T3] - private def onlyon4[T1: ClassTag, T2: ClassTag, T3: ClassTag, T4:ClassTag](): Set[Class[_]] = onlyon3[T1, T2, T3] ++ onlyon[T4] + private def onlyon3[T1: ClassTag, T2: ClassTag, T3: ClassTag](): Set[Class[_]] = + onlyon2[T1, T2] ++ onlyon[T3] + private def onlyon4[T1: ClassTag, T2: ClassTag, T3: ClassTag, T4: ClassTag](): Set[Class[_]] = + onlyon3[T1, T2, T3] ++ onlyon[T4] - /* - * Built-in attribute keys which can appear in user source code - */ - final val ALIAS = Key.builtin("alias", KeyParameter.Forbidden, onlyon2[Production, Rule]) + /* Built-in attribute keys which can appear in user source code */ + final val ALIAS = Key.builtin("alias", KeyParameter.Forbidden, onlyon2[Production, Rule]) final val ALIAS_REC = Key.builtin("alias-rec", KeyParameter.Forbidden, onlyon2[Production, Rule]) - final val ALL_PATH = Key.builtin("all-path", KeyParameter.Forbidden, onlyon[Claim]) - final val ANYWHERE = Key.builtin("anywhere", KeyParameter.Forbidden, onlyon[Rule]) + final val ALL_PATH = Key.builtin("all-path", KeyParameter.Forbidden, onlyon[Claim]) + final val ANYWHERE = Key.builtin("anywhere", KeyParameter.Forbidden, onlyon[Rule]) final val APPLY_PRIORITY = Key.builtin("applyPriority", KeyParameter.Required, onlyon[Production]) - final val ASSOC = Key.builtin("assoc", KeyParameter.Forbidden, onlyon[Production]) - final val AVOID = Key.builtin("avoid", KeyParameter.Forbidden, onlyon[Production]) - final val BAG = Key.builtin("bag", KeyParameter.Forbidden, onlyon[Production]) - final val BINDER = Key.builtin("binder", KeyParameter.Optional, onlyon[Production]) - final val BRACKET = Key.builtin("bracket", KeyParameter.Forbidden, onlyon[Production]) - final val CELL = Key.builtin("cell", KeyParameter.Forbidden, onlyon[Production]) - final val CELL_COLLECTION = Key.builtin("cellCollection", KeyParameter.Forbidden, onlyon2[Production, SyntaxSort]) - final val CELL_NAME = Key.builtin("cellName", KeyParameter.Required, onlyon[Production]) + final val ASSOC = Key.builtin("assoc", KeyParameter.Forbidden, onlyon[Production]) + final val AVOID = Key.builtin("avoid", KeyParameter.Forbidden, onlyon[Production]) + final val BAG = Key.builtin("bag", KeyParameter.Forbidden, onlyon[Production]) + final val BINDER = Key.builtin("binder", KeyParameter.Optional, onlyon[Production]) + final val BRACKET = Key.builtin("bracket", KeyParameter.Forbidden, onlyon[Production]) + final val CELL = Key.builtin("cell", KeyParameter.Forbidden, onlyon[Production]) + final val CELL_COLLECTION = + Key.builtin("cellCollection", KeyParameter.Forbidden, onlyon2[Production, SyntaxSort]) + final val CELL_NAME = Key.builtin("cellName", KeyParameter.Required, onlyon[Production]) final val CIRCULARITY = Key.builtin("circularity", KeyParameter.Forbidden, onlyon[Claim]) - final val COLOR = Key.builtin("color", KeyParameter.Required, onlyon[Production]) - final val COLORS = Key.builtin("colors", KeyParameter.Required, onlyon[Production]) - final val COMM = Key.builtin("comm", KeyParameter.Forbidden, onlyon2[Production, Rule]) - final val CONCRETE = Key.builtin("concrete", KeyParameter.Optional, onlyon3[Module, Production, Rule]) + final val COLOR = Key.builtin("color", KeyParameter.Required, onlyon[Production]) + final val COLORS = Key.builtin("colors", KeyParameter.Required, onlyon[Production]) + final val COMM = Key.builtin("comm", KeyParameter.Forbidden, onlyon2[Production, Rule]) + final val CONCRETE = + Key.builtin("concrete", KeyParameter.Optional, onlyon3[Module, Production, Rule]) final val CONSTRUCTOR = Key.builtin("constructor", KeyParameter.Forbidden, onlyon[Production]) - final val CONTEXT = Key.builtin("context", KeyParameter.Required, onlyon[ContextAlias]) - final val COOL = Key.builtin("cool", KeyParameter.Forbidden, onlyon[Rule]) - final val DEPENDS = Key.builtin("depends", KeyParameter.Required, onlyon[Claim]) - final val ELEMENT = Key.builtin("element", KeyParameter.Required, onlyon[Production]) - final val EXIT = Key.builtin("exit", KeyParameter.Forbidden, onlyon[Production]) - final val FORMAT = Key.builtin("format", KeyParameter.Required, onlyon[Production]) - final val FRESH_GENERATOR = Key.builtin("freshGenerator", KeyParameter.Forbidden, onlyon[Production]) - final val FUNCTION = Key.builtin("function", KeyParameter.Forbidden, onlyon[Production]) + final val CONTEXT = Key.builtin("context", KeyParameter.Required, onlyon[ContextAlias]) + final val COOL = Key.builtin("cool", KeyParameter.Forbidden, onlyon[Rule]) + final val DEPENDS = Key.builtin("depends", KeyParameter.Required, onlyon[Claim]) + final val ELEMENT = Key.builtin("element", KeyParameter.Required, onlyon[Production]) + final val EXIT = Key.builtin("exit", KeyParameter.Forbidden, onlyon[Production]) + final val FORMAT = Key.builtin("format", KeyParameter.Required, onlyon[Production]) + final val FRESH_GENERATOR = + Key.builtin("freshGenerator", KeyParameter.Forbidden, onlyon[Production]) + final val FUNCTION = Key.builtin("function", KeyParameter.Forbidden, onlyon[Production]) final val FUNCTIONAL = Key.builtin("functional", KeyParameter.Forbidden, onlyon[Production]) - final val GROUP = Key.builtin("group", KeyParameter.Required, onlyon[Sentence]) - final val HASKELL = Key.builtin("haskell", KeyParameter.Forbidden, onlyon[Module]) - final val HEAT = Key.builtin("heat", KeyParameter.Forbidden, onlyon[Rule]) - final val HOOK = Key.builtin("hook", KeyParameter.Required, onlyon2[Production, SyntaxSort]) - final val HYBRID = Key.builtin("hybrid", KeyParameter.Optional, onlyon[Production]) - final val IDEM = Key.builtin("idem", KeyParameter.Forbidden, onlyon[Production]) - final val IMPURE = Key.builtin("impure", KeyParameter.Forbidden, onlyon[Production]) - final val INDEX = Key.builtin("index", KeyParameter.Required, onlyon[Production]) - final val INITIAL = Key.builtin("initial", KeyParameter.Forbidden, onlyon[Production]) - final val INITIALIZER = Key.builtin("initializer", KeyParameter.Forbidden, onlyon2[Production, Rule]) + final val GROUP = Key.builtin("group", KeyParameter.Required, onlyon[Sentence]) + final val HASKELL = Key.builtin("haskell", KeyParameter.Forbidden, onlyon[Module]) + final val HEAT = Key.builtin("heat", KeyParameter.Forbidden, onlyon[Rule]) + final val HOOK = Key.builtin("hook", KeyParameter.Required, onlyon2[Production, SyntaxSort]) + final val HYBRID = Key.builtin("hybrid", KeyParameter.Optional, onlyon[Production]) + final val IDEM = Key.builtin("idem", KeyParameter.Forbidden, onlyon[Production]) + final val IMPURE = Key.builtin("impure", KeyParameter.Forbidden, onlyon[Production]) + final val INDEX = Key.builtin("index", KeyParameter.Required, onlyon[Production]) + final val INITIAL = Key.builtin("initial", KeyParameter.Forbidden, onlyon[Production]) + final val INITIALIZER = + Key.builtin("initializer", KeyParameter.Forbidden, onlyon2[Production, Rule]) final val INJECTIVE = Key.builtin("injective", KeyParameter.Forbidden, onlyon[Production]) - final val INTERNAL = Key.builtin("internal", KeyParameter.Forbidden, onlyon[Production]) - final val KAST = Key.builtin("kast", KeyParameter.Forbidden, onlyon[Module]) - final val KLABEL = Key.builtin("klabel", KeyParameter.Required, onlyon[Production]) - final val KORE = Key.builtin("kore", KeyParameter.Forbidden, onlyon2[RuleOrClaim, Module]) - final val LABEL = Key.builtin("label", KeyParameter.Required, onlyon[Sentence]) - final val LATEX = Key.builtin("latex", KeyParameter.Required, onlyon[Production]) - final val LEFT = Key.builtin("left", KeyParameter.Forbidden, onlyon[Production]) + final val INTERNAL = Key.builtin("internal", KeyParameter.Forbidden, onlyon[Production]) + final val KAST = Key.builtin("kast", KeyParameter.Forbidden, onlyon[Module]) + final val KLABEL = Key.builtin("klabel", KeyParameter.Required, onlyon[Production]) + final val KORE = Key.builtin("kore", KeyParameter.Forbidden, onlyon2[RuleOrClaim, Module]) + final val LABEL = Key.builtin("label", KeyParameter.Required, onlyon[Sentence]) + final val LATEX = Key.builtin("latex", KeyParameter.Required, onlyon[Production]) + final val LEFT = Key.builtin("left", KeyParameter.Forbidden, onlyon[Production]) final val LOCATIONS = Key.builtin("locations", KeyParameter.Forbidden, onlyon[SyntaxSort]) - final val MACRO = Key.builtin("macro", KeyParameter.Forbidden, onlyon2[Production, Rule]) + final val MACRO = Key.builtin("macro", KeyParameter.Forbidden, onlyon2[Production, Rule]) final val MACRO_REC = Key.builtin("macro-rec", KeyParameter.Forbidden, onlyon2[Production, Rule]) - final val MAINCELL = Key.builtin("maincell", KeyParameter.Forbidden, onlyon[Production]) - final val MEMO = Key.builtin("memo", KeyParameter.Forbidden, onlyon[Production]) + final val MAINCELL = Key.builtin("maincell", KeyParameter.Forbidden, onlyon[Production]) + final val MEMO = Key.builtin("memo", KeyParameter.Forbidden, onlyon[Production]) final val ML_BINDER = Key.builtin("mlBinder", KeyParameter.Forbidden, onlyon[Production]) - final val ML_OP = Key.builtin("mlOp", KeyParameter.Forbidden, onlyon[Production]) - final val MULTIPLICITY = Key.builtin("multiplicity", KeyParameter.Required, onlyon[Production]) - final val NON_ASSOC = Key.builtin("non-assoc", KeyParameter.Forbidden, onlyon[Production]) + final val ML_OP = Key.builtin("mlOp", KeyParameter.Forbidden, onlyon[Production]) + final val MULTIPLICITY = Key.builtin("multiplicity", KeyParameter.Required, onlyon[Production]) + final val NON_ASSOC = Key.builtin("non-assoc", KeyParameter.Forbidden, onlyon[Production]) final val NON_EXECUTABLE = Key.builtin("non-executable", KeyParameter.Forbidden, onlyon[Rule]) - final val NOT_LR1 = Key.builtin("not-lr1", KeyParameter.Forbidden, onlyon[Module]) + final val NOT_LR1 = Key.builtin("not-lr1", KeyParameter.Forbidden, onlyon[Module]) final val NO_EVALUATORS = Key.builtin("no-evaluators", KeyParameter.Forbidden, onlyon[Production]) - final val ONE_PATH = Key.builtin("one-path", KeyParameter.Forbidden, onlyon[Claim]) - final val OWISE = Key.builtin("owise", KeyParameter.Forbidden, onlyon[Rule]) - final val PARSER = Key.builtin("parser", KeyParameter.Required, onlyon[Production]) - final val PREC = Key.builtin("prec", KeyParameter.Required, onlyon[Production]) - final val PREFER = Key.builtin("prefer", KeyParameter.Forbidden, onlyon[Production]) - final val PRESERVES_DEFINEDNESS = Key.builtin("preserves-definedness", KeyParameter.Forbidden, onlyon[Rule]) - final val PRIORITY = Key.builtin("priority", KeyParameter.Required, onlyon4[Context, ContextAlias, Production, Rule]) + final val ONE_PATH = Key.builtin("one-path", KeyParameter.Forbidden, onlyon[Claim]) + final val OWISE = Key.builtin("owise", KeyParameter.Forbidden, onlyon[Rule]) + final val PARSER = Key.builtin("parser", KeyParameter.Required, onlyon[Production]) + final val PREC = Key.builtin("prec", KeyParameter.Required, onlyon[Production]) + final val PREFER = Key.builtin("prefer", KeyParameter.Forbidden, onlyon[Production]) + final val PRESERVES_DEFINEDNESS = + Key.builtin("preserves-definedness", KeyParameter.Forbidden, onlyon[Rule]) + final val PRIORITY = + Key.builtin("priority", KeyParameter.Required, onlyon4[Context, ContextAlias, Production, Rule]) final val PRIVATE = Key.builtin("private", KeyParameter.Forbidden, onlyon2[Module, Production]) - final val PUBLIC = Key.builtin("public", KeyParameter.Forbidden, onlyon2[Module, Production]) - final val RESULT = Key.builtin("result", KeyParameter.Required, onlyon4[Context, ContextAlias, Production, Rule]) - final val RETURNS_UNIT = Key.builtin("returnsUnit", KeyParameter.Forbidden, onlyon[Production]) - final val RIGHT = Key.builtin("right", KeyParameter.Forbidden, onlyon[Production]) - final val SEQSTRICT = Key.builtin("seqstrict", KeyParameter.Optional, onlyon[Production]) + final val PUBLIC = Key.builtin("public", KeyParameter.Forbidden, onlyon2[Module, Production]) + final val RESULT = + Key.builtin("result", KeyParameter.Required, onlyon4[Context, ContextAlias, Production, Rule]) + final val RETURNS_UNIT = Key.builtin("returnsUnit", KeyParameter.Forbidden, onlyon[Production]) + final val RIGHT = Key.builtin("right", KeyParameter.Forbidden, onlyon[Production]) + final val SEQSTRICT = Key.builtin("seqstrict", KeyParameter.Optional, onlyon[Production]) final val SIMPLIFICATION = Key.builtin("simplification", KeyParameter.Optional, onlyon[Rule]) - final val SMTLIB = Key.builtin("smtlib", KeyParameter.Required, onlyon[Production]) - final val SMT_HOOK = Key.builtin("smt-hook", KeyParameter.Required, onlyon[Production]) - final val SMT_LEMMA = Key.builtin("smt-lemma", KeyParameter.Forbidden, onlyon[Rule]) - final val STREAM = Key.builtin("stream", KeyParameter.Optional, onlyon2[Production, Rule]) - final val STRICT = Key.builtin("strict", KeyParameter.Optional, onlyon[Production]) - final val SYMBOL = Key.builtin("symbol", KeyParameter.Forbidden, onlyon[Production]) - final val SYMBOLIC = Key.builtin("symbolic", KeyParameter.Optional, onlyon3[Module, Production, Rule]) - final val TAG = Key.builtin("tag", KeyParameter.Required, onlyon[Rule]) - final val TOKEN = Key.builtin("token", KeyParameter.Forbidden, onlyon2[SyntaxSort, Production]) - final val TOTAL = Key.builtin("total", KeyParameter.Forbidden, onlyon[Production]) + final val SMTLIB = Key.builtin("smtlib", KeyParameter.Required, onlyon[Production]) + final val SMT_HOOK = Key.builtin("smt-hook", KeyParameter.Required, onlyon[Production]) + final val SMT_LEMMA = Key.builtin("smt-lemma", KeyParameter.Forbidden, onlyon[Rule]) + final val STREAM = Key.builtin("stream", KeyParameter.Optional, onlyon2[Production, Rule]) + final val STRICT = Key.builtin("strict", KeyParameter.Optional, onlyon[Production]) + final val SYMBOL = Key.builtin("symbol", KeyParameter.Forbidden, onlyon[Production]) + final val SYMBOLIC = + Key.builtin("symbolic", KeyParameter.Optional, onlyon3[Module, Production, Rule]) + final val TAG = Key.builtin("tag", KeyParameter.Required, onlyon[Rule]) + final val TOKEN = Key.builtin("token", KeyParameter.Forbidden, onlyon2[SyntaxSort, Production]) + final val TOTAL = Key.builtin("total", KeyParameter.Forbidden, onlyon[Production]) final val TRUSTED = Key.builtin("trusted", KeyParameter.Forbidden, onlyon[Claim]) - final val TYPE = Key.builtin("type", KeyParameter.Required, onlyon[Production]) - final val UNBOUND_VARIABLES = Key.builtin("unboundVariables", KeyParameter.Required, onlyon4[Context, ContextAlias, Production, RuleOrClaim]) - final val UNIT = Key.builtin("unit", KeyParameter.Required, onlyon[Production]) + final val TYPE = Key.builtin("type", KeyParameter.Required, onlyon[Production]) + final val UNBOUND_VARIABLES = Key.builtin( + "unboundVariables", + KeyParameter.Required, + onlyon4[Context, ContextAlias, Production, RuleOrClaim] + ) + final val UNIT = Key.builtin("unit", KeyParameter.Required, onlyon[Production]) final val UNPARSE_AVOID = Key.builtin("unparseAvoid", KeyParameter.Forbidden, onlyon[Production]) - final val UNUSED = Key.builtin("unused", KeyParameter.Forbidden, onlyon[Production]) - final val WRAP_ELEMENT = Key.builtin("wrapElement", KeyParameter.Required, onlyon[Production]) - - /* - * Internal attribute keys which cannot appear in user source code - */ - final val ANONYMOUS = Key("anonymous", KeyType.Internal) - final val BRACKET_LABEL = Key("bracketLabel", KeyType.Internal) - final val CELL_FRAGMENT = Key("cellFragment", KeyType.Internal) - final val CELL_OPT_ABSENT = Key("cellOptAbsent", KeyType.Internal) - final val CELL_SORT = Key("cellSort", KeyType.Internal) - final val CONCAT = Key("concat", KeyType.Internal) - final val CONTENT_START_COLUMN = Key("contentStartColumn", KeyType.Internal) - final val CONTENT_START_LINE = Key("contentStartLine", KeyType.Internal) - final val COOL_LIKE = Key("cool-like", KeyType.Internal) - final val DENORMAL = Key("denormal", KeyType.Internal) - final val DIGEST = Key("digest", KeyType.Internal) - final val DUMMY_CELL = Key("dummy_cell", KeyType.Internal) - final val FILTER_ELEMENT = Key("filterElement", KeyType.Internal) - final val FRESH = Key("fresh", KeyType.Internal) + final val UNUSED = Key.builtin("unused", KeyParameter.Forbidden, onlyon[Production]) + final val WRAP_ELEMENT = Key.builtin("wrapElement", KeyParameter.Required, onlyon[Production]) + + /* Internal attribute keys which cannot appear in user source code */ + final val ANONYMOUS = Key("anonymous", KeyType.Internal) + final val BRACKET_LABEL = Key("bracketLabel", KeyType.Internal) + final val CELL_FRAGMENT = Key("cellFragment", KeyType.Internal) + final val CELL_OPT_ABSENT = Key("cellOptAbsent", KeyType.Internal) + final val CELL_SORT = Key("cellSort", KeyType.Internal) + final val CONCAT = Key("concat", KeyType.Internal) + final val CONTENT_START_COLUMN = Key("contentStartColumn", KeyType.Internal) + final val CONTENT_START_LINE = Key("contentStartLine", KeyType.Internal) + final val COOL_LIKE = Key("cool-like", KeyType.Internal) + final val DENORMAL = Key("denormal", KeyType.Internal) + final val DIGEST = Key("digest", KeyType.Internal) + final val DUMMY_CELL = Key("dummy_cell", KeyType.Internal) + final val FILTER_ELEMENT = Key("filterElement", KeyType.Internal) + final val FRESH = Key("fresh", KeyType.Internal) final val GENERATED_BY_LIST_SUBSORTING = Key("generatedByListSubsorting", KeyType.Internal) - final val HAS_DOMAIN_VALUES = Key("hasDomainValues", KeyType.Internal) - final val LEFT_INTERNAL = Key("left", KeyType.Internal) - final val LOCATION = Key(classOf[Location].getName, KeyType.Internal) - final val NAT = Key("nat", KeyType.Internal) - final val NOT_INJECTION = Key("notInjection", KeyType.Internal) - final val NOT_LR1_MODULES = Key("not-lr1-modules", KeyType.Internal) - final val ORIGINAL_NAME = Key("originalName", KeyType.Internal) - final val ORIGINAL_PRD = Key("originalPrd", KeyType.Internal) - final val PATTERN = Key("pattern", KeyType.Internal) - final val PATTERN_FOLDING = Key("pattern-folding", KeyType.Internal) - final val PREDICATE = Key("predicate", KeyType.Internal) - final val PRETTY_PRINT_WITH_SORT_ANNOTATION = Key("prettyPrintWithSortAnnotation", KeyType.Internal) - final val PRIORITIES = Key("priorities", KeyType.Internal) - final val PRODUCTION = Key(classOf[Production].getName, KeyType.Internal) - final val PRODUCTION_ID = Key("productionId", KeyType.Internal) - final val PROJECTION = Key("projection", KeyType.Internal) - final val RECORD_PRD = Key("recordPrd", KeyType.Internal) - final val RECORD_PRD_ZERO = Key("recordPrd-zero", KeyType.Internal) - final val RECORD_PRD_ONE = Key("recordPrd-one", KeyType.Internal) - final val RECORD_PRD_MAIN = Key("recordPrd-main", KeyType.Internal) - final val RECORD_PRD_EMPTY = Key("recordPrd-empty", KeyType.Internal) - final val RECORD_PRD_SUBSORT = Key("recordPrd-subsort", KeyType.Internal) - final val RECORD_PRD_REPEAT = Key("recordPrd-repeat", KeyType.Internal) - final val RECORD_PRD_ITEM = Key("recordPrd-item", KeyType.Internal) - final val REFRESHED = Key("refreshed", KeyType.Internal) - final val REGEX = Key("regex", KeyType.Internal) - final val REJECT = Key("reject", KeyType.Internal) - final val REMOVE = Key("remove", KeyType.Internal) - final val RIGHT_INTERNAL = Key("right", KeyType.Internal) - final val SMT_PRELUDE = Key("smt-prelude", KeyType.Internal) - final val SORT = Key(classOf[Sort].getName, KeyType.Internal) - final val SORT_PARAMS = Key("sortParams", KeyType.Internal) - final val SOURCE = Key(classOf[Source].getName, KeyType.Internal) - final val SYNTAX_MODULE = Key("syntaxModule", KeyType.Internal) + final val HAS_DOMAIN_VALUES = Key("hasDomainValues", KeyType.Internal) + final val LEFT_INTERNAL = Key("left", KeyType.Internal) + final val LOCATION = Key(classOf[Location].getName, KeyType.Internal) + final val NAT = Key("nat", KeyType.Internal) + final val NOT_INJECTION = Key("notInjection", KeyType.Internal) + final val NOT_LR1_MODULES = Key("not-lr1-modules", KeyType.Internal) + final val ORIGINAL_NAME = Key("originalName", KeyType.Internal) + final val ORIGINAL_PRD = Key("originalPrd", KeyType.Internal) + final val PATTERN = Key("pattern", KeyType.Internal) + final val PATTERN_FOLDING = Key("pattern-folding", KeyType.Internal) + final val PREDICATE = Key("predicate", KeyType.Internal) + final val PRETTY_PRINT_WITH_SORT_ANNOTATION = + Key("prettyPrintWithSortAnnotation", KeyType.Internal) + final val PRIORITIES = Key("priorities", KeyType.Internal) + final val PRODUCTION = Key(classOf[Production].getName, KeyType.Internal) + final val PRODUCTION_ID = Key("productionId", KeyType.Internal) + final val PROJECTION = Key("projection", KeyType.Internal) + final val RECORD_PRD = Key("recordPrd", KeyType.Internal) + final val RECORD_PRD_ZERO = Key("recordPrd-zero", KeyType.Internal) + final val RECORD_PRD_ONE = Key("recordPrd-one", KeyType.Internal) + final val RECORD_PRD_MAIN = Key("recordPrd-main", KeyType.Internal) + final val RECORD_PRD_EMPTY = Key("recordPrd-empty", KeyType.Internal) + final val RECORD_PRD_SUBSORT = Key("recordPrd-subsort", KeyType.Internal) + final val RECORD_PRD_REPEAT = Key("recordPrd-repeat", KeyType.Internal) + final val RECORD_PRD_ITEM = Key("recordPrd-item", KeyType.Internal) + final val REFRESHED = Key("refreshed", KeyType.Internal) + final val REGEX = Key("regex", KeyType.Internal) + final val REJECT = Key("reject", KeyType.Internal) + final val REMOVE = Key("remove", KeyType.Internal) + final val RIGHT_INTERNAL = Key("right", KeyType.Internal) + final val SMT_PRELUDE = Key("smt-prelude", KeyType.Internal) + final val SORT = Key(classOf[Sort].getName, KeyType.Internal) + final val SORT_PARAMS = Key("sortParams", KeyType.Internal) + final val SOURCE = Key(classOf[Source].getName, KeyType.Internal) + final val SYNTAX_MODULE = Key("syntaxModule", KeyType.Internal) final val TEMPORARY_CELL_SORT_DECL = Key("temporary-cell-sort-decl", KeyType.Internal) - final val TERMINALS = Key("terminals", KeyType.Internal) - final val UNIQUE_ID = Key("UNIQUE_ID", KeyType.Internal) - final val USER_LIST = Key("userList", KeyType.Internal) - final val USER_LIST_TERMINATOR = Key("userListTerminator", KeyType.Internal) - final val WITH_CONFIG = Key("withConfig", KeyType.Internal) + final val TERMINALS = Key("terminals", KeyType.Internal) + final val UNIQUE_ID = Key("UNIQUE_ID", KeyType.Internal) + final val USER_LIST = Key("userList", KeyType.Internal) + final val USER_LIST_TERMINATOR = Key("userListTerminator", KeyType.Internal) + final val WITH_CONFIG = Key("withConfig", KeyType.Internal) private val stringClassName = classOf[String].getName - private val intClassName = classOf[java.lang.Integer].getName + private val intClassName = classOf[java.lang.Integer].getName // All Key fields with UPPER_CASE naming private val pat = Pattern.compile("[A-Z]+(_[A-Z0-9]+)*") @@ -370,7 +412,7 @@ object Att { .map(_.get(this).asInstanceOf[Key]) .groupBy(_.keyType) - private val builtinKeys: Map[String, Key] = keys(KeyType.BuiltIn).map(k => (k.key, k)).toMap + private val builtinKeys: Map[String, Key] = keys(KeyType.BuiltIn).map(k => (k.key, k)).toMap private val internalKeys: Map[String, Key] = keys(KeyType.Internal).map(k => (k.key, k)).toMap def getBuiltinKeyOptional(key: String): Optional[Key] = @@ -387,7 +429,7 @@ object Att { Optional.empty() } - def getUserGroupOptional(group: String) : Optional[Key] = + def getUserGroupOptional(group: String): Optional[Key] = if (!builtinKeys.contains(group)) { Optional.of(Key(group, KeyType.UserGroup, KeyParameter.Optional)) } else { @@ -395,52 +437,54 @@ object Att { } private def getInternalKeyOrAssert(key: String): Key = - getInternalKeyOptional(key).orElseThrow(() => - new AssertionError( - "Key '" + key + "' was not found among the internal attributes whitelist.\n" + - "To add a new internal attribute, create a field `final val MY_ATT = Key(\"my-att\", KeyType.Internal)` " + - "in the Att object.")) - + getInternalKeyOptional(key).orElseThrow(() => + new AssertionError( + "Key '" + key + "' was not found among the internal attributes whitelist.\n" + + "To add a new internal attribute, create a field `final val MY_ATT = Key(\"my-att\", KeyType.Internal)` " + + "in the Att object." + ) + ) def from(thatAtt: java.util.Map[Key, String]): Att = Att(immutable(thatAtt).map { case (k, v) => ((k, Att.stringClassName), v) }.toMap) - private def apply(thatAtt: Map[(Key, String), Any]) = { + private def apply(thatAtt: Map[(Key, String), Any]) = new Att(thatAtt) - } def mergeAttributes(p: Set[Att]): Att = { - val union = p.flatMap(_.att) - val attMap = union.groupBy({ case ((name, _), _) => name}) - Att(union.filter { key => attMap(key._1._1).size == 1 }.toMap) + val union = p.flatMap(_.att) + val attMap = union.groupBy { case ((name, _), _) => name } + Att(union.filter(key => attMap(key._1._1).size == 1).toMap) } implicit val ord: Ordering[Att] = { import scala.math.Ordering.Implicits._ - Ordering.by[Att, Seq[(String, String, String)]](att => att.att.iterator.map(k => (k._1._1.key, k._1._2, k._2.toString)).toSeq.sorted) + Ordering.by[Att, Seq[(String, String, String)]](att => + att.att.iterator.map(k => (k._1._1.key, k._1._2, k._2.toString)).toSeq.sorted + ) } } trait AttributesToString { self: Att => - override def toString: String = { + override def toString: String = if (att.isEmpty) { "" } else { "[" + toStrings.sorted.mkString(", ") + "]" } - } - def postfixString: String = { + def postfixString: String = if (toStrings.isEmpty) "" else " " + toString() - } - lazy val toStrings: List[String] = { val stringClassName = classOf[String].getName - att filter { case ((Att.PRODUCTION_ID, _), _) => false; case _ => true } map - { case ((attKey, `stringClassName`), "") => attKey.key - case ((attKey, _), value) => attKey.key + "(" + value + ")" } toList + att + .filter { case ((Att.PRODUCTION_ID, _), _) => false; case _ => true } + .map { + case ((attKey, `stringClassName`), "") => attKey.key + case ((attKey, _), value) => attKey.key + "(" + value + ")" + } toList } } diff --git a/kore/src/main/scala/org/kframework/attributes/Location.scala b/kore/src/main/scala/org/kframework/attributes/Location.scala index 382111c794a..3dc565b002b 100644 --- a/kore/src/main/scala/org/kframework/attributes/Location.scala +++ b/kore/src/main/scala/org/kframework/attributes/Location.scala @@ -1,9 +1,16 @@ // Copyright (c) K Team. All Rights Reserved. package org.kframework.attributes -case class Location(startLine: Int, startColumn: Int, endLine: Int, endColumn: Int) extends Comparable[Location] with AttValue { +case class Location(startLine: Int, startColumn: Int, endLine: Int, endColumn: Int) + extends Comparable[Location] + with AttValue { import scala.math.Ordered.orderingToOrdered - def compareTo(that: Location): Int = (startLine, startColumn, endLine, endColumn) compare (that.startLine, that.startColumn, that.endLine, that.endColumn) + def compareTo(that: Location): Int = (startLine, startColumn, endLine, endColumn).compare( + that.startLine, + that.startColumn, + that.endLine, + that.endColumn + ) } case class Source(source: String) extends Comparable[Source] with AttValue { diff --git a/kore/src/main/scala/org/kframework/builtin/Sorts.scala b/kore/src/main/scala/org/kframework/builtin/Sorts.scala index 61d1843e877..bdbfad677f7 100644 --- a/kore/src/main/scala/org/kframework/builtin/Sorts.scala +++ b/kore/src/main/scala/org/kframework/builtin/Sorts.scala @@ -6,42 +6,42 @@ import org.kframework.kore.ADT import org.kframework.kore.KORE.Sort object Sorts { - val Layout = Sort("#Layout") + val Layout = Sort("#Layout") val LineMarker = Sort("#LineMarker") val RuleTag = Sort("#RuleTag") - val KString = Sort("KString") - val KBool = Sort("KBool") + val KString = Sort("KString") + val KBool = Sort("KBool") val RuleContent = Sort("#RuleContent") - val RuleBody = Sort("#RuleBody") + val RuleBody = Sort("#RuleBody") - val Bool = Sort("Bool") - val Int = Sort("Int") - val MInt = Sort("MInt") - val String = Sort("String") - val Float = Sort("Float") + val Bool = Sort("Bool") + val Int = Sort("Int") + val MInt = Sort("MInt") + val String = Sort("String") + val Float = Sort("Float") val StringBuffer = Sort("StringBuffer") - val Bytes = Sort("Bytes") + val Bytes = Sort("Bytes") val List = Sort("List") - val Set = Sort("Set") - val Map = Sort("Map") - - val K = Sort("K") - val KBott = Sort("KBott") - val KVariable = Sort("#KVariable") - val KItem = Sort("KItem") - val KLabel = Sort("KLabel") - val KResult = Sort("KResult") - val KList = Sort("KList") + val Set = Sort("Set") + val Map = Sort("Map") + + val K = Sort("K") + val KBott = Sort("KBott") + val KVariable = Sort("#KVariable") + val KItem = Sort("KItem") + val KLabel = Sort("KLabel") + val KResult = Sort("KResult") + val KList = Sort("KList") val KConfigVar = Sort("KConfigVar") - val Bag = Sort("Bag") - val Cell = Sort("Cell") + val Bag = Sort("Bag") + val Cell = Sort("Cell") val CellName = Sort("#CellName"); - val GeneratedTopCell = Sort("GeneratedTopCell") + val GeneratedTopCell = Sort("GeneratedTopCell") val GeneratedCounterCell = Sort("GeneratedCounterCell") val Id = Sort("Id") diff --git a/kore/src/main/scala/org/kframework/collections.scala b/kore/src/main/scala/org/kframework/collections.scala index 35211f6c42c..f492b424b5f 100644 --- a/kore/src/main/scala/org/kframework/collections.scala +++ b/kore/src/main/scala/org/kframework/collections.scala @@ -2,28 +2,27 @@ package org.kframework -import java.util - +import collection._ import collection.JavaConverters._ -import java.util.stream.StreamSupport -import scala.collection.mutable.Builder -import scala.collection.mutable.ListBuffer +import java.util import java.util.function.BiConsumer import java.util.function.BinaryOperator import java.util.function.Supplier -import scala.collection.mutable.SetBuilder +import java.util.stream.StreamSupport +import scala.collection.mutable.Builder +import scala.collection.mutable.ListBuffer import scala.collection.mutable.MapBuilder -import collection._ +import scala.collection.mutable.SetBuilder object Collections { def immutable[T](s: java.lang.Iterable[T]): Iterable[T] = s.asScala - def immutable[T](s: java.util.Set[T]): Set[T] = s.asScala.toSet - def immutable[T](s: java.util.List[T]): Seq[T] = s.asScala - def immutable[K, V](s: java.util.Map[K, V]): Map[K, V] = s.asScala - def immutable[T](s: Array[T]): Seq[T] = s + def immutable[T](s: java.util.Set[T]): Set[T] = s.asScala.toSet + def immutable[T](s: java.util.List[T]): Seq[T] = s.asScala + def immutable[K, V](s: java.util.Map[K, V]): Map[K, V] = s.asScala + def immutable[T](s: Array[T]): Seq[T] = s - def mutable[T](s: scala.List[T]): java.util.List[T] = s.asJava - def mutable[T](s: Seq[T]): java.util.List[T] = s.asJava + def mutable[T](s: scala.List[T]): java.util.List[T] = s.asJava + def mutable[T](s: Seq[T]): java.util.List[T] = s.asJava def mutable[K, V](s: Map[K, V]): java.util.Map[K, V] = s.asJava def mutable[T](s: Set[T]): java.util.Set[T] = { val x = new util.HashSet[T]() @@ -32,21 +31,26 @@ object Collections { } def iterable[T](c: Iterable[T]): java.lang.Iterable[T] = c.asJava - def stream[T](c: Iterable[T]): java.util.stream.Stream[T] = StreamSupport.stream(c.asJava.spliterator(), false); + def stream[T](c: Iterable[T]): java.util.stream.Stream[T] = + StreamSupport.stream(c.asJava.spliterator(), false); def map[T](f: java.util.function.Function[T, T])(s: Set[T]): Set[T] = s.map(x => f(x)) - def map[T](f: java.util.function.Function[T, T])(s: scala.List[T]): scala.List[T] = s.map(x => f(x)) + def map[T](f: java.util.function.Function[T, T])(s: scala.List[T]): scala.List[T] = + s.map(x => f(x)) def map[T](f: java.util.function.Function[T, T])(s: Seq[T]): Seq[T] = s.map(x => f(x)) - def add[T](e: T)(s: Set[T]): Set[T] = s + e - def minus[T](e: T)(s: Set[T]): Set[T] = s - e + def add[T](e: T)(s: Set[T]): Set[T] = s + e + def minus[T](e: T)(s: Set[T]): Set[T] = s - e def or[T](a: Set[T], b: Set[T]): Set[T] = a | b def cons[T](e: T)(s: Seq[T]): Seq[T] = e +: s - @annotation.varargs def List[T](es: T*): scala.List[T] = scala.List[T](es: _*) - @annotation.varargs def Seq[T](es: T*) = scala.collection.immutable.Seq[T](es: _*) - @annotation.varargs def Set[T](es: T*) = scala.collection.immutable.Set[T](es: _*) + @annotation.varargs + def List[T](es: T*): scala.List[T] = scala.List[T](es: _*) + @annotation.varargs + def Seq[T](es: T*) = scala.collection.immutable.Seq[T](es: _*) + @annotation.varargs + def Set[T](es: T*) = scala.collection.immutable.Set[T](es: _*) def toList[T]: Collector[T, scala.List[T]] = Collector(() => new CombinerFromBuilder(ListBuffer())) @@ -58,8 +62,9 @@ object Collections { Collector(() => new CombinerFromBuilder(new MapBuilder(Map()))) } -class CombinerFromBuilder[T, R <: {def iterator : Iterator[T]}](protected[this] val b: Builder[T, R]) extends -Combiner[T, R] { +class CombinerFromBuilder[T, R <: { def iterator: Iterator[T] }]( + protected[this] val b: Builder[T, R] +) extends Combiner[T, R] { type This <: CombinerFromBuilder[T, R] def +=(elem: T): this.type = { b += elem; this } @@ -81,7 +86,8 @@ trait Combiner[T, R] extends Builder[T, R] with Iterable[T] { def combine(other: Iterable[T]) } -case class Collector[T, R](cf: () => Combiner[T, R]) extends java.util.stream.Collector[T, Combiner[T, R], R] { +case class Collector[T, R](cf: () => Combiner[T, R]) + extends java.util.stream.Collector[T, Combiner[T, R], R] { def accumulator() = new BiConsumer[Combiner[T, R], T] { def accept(buffer: Combiner[T, R], e: T) = buffer += e } @@ -95,9 +101,10 @@ case class Collector[T, R](cf: () => Combiner[T, R]) extends java.util.stream.Co } } - def finisher(): java.util.function.Function[Combiner[T, R], R] = new java.util.function.Function[Combiner[T, R], R] { - def apply(buffer: Combiner[T, R]): R = buffer.result() - } + def finisher(): java.util.function.Function[Combiner[T, R], R] = + new java.util.function.Function[Combiner[T, R], R] { + def apply(buffer: Combiner[T, R]): R = buffer.result() + } def supplier(): Supplier[Combiner[T, R]] = new Supplier[Combiner[T, R]] { def get() = cf() diff --git a/kore/src/main/scala/org/kframework/compile/AddBottomSortForListsWithIdenticalLabels.scala b/kore/src/main/scala/org/kframework/compile/AddBottomSortForListsWithIdenticalLabels.scala index e4c92c23afb..d70048e9201 100644 --- a/kore/src/main/scala/org/kframework/compile/AddBottomSortForListsWithIdenticalLabels.scala +++ b/kore/src/main/scala/org/kframework/compile/AddBottomSortForListsWithIdenticalLabels.scala @@ -1,34 +1,42 @@ // Copyright (c) K Team. All Rights Reserved. package org.kframework.compile +import collection._ import org.kframework.attributes.Att import org.kframework.definition._ import org.kframework.kore.KORE.Sort - -import collection._ import scala.collection.immutable.Iterable object AddBottomSortForListsWithIdenticalLabels extends Function[Module, Module] { val singleton = this override def apply(m: Module) = { - val theAdditionalSubsortingProductionsSets: Iterable[Set[Sentence]] = UserList.apply(m.sentences) + val theAdditionalSubsortingProductionsSets: Iterable[Set[Sentence]] = UserList + .apply(m.sentences) .groupBy(l => l.klabel) - .map { - case (klabel, userListInfo) => - val minimalSorts = m.subsorts.minimal(userListInfo map { li => li.sort }) - if (minimalSorts.size > 1) { - val newBottomSort = Sort("GeneratedListBottom{" + klabel.name.replace("|","") + "}") + .map { case (klabel, userListInfo) => + val minimalSorts = m.subsorts.minimal(userListInfo.map(li => li.sort)) + if (minimalSorts.size > 1) { + val newBottomSort = Sort("GeneratedListBottom{" + klabel.name.replace("|", "") + "}") - Set[Sentence]() - .|(minimalSorts.map(s => Production(Seq(), s, Seq(NonTerminal(newBottomSort, None)), Att.empty))) - .+(SyntaxSort(Seq(), newBottomSort, Att.empty)) - .+(Production(userListInfo.head.pTerminator.klabel.get, Seq(), newBottomSort, + Set[Sentence]() + .|( + minimalSorts + .map(s => Production(Seq(), s, Seq(NonTerminal(newBottomSort, None)), Att.empty)) + ) + .+(SyntaxSort(Seq(), newBottomSort, Att.empty)) + .+( + Production( + userListInfo.head.pTerminator.klabel.get, + Seq(), + newBottomSort, Seq(Terminal(".GeneratedListBottom")), - Att.empty.add(Att.UNPARSE_AVOID))) - } else { - Set[Sentence]() - } + Att.empty.add(Att.UNPARSE_AVOID) + ) + ) + } else { + Set[Sentence]() + } } val theAdditionalSubsortingProductions = theAdditionalSubsortingProductionsSets.flatten diff --git a/kore/src/main/scala/org/kframework/compile/AssocCommToAssoc.scala b/kore/src/main/scala/org/kframework/compile/AssocCommToAssoc.scala index 71fbe08787f..11f49672cb1 100644 --- a/kore/src/main/scala/org/kframework/compile/AssocCommToAssoc.scala +++ b/kore/src/main/scala/org/kframework/compile/AssocCommToAssoc.scala @@ -1,27 +1,28 @@ // Copyright (c) K Team. All Rights Reserved. package org.kframework.compile -import org.kframework.Collections._ +import collection.JavaConverters._ import org.kframework.attributes.Att -import org.kframework.definition.{Module, Rule, Sentence} -import org.kframework.kore.SortedADT.SortedKVariable -import org.kframework.kore.KORE.{KApply, KRewrite} +import org.kframework.definition.Module +import org.kframework.definition.Rule +import org.kframework.definition.Sentence import org.kframework.kore._ - -import collection.JavaConverters._ +import org.kframework.kore.KORE.KApply +import org.kframework.kore.KORE.KRewrite +import org.kframework.kore.SortedADT.SortedKVariable +import org.kframework.Collections._ import scala.collection.Set /** - * Compiler pass for merging the rules as expected by FastRuleMatcher - */ + * Compiler pass for merging the rules as expected by FastRuleMatcher + */ class AssocCommToAssoc extends Function[Module, Module] { - override def apply(m: Module) = { - Module(m.name, m.imports, m.localSentences flatMap {apply(_)(m)}, m.att) - } + override def apply(m: Module) = + Module(m.name, m.imports, m.localSentences.flatMap(apply(_)(m)), m.att) private def apply(s: Sentence)(implicit m: Module): List[Sentence] = s match { - //TODO(AndreiS): handle AC in requires and ensures + // TODO(AndreiS): handle AC in requires and ensures case r: Rule if !r.att.contains(Att.PATTERN_FOLDING) => val newBodies = apply(r.body) val substitutionOfVariables: Map[KVariable, K] = new FoldK[Map[KVariable, K]]() { @@ -32,17 +33,20 @@ class AssocCommToAssoc extends Function[Module, Module] { override def apply(k: KRewrite): E = apply(k.left) override def apply(k: KApply) = - merge(if(isAssocComm(k.klabel)) - computeSubstitution(k.klabel, k.items.asScala.toList) - else - unit, super.apply(k)) + merge( + if (isAssocComm(k.klabel)) + computeSubstitution(k.klabel, k.items.asScala.toList) + else + unit, + super.apply(k) + ) }.apply(r.body) val substitute = new TransformK() { override def apply(v: KVariable) = substitutionOfVariables.getOrElse(v, v) } newBodies .map(substitute) - .map {Rule(_, r.requires, r.ensures, r.att)} + .map(Rule(_, r.requires, r.ensures, r.att)) // if(substitutionOfVariables.nonEmpty) { // println(newBodies) @@ -55,9 +59,9 @@ class AssocCommToAssoc extends Function[Module, Module] { case Unapply.KApply(label: KLabel, children: List[K]) if isAssocComm(label) => convert(label, children) case Unapply.KApply(label: KLabel, children: List[K]) => - crossProduct(children map apply) map {KApply(label,(_: _*))} + crossProduct(children.map(apply)).map(KApply(label, _: _*)) case Unapply.KRewrite(left: K, right: K) => - apply(left) map {KRewrite(_, right, Att.empty)} + apply(left).map(KRewrite(_, right, Att.empty)) case _ => List(k) } @@ -70,67 +74,82 @@ class AssocCommToAssoc extends Function[Module, Module] { private def convert(label: KLabel, children: List[K])(implicit m: Module): List[K] = { val opSort: Sort = m.signatureFor(label).head._2 - val (elements: Seq[K], nonElements: Seq[K]) = children partition { + val (elements: Seq[K], nonElements: Seq[K]) = children.partition { case v: SortedKVariable => m.subsorts.lessThan(v.sort, opSort); - case _ => true + case _ => true } assert(nonElements.size <= 1) - assert(nonElements.headOption forall { case v: KVariable => v.name.equals("THE_VARIABLE") || v.name.startsWith("_DotVar") || v.att.contains(Att.ANONYMOUS) }) + assert(nonElements.headOption.forall { case v: KVariable => + v.name.equals("THE_VARIABLE") || v.name.startsWith("_DotVar") || v.att.contains(Att.ANONYMOUS) + }) val frameOption = nonElements.headOption val convertedChildren: List[List[K]] = frameOption match { case Some(v: KVariable) if v.name.equals("THE_VARIABLE") => - elements.permutations.toList map { - _.foldRight(List(anonymousVariable(opSort))) { (e, l) => anonymousVariable(opSort) :: e :: l } + elements.permutations.toList.map { + _.foldRight(List(anonymousVariable(opSort))) { (e, l) => + anonymousVariable(opSort) :: e :: l + } } - //TODO(AndreiS): check the variable is free (not constrained elsewhere by the rule) + // TODO(AndreiS): check the variable is free (not constrained elsewhere by the rule) case Some(v: KVariable) if v.name.startsWith("_DotVar") || v.att.contains(Att.ANONYMOUS) => - elements.permutations.toList map { - _.foldRight(List(dotVariable(opSort, 0))) { (e, l) => dotVariable(opSort, (l.size + 1) / 2) :: e :: l } + elements.permutations.toList.map { + _.foldRight(List(dotVariable(opSort, 0))) { (e, l) => + dotVariable(opSort, (l.size + 1) / 2) :: e :: l + } } case None => elements.toList.permutations.toList } - convertedChildren flatMap { cs => crossProduct(cs map apply) } map {KApply(label,(_: _*))} + convertedChildren.flatMap(cs => crossProduct(cs.map(apply))).map(KApply(label, _: _*)) } - private def computeSubstitution(label: KLabel, children: List[K])(implicit m: Module): Map[KVariable, K] = { + private def computeSubstitution(label: KLabel, children: List[K])(implicit + m: Module + ): Map[KVariable, K] = { val opSort: Sort = m.signatureFor(label).head._2 - val (elements: Seq[K], nonElements: Seq[K]) = children partition { + val (elements: Seq[K], nonElements: Seq[K]) = children.partition { case v: SortedKVariable => m.subsorts.lessThan(v.sort, opSort); - case _ => true + case _ => true } assert(nonElements.size <= 1) - assert(nonElements.headOption forall { case v: KVariable => v.name.equals("THE_VARIABLE") || v.name.startsWith("_DotVar") || v.att.contains(Att.ANONYMOUS) }) + assert(nonElements.headOption.forall { case v: KVariable => + v.name.equals("THE_VARIABLE") || v.name.startsWith("_DotVar") || v.att.contains(Att.ANONYMOUS) + }) val frameOption = nonElements.headOption frameOption match { case Some(v: KVariable) if v.name.startsWith("_DotVar") || v.att.contains(Att.ANONYMOUS) => - Map(v -> KApply(label,((0 to elements.size) map {dotVariable(opSort, _)}: _*))) + Map(v -> KApply(label, (0 to elements.size).map(dotVariable(opSort, _)): _*)) case _ => Map() } } private def substituteFrame(k: K, name: String, substitute: K): K = k match { - case Unapply.KApply(label: KLabel, children: List[K]) => KApply(label, children map {substituteFrame(_, name, substitute)}: _*) + case Unapply.KApply(label: KLabel, children: List[K]) => + KApply(label, children.map(substituteFrame(_, name, substitute)): _*) case Unapply.KVariable(`name`) => substitute - case _: K => k + case _: K => k } - private def crossProduct[T](lls: List[List[T]]): List[List[T]] = { + private def crossProduct[T](lls: List[List[T]]): List[List[T]] = lls match { case (head: List[T]) :: (tail: List[List[T]]) => - for {x <- head; (xs: List[T]) <- crossProduct(tail)} yield x :: xs + for { + x <- head + (xs: List[T]) <- crossProduct(tail) + } yield x :: xs case List() => List(List()) } - } - private def anonymousVariable(s: Sort): K = SortedADT.SortedKVariable("THE_VARIABLE", Att.empty.add(classOf[Sort], s)) + private def anonymousVariable(s: Sort): K = + SortedADT.SortedKVariable("THE_VARIABLE", Att.empty.add(classOf[Sort], s)) - private def dotVariable(s: Sort, n: Int): K = SortedADT.SortedKVariable(s.toString + "_DotVar" + n, Att.empty.add(classOf[Sort], s)) + private def dotVariable(s: Sort, n: Int): K = + SortedADT.SortedKVariable(s.toString + "_DotVar" + n, Att.empty.add(classOf[Sort], s)) } diff --git a/kore/src/main/scala/org/kframework/compile/ConfigurationInfoFromModule.scala b/kore/src/main/scala/org/kframework/compile/ConfigurationInfoFromModule.scala index 100e6d925d8..a4d3eb068fd 100644 --- a/kore/src/main/scala/org/kframework/compile/ConfigurationInfoFromModule.scala +++ b/kore/src/main/scala/org/kframework/compile/ConfigurationInfoFromModule.scala @@ -1,33 +1,40 @@ // Copyright (c) K Team. All Rights Reserved. package org.kframework.compile +import collection._ import java.util -import org.kframework.POSet -import org.kframework.kore.KORE.{KApply, KLabel} - -import scala.collection.JavaConverters._ +import org.kframework.attributes.Att +import org.kframework.builtin.Sorts import org.kframework.compile.ConfigurationInfo.Multiplicity -import org.kframework.definition.{Module, NonTerminal, Production, Rule} +import org.kframework.definition.Module +import org.kframework.definition.NonTerminal +import org.kframework.definition.Production +import org.kframework.definition.Rule import org.kframework.kore._ -import org.kframework.TopologicalSort._ -import org.kframework.attributes.Att +import org.kframework.kore.KORE.KApply +import org.kframework.kore.KORE.KLabel import org.kframework.utils.errorsystem.KEMException -import org.kframework.builtin.Sorts - -import collection._ +import org.kframework.POSet +import org.kframework.TopologicalSort._ +import scala.collection.JavaConverters._ object ConfigurationInfoFromModule class ConfigurationInfoFromModule(val m: Module) extends ConfigurationInfo { - private val cellProductionsSet: Set[(Sort, Production)] = m.productions.filter(_.att.contains(Att.CELL)) .map(p => (p.sort, p)) - private val cellBagProductionsSet: Set[(Sort, Production)] = m.productions.filter(_.att.contains(Att.CELL_COLLECTION)).map(p => (p.sort, p)) + private val cellProductionsSet: Set[(Sort, Production)] = + m.productions.filter(_.att.contains(Att.CELL)).map(p => (p.sort, p)) + private val cellBagProductionsSet: Set[(Sort, Production)] = + m.productions.filter(_.att.contains(Att.CELL_COLLECTION)).map(p => (p.sort, p)) - private val cellSorts: Set[Sort] = cellProductionsSet .map({sp => sp._1}) - private val cellBagSorts: Set[Sort] = cellBagProductionsSet.map({sp => sp._1}) + private val cellSorts: Set[Sort] = cellProductionsSet.map(sp => sp._1) + private val cellBagSorts: Set[Sort] = cellBagProductionsSet.map(sp => sp._1) private def buildCellProductionMap(cells: Set[(Sort, Production)]): Map[Sort, Production] = { - def buildCellProductionMap(_cells: Set[(Sort, Production)], _cellMap: Map[Sort, Production]): Map[Sort, Production] = { + def buildCellProductionMap( + _cells: Set[(Sort, Production)], + _cellMap: Map[Sort, Production] + ): Map[Sort, Production] = { if (_cells.size == 0) return _cellMap val (s, p) = _cells.head @@ -40,46 +47,58 @@ class ConfigurationInfoFromModule(val m: Module) extends ConfigurationInfo { buildCellProductionMap(cells, Map()) } - private val cellProductions: Map[Sort,Production] = buildCellProductionMap(cellProductionsSet) - private val cellBagProductions: Map[Sort,Production] = buildCellProductionMap(cellBagProductionsSet) + private val cellProductions: Map[Sort, Production] = buildCellProductionMap(cellProductionsSet) + private val cellBagProductions: Map[Sort, Production] = buildCellProductionMap( + cellBagProductionsSet + ) - private val cellBagSubsorts: Map[Sort, Set[Sort]] = cellBagProductions.values.map(p => (p.sort, getCellSortsOfCellBag(p.sort))).toMap - private val cellLabels: Map[Sort, KLabel] = cellProductions.mapValues(_.klabel.get) + private val cellBagSubsorts: Map[Sort, Set[Sort]] = + cellBagProductions.values.map(p => (p.sort, getCellSortsOfCellBag(p.sort))).toMap + private val cellLabels: Map[Sort, KLabel] = cellProductions.mapValues(_.klabel.get) private val cellLabelsToSorts: Map[KLabel, Sort] = cellLabels.map(_.swap) - private val cellFragmentLabel: Map[Sort,KLabel] = - m.productions.filter(_.att.contains(Att.CELL_FRAGMENT, classOf[Sort])) - .map(p => (p.att.get(Att.CELL_FRAGMENT, classOf[Sort]),p.klabel.get)).toMap - private val cellAbsentLabel: Map[Sort,KLabel] = - m.productions.filter(_.att.contains(Att.CELL_OPT_ABSENT, classOf[Sort])) - .map (p => (p.att.get(Att.CELL_OPT_ABSENT, classOf[Sort]),p.klabel.get)).toMap - + private val cellFragmentLabel: Map[Sort, KLabel] = + m.productions + .filter(_.att.contains(Att.CELL_FRAGMENT, classOf[Sort])) + .map(p => (p.att.get(Att.CELL_FRAGMENT, classOf[Sort]), p.klabel.get)) + .toMap + private val cellAbsentLabel: Map[Sort, KLabel] = + m.productions + .filter(_.att.contains(Att.CELL_OPT_ABSENT, classOf[Sort])) + .map(p => (p.att.get(Att.CELL_OPT_ABSENT, classOf[Sort]), p.klabel.get)) + .toMap private val cellInitializer: Map[Sort, KApply] = - m.productions.filter(p => (cellSorts(p.sort) || cellBagSorts(p.sort)) && p.att.contains(Att.INITIALIZER)) - .map(p => (p.sort, KApply(p.klabel.get))).flatMap({ case (s, app) => if (cellBagSorts(s)) getCellSortsOfCellBag(s).map((_, app)) else Seq((s, app))}).toMap + m.productions + .filter(p => (cellSorts(p.sort) || cellBagSorts(p.sort)) && p.att.contains(Att.INITIALIZER)) + .map(p => (p.sort, KApply(p.klabel.get))) + .flatMap { case (s, app) => + if (cellBagSorts(s)) getCellSortsOfCellBag(s).map((_, app)) else Seq((s, app)) + } + .toMap - private val edges: Set[(Sort, Sort)] = cellProductions.toList.flatMap { case (s,p) => - p.items.flatMap{ + private val edges: Set[(Sort, Sort)] = cellProductions.toList.flatMap { case (s, p) => + p.items.flatMap { case NonTerminal(n, _) if cellSorts.contains(n) => List((s, n)) - case NonTerminal(n, _) if cellBagSorts.contains(n) => getCellSortsOfCellBag(n).map(subsort => (s, subsort)) + case NonTerminal(n, _) if cellBagSorts.contains(n) => + getCellSortsOfCellBag(n).map(subsort => (s, subsort)) case _ => List() - }}.toSet + } + }.toSet - private def getCellSortsOfCellBag(n: Sort): Set[Sort] = { + private def getCellSortsOfCellBag(n: Sort): Set[Sort] = m.allSorts.filter(m.subsorts.directlyGreaterThan(n, _)) - } - override def getCellBagSortsOfCell(n: Sort): Set[Sort] = { + override def getCellBagSortsOfCell(n: Sort): Set[Sort] = m.allSorts.filter(m.subsorts.directlyLessThan(n, _)).intersect(cellBagSorts) - } private val edgesPoset: POSet[Sort] = POSet(edges) private lazy val topCells = cellSorts.diff(edges.map(_._2)) - private val sortedSorts: Seq[Sort] = tsort(edges).toSeq - private val sortedEdges: Seq[(Sort, Sort)] = edges.toList.sortWith((l, r) => sortedSorts.indexOf(l._1) < sortedSorts.indexOf(r._1)) + private val sortedSorts: Seq[Sort] = tsort(edges).toSeq + private val sortedEdges: Seq[(Sort, Sort)] = + edges.toList.sortWith((l, r) => sortedSorts.indexOf(l._1) < sortedSorts.indexOf(r._1)) val levels: Map[Sort, Int] = sortedEdges.foldLeft(topCells.map((_, 0)).toMap) { case (m: Map[Sort, Int], (from: Sort, to: Sort)) => m + (to -> (m(from) + 1)) @@ -94,8 +113,8 @@ class ConfigurationInfoFromModule(val m: Module) extends ConfigurationInfo { mainCells.head } - override def getLevel(k: Sort): Int = levels.getOrElse(k, -1) - override def isParentCell(k: Sort): Boolean = edges exists { case (c, _) => c == k } + override def getLevel(k: Sort): Int = levels.getOrElse(k, -1) + override def isParentCell(k: Sort): Boolean = edges.exists { case (c, _) => c == k } override def getMultiplicity(k: Sort): Multiplicity = if (cellBagSubsorts.values.flatten.toSet.contains(k)) @@ -105,32 +124,37 @@ class ConfigurationInfoFromModule(val m: Module) extends ConfigurationInfo { else Multiplicity.ONE - override def getParent(k: Sort): Sort = edges collectFirst { case (p, `k`) => p } get - override def isCell(k: Sort): Boolean = cellSorts.contains(k) - override def isCellCollection(s: Sort): Boolean = cellBagSorts.contains(s) + override def getParent(k: Sort): Sort = edges.collectFirst { case (p, `k`) => p } get + override def isCell(k: Sort): Boolean = cellSorts.contains(k) + override def isCellCollection(s: Sort): Boolean = cellBagSorts.contains(s) override def isCellLabel(kLabel: KLabel): Boolean = cellLabelsToSorts.contains(kLabel) - override def isLeafCell(k: Sort): Boolean = !isParentCell(k) - - override def getChildren(k: Sort): util.List[Sort] = cellProductions(k).items.filter(_.isInstanceOf[NonTerminal]).map(_.asInstanceOf[NonTerminal].sort).flatMap {s => { - if (cellBagSorts(s)) - getCellSortsOfCellBag(s).toSeq - else - Seq(s) - }}.asJava + override def isLeafCell(k: Sort): Boolean = !isParentCell(k) + + override def getChildren(k: Sort): util.List[Sort] = cellProductions(k).items + .filter(_.isInstanceOf[NonTerminal]) + .map(_.asInstanceOf[NonTerminal].sort) + .flatMap { s => + if (cellBagSorts(s)) + getCellSortsOfCellBag(s).toSeq + else + Seq(s) + } + .asJava - override def leafCellType(k: Sort): Sort = cellProductions(k).items.collectFirst{ case NonTerminal(n, _) => n} get + override def leafCellType(k: Sort): Sort = cellProductions(k).items.collectFirst { + case NonTerminal(n, _) => n + } get override def getDefaultCell(k: Sort): KApply = cellInitializer(k) - override def isConstantInitializer(k: Sort): Boolean = { + override def isConstantInitializer(k: Sort): Boolean = !m.productionsFor(getDefaultCell(k).klabel).exists(_.items.exists(_.isInstanceOf[NonTerminal])) - } - override def getCellLabel(k: Sort): KLabel = cellLabels(k) + override def getCellLabel(k: Sort): KLabel = cellLabels(k) override def getCellSort(kLabel: KLabel): Sort = cellLabelsToSorts(kLabel) - override def getCellFragmentLabel(k : Sort): KLabel = cellFragmentLabel(k) - override def getCellAbsentLabel(k: Sort): KLabel = cellAbsentLabel(k) + override def getCellFragmentLabel(k: Sort): KLabel = cellFragmentLabel(k) + override def getCellAbsentLabel(k: Sort): KLabel = cellAbsentLabel(k) override def getRootCell: Sort = { if (topCells.size > 1) @@ -138,10 +162,10 @@ class ConfigurationInfoFromModule(val m: Module) extends ConfigurationInfo { topCells.head } - override def getComputationCell: Sort = mainCell + override def getComputationCell: Sort = mainCell override def getCellSorts: util.Set[Sort] = cellSorts.asJava - override def getUnit(k: Sort): KApply = { + override def getUnit(k: Sort): KApply = if (getMultiplicity(k) == Multiplicity.OPTIONAL) KApply(KLabel(cellProductions(k).att.get(Att.UNIT))) else { @@ -149,7 +173,6 @@ class ConfigurationInfoFromModule(val m: Module) extends ConfigurationInfo { assert(sorts.size == 1, "Too many cell bags found for cell sort: " + k + ", " + sorts) KApply(KLabel(cellBagProductions(sorts.head).att.get(Att.UNIT))) } - } override def getConcat(k: Sort): KLabel = { val sorts = getCellBagSortsOfCell(k) @@ -160,7 +183,11 @@ class ConfigurationInfoFromModule(val m: Module) extends ConfigurationInfo { override def getCellForConcat(concat: KLabel): Option[Sort] = cellSorts .map(s => (s, getCellBagSortsOfCell(s))) .filter(_._2.size == 1) - .filter(p => cellBagProductions(p._2.head).klabel.get.equals(concat) || (cellInitializer.contains(p._1) && cellInitializer(p._1).klabel == concat)) + .filter(p => + cellBagProductions(p._2.head).klabel.get.equals(concat) || (cellInitializer.contains( + p._1 + ) && cellInitializer(p._1).klabel == concat) + ) .map(_._1) .headOption @@ -174,24 +201,23 @@ class ConfigurationInfoFromModule(val m: Module) extends ConfigurationInfo { .headOption } - - lazy val initRules: Set[Rule] = m.rules.collect({ case r if r.att.contains(Att.INITIALIZER) => r }) + lazy val initRules: Set[Rule] = m.rules.collect { case r if r.att.contains(Att.INITIALIZER) => r } lazy val configVars: Set[KToken] = { val transformer = new FoldK[Set[KToken]] { - override def apply(k: KToken): Set[KToken] = { + override def apply(k: KToken): Set[KToken] = if (k.sort == Sorts.KConfigVar) Set(k) else unit - } - def unit = Set() + def unit = Set() def merge(set1: Set[KToken], set2: Set[KToken]) = set1 | set2 } - initRules.map(r => transformer.apply(r.body)) + initRules + .map(r => transformer.apply(r.body)) .fold(transformer.unit)(transformer.merge) } lazy val cellProductionsFor: Map[Sort, Set[Production]] = m.productions - .collect({ case p if p.att.contains(Att.CELL) => p }) + .collect { case p if p.att.contains(Att.CELL) => p } .groupBy(_.sort) .map { case (s, ps) => (s, ps) } diff --git a/kore/src/main/scala/org/kframework/compile/LabelInfoFromModule.scala b/kore/src/main/scala/org/kframework/compile/LabelInfoFromModule.scala index 0fdbc09894e..f0e2ff3be1d 100644 --- a/kore/src/main/scala/org/kframework/compile/LabelInfoFromModule.scala +++ b/kore/src/main/scala/org/kframework/compile/LabelInfoFromModule.scala @@ -5,10 +5,15 @@ import org.kframework.attributes.Att import org.kframework.definition.Module class LabelInfoFromModule(module: Module) extends LabelInfo { - module.productionsFor.foreach({ - case (label, prods) => - def att(key : Att.Key) = prods.exists(_.att.contains(key)) - addLabel(prods.head.sort, label.toString, att(Att.ASSOC), att(Att.COMM), - att(Att.FUNCTION) || att(Att.PATTERN), prods.head) - }) + module.productionsFor.foreach { case (label, prods) => + def att(key: Att.Key) = prods.exists(_.att.contains(key)) + addLabel( + prods.head.sort, + label.toString, + att(Att.ASSOC), + att(Att.COMM), + att(Att.FUNCTION) || att(Att.PATTERN), + prods.head + ) + } } diff --git a/kore/src/main/scala/org/kframework/compile/MergeRules.scala b/kore/src/main/scala/org/kframework/compile/MergeRules.scala index 1a06e8625b2..067cce129e8 100644 --- a/kore/src/main/scala/org/kframework/compile/MergeRules.scala +++ b/kore/src/main/scala/org/kframework/compile/MergeRules.scala @@ -1,28 +1,38 @@ // Copyright (c) K Team. All Rights Reserved. package org.kframework.compile +import collection._ import org.kframework.attributes.Att -import org.kframework.builtin.{KLabels, Sorts} -import org.kframework.definition.{Module, ModuleTransformer, Rule} +import org.kframework.builtin.KLabels +import org.kframework.builtin.Sorts +import org.kframework.definition.Module +import org.kframework.definition.ModuleTransformer +import org.kframework.definition.Rule import org.kframework.kore._ -import org.kframework.kore.KORE.{KApply, KLabel, KToken, Sort} -import org.kframework.kore.{K, KApply, KLabel, KVariable, Unapply, Assoc} - -import scala.collection.JavaConverters._ +import org.kframework.kore.Assoc +import org.kframework.kore.K +import org.kframework.kore.KApply +import org.kframework.kore.KLabel +import org.kframework.kore.KORE.KApply +import org.kframework.kore.KORE.KLabel +import org.kframework.kore.KORE.KToken +import org.kframework.kore.KORE.Sort +import org.kframework.kore.KVariable +import org.kframework.kore.Unapply import scala.collection.immutable.Iterable -import collection._ +import scala.collection.JavaConverters._ /** - * Compiler pass for merging the rules as expected by FastRuleMatcher - */ -class MergeRules(val automatonAttribute: Att.Key, filterAttribute: Att.Key) extends Function[Module, Module] { - + * Compiler pass for merging the rules as expected by FastRuleMatcher + */ +class MergeRules(val automatonAttribute: Att.Key, filterAttribute: Att.Key) + extends Function[Module, Module] { object ML { - val and = KLabels.ML_AND - val or = KLabels.ML_OR - val True = KApply(KLabels.ML_TRUE) - val False = KApply(KLabels.ML_FALSE) + val and = KLabels.ML_AND + val or = KLabels.ML_OR + val True = KApply(KLabels.ML_TRUE) + val False = KApply(KLabels.ML_FALSE) val TrueToken: K = KToken("true", Sorts.Bool, Att.empty) } @@ -31,10 +41,15 @@ class MergeRules(val automatonAttribute: Att.Key, filterAttribute: Att.Key) exte val isRulePredicate = KLabel("isRule") def apply(m: Module): Module = { - val rulesToMerge = m.rules filter {_.att.contains(filterAttribute)} + val rulesToMerge = m.rules.filter(_.att.contains(filterAttribute)) if (rulesToMerge.nonEmpty) { - val newBody = pushDisjunction(rulesToMerge map { r => (convertKRewriteToKApply(r.body), KApply(isRulePredicate,KToken(r.hashCode.toString, Sorts.K, Att.empty))) })(m) + val newBody = pushDisjunction(rulesToMerge.map { r => + ( + convertKRewriteToKApply(r.body), + KApply(isRulePredicate, KToken(r.hashCode.toString, Sorts.K, Att.empty)) + ) + })(m) val automatonRule = Rule(newBody, TrueToken, TrueToken, Att.empty.add(automatonAttribute)) Module(m.name, m.imports, m.localSentences + automatonRule, m.att) } else { @@ -43,78 +58,97 @@ class MergeRules(val automatonAttribute: Att.Key, filterAttribute: Att.Key) exte } private def convertKRewriteToKApply(k: K): K = k match { - case Unapply.KApply(label, children) => KApply(label, (children map convertKRewriteToKApply: _*)) - case Unapply.KRewrite(l, r) => KApply(KLabels.KREWRITE,l, r) - case other => other + case Unapply.KApply(label, children) => KApply(label, children.map(convertKRewriteToKApply): _*) + case Unapply.KRewrite(l, r) => KApply(KLabels.KREWRITE, l, r) + case other => other } - private def makeOr(ks: K*): K = { + private def makeOr(ks: K*): K = if (ks.size == 1) { ks.head } else { - KApply(or,ks: _*) + KApply(or, ks: _*) } - } private def pushDisjunction(terms: Set[(K, K)])(implicit m: Module): K = { val rwLabel = KLabels.KREWRITE - val termsWithoutRewrites: Set[(K, K)] = terms.map({ + val termsWithoutRewrites: Set[(K, K)] = terms.map { case (Unapply.KApply(`rwLabel`, children), ruleP) => (children.head, ruleP) - case other => other - }) + case other => other + } - val theRewrites: Set[(K, K)] = terms collect { case (Unapply.KApply(`rwLabel`, children), ruleP) => (children.last, ruleP) } + val theRewrites: Set[(K, K)] = terms.collect { + case (Unapply.KApply(`rwLabel`, children), ruleP) => (children.last, ruleP) + } val disjunctionOfKApplies: Iterable[(K, K)] = termsWithoutRewrites - .collect({ case (x: KApply, ruleP) if !x.klabel.isInstanceOf[KVariable] => (x, ruleP) }) + .collect { case (x: KApply, ruleP) if !x.klabel.isInstanceOf[KVariable] => (x, ruleP) } .groupBy(_._1.klabel) - .map { - case (klabel: KLabel, ks: Set[(KApply, K)]) => - val klistPredicatePairs: Set[(Seq[K], K)] = ks map { case (kapply, ruleP) => (kapply.klist.items.asScala.toSeq, ruleP) } - val normalizedItemsPredicatePairs = if (isEffectiveAssoc(klabel, m) || klabel == KLabels.KSEQ) { - val unitKLabel: KLabel = if (klabel != KLabels.KSEQ) KLabel(m.attributesFor(klabel).get(Att.UNIT)) else KLabels.DOTK + .map { case (klabel: KLabel, ks: Set[(KApply, K)]) => + val klistPredicatePairs: Set[(Seq[K], K)] = ks.map { case (kapply, ruleP) => + (kapply.klist.items.asScala.toSeq, ruleP) + } + val normalizedItemsPredicatePairs = + if (isEffectiveAssoc(klabel, m) || klabel == KLabels.KSEQ) { + val unitKLabel: KLabel = + if (klabel != KLabels.KSEQ) KLabel(m.attributesFor(klabel).get(Att.UNIT)) + else KLabels.DOTK val unitK: K = KApply(unitKLabel) - val flatItemsPredicatePairs: Set[(Seq[K], K)] = klistPredicatePairs map { case (items, ruleP) => (Assoc.flatten(klabel, items, unitKLabel), ruleP) } - val maxLength: Int = (flatItemsPredicatePairs map { _._1.size }).max - flatItemsPredicatePairs map { case (items, ruleP) => (items.padTo(maxLength, unitK), ruleP) } + val flatItemsPredicatePairs: Set[(Seq[K], K)] = klistPredicatePairs.map { + case (items, ruleP) => (Assoc.flatten(klabel, items, unitKLabel), ruleP) + } + val maxLength: Int = flatItemsPredicatePairs.map(_._1.size).max + flatItemsPredicatePairs.map { case (items, ruleP) => + (items.padTo(maxLength, unitK), ruleP) + } } else { klistPredicatePairs } - val setOfLists: Set[Seq[(K, K)]] = normalizedItemsPredicatePairs map { case (items, ruleP) => items.map((_, ruleP)) } - val childrenDisjunctionsOfklabel: IndexedSeq[K] = - setOfLists.head.indices - .map(i => setOfLists.map(l => l(i))) - .map(pushDisjunction) - val rulePs = ks map {_._2} toSeq - - (KApply(klabel,childrenDisjunctionsOfklabel: _*), KApply(or,rulePs: _*)) + val setOfLists: Set[Seq[(K, K)]] = normalizedItemsPredicatePairs.map { + case (items, ruleP) => items.map((_, ruleP)) + } + val childrenDisjunctionsOfklabel: IndexedSeq[K] = + setOfLists.head.indices + .map(i => setOfLists.map(l => l(i))) + .map(pushDisjunction) + val rulePs = ks.map(_._2) toSeq + + (KApply(klabel, childrenDisjunctionsOfklabel: _*), KApply(or, rulePs: _*)) } - val disjunctionOfVarKApplies: Iterable[(K, K)] = termsWithoutRewrites - .collect({ case (x: KApply, ruleP: K) if x.klabel.isInstanceOf[KVariable] => (x, ruleP) }) - .toIndexedSeq + val disjunctionOfVarKApplies: Iterable[(K, K)] = termsWithoutRewrites.collect { + case (x: KApply, ruleP: K) if x.klabel.isInstanceOf[KVariable] => (x, ruleP) + }.toIndexedSeq - val disjunctionOfOthers: Iterable[(K, K)] = termsWithoutRewrites.filterNot(_._1.isInstanceOf[KApply]) + val disjunctionOfOthers: Iterable[(K, K)] = termsWithoutRewrites + .filterNot(_._1.isInstanceOf[KApply]) .groupBy(_._1) - .map({ case (k, set) => (k, set.map(_._2)) }) - .map({ case (k, rulePs) => (k, makeOr(rulePs.toSeq: _*)) }) + .map { case (k, set) => (k, set.map(_._2)) } + .map { case (k, rulePs) => (k, makeOr(rulePs.toSeq: _*)) } - val entireDisjunction: Iterable[(K, K)] = disjunctionOfKApplies ++ disjunctionOfVarKApplies ++ disjunctionOfOthers - val theLHS = if (entireDisjunction.size == 1) - entireDisjunction.head._1 - else - makeOr(entireDisjunction.map({ case (a, b) => KApply(and,a, b) }).toSeq: _*) + val entireDisjunction: Iterable[(K, K)] = + disjunctionOfKApplies ++ disjunctionOfVarKApplies ++ disjunctionOfOthers + val theLHS = + if (entireDisjunction.size == 1) + entireDisjunction.head._1 + else + makeOr(entireDisjunction.map { case (a, b) => KApply(and, a, b) }.toSeq: _*) if (theRewrites.nonEmpty) { - KApply(rwLabel,theLHS, makeOr(theRewrites.map({ case (a, b) => KApply(and,a, b) }).toSeq: _*)) + KApply( + rwLabel, + theLHS, + makeOr(theRewrites.map { case (a, b) => KApply(and, a, b) }.toSeq: _*) + ) } else { theLHS } } - private def isEffectiveAssoc(kLabel: KLabel, module: Module) : Boolean = { - module.attributesFor.getOrElse(kLabel, Att.empty).contains(Att.ASSOC) && (!module.attributesFor.getOrElse(kLabel, Att.empty).contains(Att.COMM)) || module.attributesFor.getOrElse(kLabel, Att.empty).contains(Att.BAG) - } + private def isEffectiveAssoc(kLabel: KLabel, module: Module): Boolean = + module.attributesFor.getOrElse(kLabel, Att.empty).contains(Att.ASSOC) && (!module.attributesFor + .getOrElse(kLabel, Att.empty) + .contains(Att.COMM)) || module.attributesFor.getOrElse(kLabel, Att.empty).contains(Att.BAG) } diff --git a/kore/src/main/scala/org/kframework/compile/NormalizeAssoc.scala b/kore/src/main/scala/org/kframework/compile/NormalizeAssoc.scala index 9425dba3ab8..7bfaf8d2f6c 100644 --- a/kore/src/main/scala/org/kframework/compile/NormalizeAssoc.scala +++ b/kore/src/main/scala/org/kframework/compile/NormalizeAssoc.scala @@ -1,16 +1,17 @@ // Copyright (c) K Team. All Rights Reserved. package org.kframework.compile -import org.kframework.Collections._ import org.kframework.attributes.Att -import org.kframework.definition.{Module, Rule, Sentence} +import org.kframework.definition.Module +import org.kframework.definition.Rule +import org.kframework.definition.Sentence import org.kframework.kore._ - +import org.kframework.Collections._ /** * Compiler pass flattening associative collections */ -class NormalizeAssoc(c: Constructors) extends ((Module, Sentence )=> Sentence) { +class NormalizeAssoc(c: Constructors) extends ((Module, Sentence) => Sentence) { import c._ @@ -23,31 +24,37 @@ class NormalizeAssoc(c: Constructors) extends ((Module, Sentence )=> Sentence) { def apply(k: K)(implicit m: Module): K = k match { case kApply: KApply => if (m.attributesFor.getOrElse(kApply.klabel, Att.empty).contains(Att.ASSOC)) { - val opKLabel: KLabel = kApply.klabel + val opKLabel: KLabel = kApply.klabel val unitKLabel: KLabel = KLabel(m.attributesFor(opKLabel).get(Att.UNIT)) - val flattenChildren = flatten(kApply, opKLabel, unitKLabel) - if (flattenChildren exists {_.isInstanceOf[KRewrite]}) { + val flattenChildren = flatten(kApply, opKLabel, unitKLabel) + if (flattenChildren.exists(_.isInstanceOf[KRewrite])) { KRewrite( - KApply(opKLabel, KList(flatten(RewriteToTop.toLeft(k), opKLabel, unitKLabel) map apply: _*), kApply.att), + KApply( + opKLabel, + KList(flatten(RewriteToTop.toLeft(k), opKLabel, unitKLabel).map(apply): _*), + kApply.att + ), RewriteToTop.toRight(k), - Att.empty) + Att.empty + ) } else { - KApply(opKLabel, KList(flattenChildren map apply: _*), kApply.att) + KApply(opKLabel, KList(flattenChildren.map(apply): _*), kApply.att) } } else { - KApply(kApply.klabel, KList(immutable(kApply.klist.items) map apply: _*), kApply.att) + KApply(kApply.klabel, KList(immutable(kApply.klist.items).map(apply): _*), kApply.att) } case kRewrite: KRewrite => KRewrite(apply(kRewrite.left), kRewrite.right, kRewrite.att) - case _ => k + case _ => k } def flatten(k: K, op: KLabel, unit: KLabel): Seq[K] = k match { case Unapply.KApply(`op`, children: List[K]) => - children flatMap {flatten(_, op, unit)} + children.flatMap(flatten(_, op, unit)) case Unapply.KApply(`unit`, List()) => Seq() - //case kRewrite: KRewrite => - // (flatten(kRewrite.left, op, unit) map {KRewrite(_, KApply(unit), kRewrite.att)}) :+ KRewrite(KApply(unit), kRewrite.right, kRewrite.att) + // case kRewrite: KRewrite => + // (flatten(kRewrite.left, op, unit) map {KRewrite(_, KApply(unit), kRewrite.att)}) :+ + // KRewrite(KApply(unit), kRewrite.right, kRewrite.att) case _ => Seq(k) } diff --git a/kore/src/main/scala/org/kframework/compile/NormalizeKSeq.scala b/kore/src/main/scala/org/kframework/compile/NormalizeKSeq.scala index 6d308a7f45c..f238832ae71 100644 --- a/kore/src/main/scala/org/kframework/compile/NormalizeKSeq.scala +++ b/kore/src/main/scala/org/kframework/compile/NormalizeKSeq.scala @@ -1,36 +1,35 @@ // Copyright (c) K Team. All Rights Reserved. package org.kframework.compile -import org.kframework.Collections._ import org.kframework.builtin.KLabels -import org.kframework.kore.KORE._ import org.kframework.kore._ +import org.kframework.kore.KORE._ +import org.kframework.Collections._ /** - * Assumes KSequences are KApplys and puts them in right-assoc normal form - */ + * Assumes KSequences are KApplys and puts them in right-assoc normal form + */ object NormalizeKSeq extends (K => K) { val self = this val dotk = KLabels.DOTK val kseq = KLabels.KSEQ - def apply(k: K): K = { + def apply(k: K): K = k match { case app: KApply => - val convertedK: K = KApply(app.klabel, immutable(app.klist.items) map apply, app.att) + val convertedK: K = KApply(app.klabel, immutable(app.klist.items).map(apply), app.att) if (app.klabel == kseq) normalize(convertedK) else convertedK case rw: KRewrite => KRewrite(apply(rw.left), apply(rw.right), rw.att) - case other => other + case other => other } - } def normalize(k: K): K = { val s: Seq[K] = Assoc.flatten(kseq, Seq(k), dotk) (s.last match { case Unapply.KApply(`dotk`, _) => s - case kvar: KVariable => s - case _ => s :+ KApply(dotk) + case kvar: KVariable => s + case _ => s :+ KApply(dotk) }).reduceRight((a, b) => kseq(a, b)) } } diff --git a/kore/src/main/scala/org/kframework/compile/RewriteToTop.scala b/kore/src/main/scala/org/kframework/compile/RewriteToTop.scala index 952bc91c32f..451b9c41cb0 100644 --- a/kore/src/main/scala/org/kframework/compile/RewriteToTop.scala +++ b/kore/src/main/scala/org/kframework/compile/RewriteToTop.scala @@ -1,81 +1,91 @@ // Copyright (c) K Team. All Rights Reserved. package org.kframework.compile -import org.kframework.Collections._ -import org.kframework.kore.KORE.{KApply, KAs, KSequence, KLabel} -import org.kframework.kore.{KRewrite, _} -import org.kframework.utils.errorsystem.KEMException; - +import org.kframework.kore._ +import org.kframework.kore.KORE.KApply +import org.kframework.kore.KORE.KAs +import org.kframework.kore.KORE.KLabel +import org.kframework.kore.KORE.KSequence +import org.kframework.kore.KRewrite +import org.kframework.utils.errorsystem.KEMException +import org.kframework.Collections._; object RewriteToTop { def toLeft(rewrite: K): K = rewrite match { case t: KRewrite => t.left - case t: KApply => compactInjections(KApply(t.klabel, immutable(t.klist.items) map toLeft, t.att)) - case t: KSequence => KSequence(mutable(immutable(t.items) map toLeft toList), t.att) - case t: KAs => KAs(toLeft(t.pattern), t.alias, t.att) - case other => other + case t: KApply => + compactInjections(KApply(t.klabel, immutable(t.klist.items).map(toLeft), t.att)) + case t: KSequence => KSequence(mutable(immutable(t.items).map(toLeft) toList), t.att) + case t: KAs => KAs(toLeft(t.pattern), t.alias, t.att) + case other => other } def toRight(rewrite: K): K = rewrite match { case t: KRewrite => toRight(t.right) // recurse here because of KAs - case t: KApply => compactInjections(KApply(t.klabel, immutable(t.klist.items) map toRight, t.att)) - case t: KSequence => KSequence(mutable(immutable(t.items) map toRight toList), t.att) - case t: KAs => t.alias - case other => other + case t: KApply => + compactInjections(KApply(t.klabel, immutable(t.klist.items).map(toRight), t.att)) + case t: KSequence => KSequence(mutable(immutable(t.items).map(toRight) toList), t.att) + case t: KAs => t.alias + case other => other } - def bubbleRewriteToTopInsideCells(k: K): K = k match { case kapp: KApply => if (isCell(kapp) && nonCell(kapp.items.get(0))) - KApply(kapp.klabel, immutable(kapp.klist.items) map makeRewriteIfNeeded, kapp.att) + KApply(kapp.klabel, immutable(kapp.klist.items).map(makeRewriteIfNeeded), kapp.att) else - KApply(kapp.klabel, immutable(kapp.klist.items) map bubbleRewriteToTopInsideCells, kapp.att) + KApply( + kapp.klabel, + immutable(kapp.klist.items).map(bubbleRewriteToTopInsideCells), + kapp.att + ) case _ => k } - def nonCell(k: K): Boolean = k match { - case kapp: KApply => if (!isCell(kapp)) { - immutable(kapp.klist.items) map nonCell forall { b => b } - } else { - false - } + case kapp: KApply => + if (!isCell(kapp)) { + immutable(kapp.klist.items).map(nonCell).forall(b => b) + } else { + false + } case rw: KRewrite => nonCell(rw.left) && nonCell(rw.right) - case _ => true + case _ => true } def hasRewrite(k: K): Boolean = k match { - case t: KRewrite => true - case t: KApply => immutable(t.klist.items).foldLeft(false)((b,k) => b || hasRewrite(k)) - case t: KSequence => immutable(t.items).foldLeft(false)((b,k) => b || hasRewrite(k)) - case other => false + case t: KRewrite => true + case t: KApply => immutable(t.klist.items).foldLeft(false)((b, k) => b || hasRewrite(k)) + case t: KSequence => immutable(t.items).foldLeft(false)((b, k) => b || hasRewrite(k)) + case other => false } - private def isCell(kapp: KApply): Boolean = { + private def isCell(kapp: KApply): Boolean = kapp.klabel.name.startsWith("<") && kapp.klabel.name.endsWith(">") - } - private def makeRewriteIfNeeded(k: K): K = if (toLeft(k) != toRight(k)) ADT.KRewrite(toLeft(k), toRight(k)) else k + private def makeRewriteIfNeeded(k: K): K = + if (toLeft(k) != toRight(k)) ADT.KRewrite(toLeft(k), toRight(k)) else k private def compactInjections(k: K): K = k match { case kapp: KApply => val args: Seq[K] = immutable(kapp.klist.items) if (isInjection(kapp) && args.length == 1 && isInjection(args.head)) { - val kappInner: KApply = args.head.asInstanceOf[KApply] + val kappInner: KApply = args.head.asInstanceOf[KApply] val sortsOuter: List[Sort] = kapp.klabel.params.toList val sortsInner: List[Sort] = kappInner.klabel.params.toList if (sortsOuter.length != 2 || sortsInner.length != 2) { throw KEMException.internalError( - "Injection compaction error: found injection with more than two sort parameters") + "Injection compaction error: found injection with more than two sort parameters" + ) } - val sortOuterIn: Sort = sortsOuter.head + val sortOuterIn: Sort = sortsOuter.head val sortOuterOut: Sort = sortsOuter.last - val sortInnerIn: Sort = sortsInner.head + val sortInnerIn: Sort = sortsInner.head val sortInnerOut: Sort = sortsInner.last if (sortInnerOut != sortOuterIn) { throw KEMException.internalError( - "Injection compaction error: found nested injections with incompatible sorts") + "Injection compaction error: found nested injections with incompatible sorts" + ) } KApply(KLabel("inj", List(sortInnerIn, sortOuterOut): _*), kappInner.klist, kapp.att) } else { @@ -86,7 +96,7 @@ object RewriteToTop { private def isInjection(k: K): Boolean = k match { case kapp: KApply => kapp.klabel.name == "inj" - case other => false + case other => false } } diff --git a/kore/src/main/scala/org/kframework/definition/Constructors.scala b/kore/src/main/scala/org/kframework/definition/Constructors.scala index de99341ec76..3027476cca5 100644 --- a/kore/src/main/scala/org/kframework/definition/Constructors.scala +++ b/kore/src/main/scala/org/kframework/definition/Constructors.scala @@ -2,18 +2,15 @@ package org.kframework.definition +import collection._ import java.util.Optional - +import org.kframework.attributes import org.kframework.attributes.Att -import org.kframework.{attributes, definition} +import org.kframework.definition import org.kframework.kore._ -import collection._ /** - * - * Helper constructors for KORE definition.classes. The class is meant to be imported - * statically. - * + * Helper constructors for KORE definition.classes. The class is meant to be imported statically. */ object Constructors { @@ -28,45 +25,71 @@ object Constructors { definition.Module(name, imports, sentences, att) def SyntaxSort(params: Seq[Sort], sort: Sort) = definition.SyntaxSort(params, sort) - def SyntaxSort(params: Seq[Sort], sort: Sort, att: attributes.Att) = definition.SyntaxSort(params, sort, att) + def SyntaxSort(params: Seq[Sort], sort: Sort, att: attributes.Att) = + definition.SyntaxSort(params, sort, att) def SortSynonym(newSort: Sort, oldSort: Sort) = definition.SortSynonym(newSort, oldSort) - def SortSynonym(newSort: Sort, oldSort: Sort, att: attributes.Att) = definition.SortSynonym(newSort, oldSort, att) + def SortSynonym(newSort: Sort, oldSort: Sort, att: attributes.Att) = + definition.SortSynonym(newSort, oldSort, att) def SyntaxLexical(name: String, regex: String) = definition.SyntaxLexical(name, regex) - def SyntaxLexical(name: String, regex: String, att: attributes.Att) = definition.SyntaxLexical(name, regex, att) - - def Production(params: Seq[Sort], sort: Sort, items: Seq[ProductionItem]) = definition.Production(params, sort, items, Att.empty) - def Production(params: Seq[Sort], sort: Sort, items: Seq[ProductionItem], att: attributes.Att) = definition.Production(params, sort, items, att) - def Production(klabel: KLabel, sort: Sort, items: Seq[ProductionItem]) = definition.Production(klabel, klabel.params, sort, items) - def Production(klabel: KLabel, sort: Sort, items: Seq[ProductionItem], att: attributes.Att) = definition.Production(klabel, klabel.params, sort, items, att) - def Production(klabel: Option[KLabel], params: Seq[Sort], sort: Sort, items: Seq[ProductionItem]) = definition.Production(klabel, params, sort, items, Att.empty) - def Production(klabel: Option[KLabel], params: Seq[Sort], sort: Sort, items: Seq[ProductionItem], att: attributes.Att) = definition.Production(klabel, params, sort, items, att) - - def Terminal(s: String) = definition.Terminal(s) - def NonTerminal(sort: Sort) = definition.NonTerminal(sort, None) + def SyntaxLexical(name: String, regex: String, att: attributes.Att) = + definition.SyntaxLexical(name, regex, att) + + def Production(params: Seq[Sort], sort: Sort, items: Seq[ProductionItem]) = + definition.Production(params, sort, items, Att.empty) + def Production(params: Seq[Sort], sort: Sort, items: Seq[ProductionItem], att: attributes.Att) = + definition.Production(params, sort, items, att) + def Production(klabel: KLabel, sort: Sort, items: Seq[ProductionItem]) = + definition.Production(klabel, klabel.params, sort, items) + def Production(klabel: KLabel, sort: Sort, items: Seq[ProductionItem], att: attributes.Att) = + definition.Production(klabel, klabel.params, sort, items, att) + def Production( + klabel: Option[KLabel], + params: Seq[Sort], + sort: Sort, + items: Seq[ProductionItem] + ) = definition.Production(klabel, params, sort, items, Att.empty) + def Production( + klabel: Option[KLabel], + params: Seq[Sort], + sort: Sort, + items: Seq[ProductionItem], + att: attributes.Att + ) = definition.Production(klabel, params, sort, items, att) + + def Terminal(s: String) = definition.Terminal(s) + def NonTerminal(sort: Sort) = definition.NonTerminal(sort, None) def NonTerminal(sort: Sort, name: Option[String]) = definition.NonTerminal(sort, name) def RegexTerminal(regexString: String) = definition.RegexTerminal("#", regexString, "#") - def RegexTerminal(precedeRegexString: String, regexString: String, followRegexString: String) = definition.RegexTerminal(precedeRegexString, regexString, followRegexString) + def RegexTerminal(precedeRegexString: String, regexString: String, followRegexString: String) = + definition.RegexTerminal(precedeRegexString, regexString, followRegexString) def Tag(s: String) = definition.Tag(s) def SyntaxPriority(priorities: Seq[Set[Tag]]) = definition.SyntaxPriority(priorities) - def SyntaxPriority(priorities: Seq[Set[Tag]], att: attributes.Att) = definition.SyntaxPriority(priorities, att) + def SyntaxPriority(priorities: Seq[Set[Tag]], att: attributes.Att) = + definition.SyntaxPriority(priorities, att) - def SyntaxAssociativity(assoc: definition.Associativity, tags: Set[Tag]) = definition.SyntaxAssociativity(assoc, tags) - def SyntaxAssociativity(assoc: definition.Associativity, tags: Set[Tag], att: attributes.Att) = definition.SyntaxAssociativity(assoc, tags, att) + def SyntaxAssociativity(assoc: definition.Associativity, tags: Set[Tag]) = + definition.SyntaxAssociativity(assoc, tags) + def SyntaxAssociativity(assoc: definition.Associativity, tags: Set[Tag], att: attributes.Att) = + definition.SyntaxAssociativity(assoc, tags, att) def Context(content: K, requires: K) = definition.Context(content, requires) - def Context(content: K, requires: K, att: attributes.Att) = definition.Context(content, requires, att) + def Context(content: K, requires: K, att: attributes.Att) = + definition.Context(content, requires, att) def ContextAlias(content: K, requires: K) = definition.ContextAlias(content, requires) - def ContextAlias(content: K, requires: K, att: attributes.Att) = definition.ContextAlias(content, requires, att) + def ContextAlias(content: K, requires: K, att: attributes.Att) = + definition.ContextAlias(content, requires, att) - def Claim(body: K, requires: K, ensures: K, att: attributes.Att) = definition.Claim(body, requires, ensures, att) + def Claim(body: K, requires: K, ensures: K, att: attributes.Att) = + definition.Claim(body, requires, ensures, att) def Claim(body: K, requires: K, ensures: K) = definition.Claim(body, requires, ensures, Att.empty) - def Rule(body: K, requires: K, ensures: K, att: attributes.Att) = definition.Rule(body, requires, ensures, att) + def Rule(body: K, requires: K, ensures: K, att: attributes.Att) = + definition.Rule(body, requires, ensures, att) def Rule(body: K, requires: K, ensures: K) = definition.Rule(body, requires, ensures, Att.empty) def Bubble(sentenceType: String, content: String, att: attributes.Att) = @@ -74,5 +97,6 @@ object Constructors { // EXTRA - def Configuration(body: K, ensures: K, att: attributes.Att) = definition.Configuration(body, ensures, att) + def Configuration(body: K, ensures: K, att: attributes.Att) = + definition.Configuration(body, ensures, att) } diff --git a/kore/src/main/scala/org/kframework/definition/outer-ext.scala b/kore/src/main/scala/org/kframework/definition/outer-ext.scala index 5ecb1ac98e0..3d9f95dc907 100644 --- a/kore/src/main/scala/org/kframework/definition/outer-ext.scala +++ b/kore/src/main/scala/org/kframework/definition/outer-ext.scala @@ -2,71 +2,93 @@ package org.kframework.definition +import java.util.Optional import javax.annotation.Nonnull -import org.kframework.kore._ import org.kframework.attributes._ +import org.kframework.kore._ import org.kframework.utils.errorsystem.KEMException - import scala.annotation.meta.param -import scala.collection.Set import scala.collection.mutable -import java.util.Optional +import scala.collection.Set -case class Configuration(body: K, ensures: K, att: Att = Att.empty) extends Sentence with OuterKORE { - override val isSyntax = true - override val isNonSyntax = true +case class Configuration(body: K, ensures: K, att: Att = Att.empty) + extends Sentence + with OuterKORE { + override val isSyntax = true + override val isNonSyntax = true override def withAtt(att: Att) = Configuration(body, ensures, att) } case class Bubble(sentenceType: String, contents: String, att: Att = Att.empty) extends Sentence { - override val isSyntax = sentenceType == "config" || sentenceType == "alias" - override val isNonSyntax = sentenceType != "alias" + override val isSyntax = sentenceType == "config" || sentenceType == "alias" + override val isNonSyntax = sentenceType != "alias" override def withAtt(att: Att) = Bubble(sentenceType, contents, att) } case class FlatImport(name: String, isPublic: Boolean, att: Att = Att.empty) extends HasLocation { override def location(): Optional[Location] = att.getOptional(classOf[Location]) - override def source(): Optional[Source] = att.getOptional(classOf[Source]) + override def source(): Optional[Source] = att.getOptional(classOf[Source]) } -case class FlatModule(name: String, imports: Set[FlatImport], localSentences: Set[Sentence], @(Nonnull@param) val att: Att = Att.empty) - extends OuterKORE with Sorting with Serializable { -} +case class FlatModule( + name: String, + imports: Set[FlatImport], + localSentences: Set[Sentence], + @(Nonnull @param) val att: Att = Att.empty +) extends OuterKORE + with Sorting + with Serializable {} object FlatModule { - def apply(name: String, unresolvedLocalSentences: Set[Sentence]): FlatModule = { + def apply(name: String, unresolvedLocalSentences: Set[Sentence]): FlatModule = new FlatModule(name, Set(), unresolvedLocalSentences, Att.empty) - } /** - * Gets a list of {@link FlatModule} and returns a set of {@link Module}. - * @param allModules List of FlatModules to be transformed. The order matters when reporting circular imports. - * @param previousModules A set of Modules already built. New modules will be added to this set. - * @return The set of Modules, directly connected and maximally shared. + * Gets a list of {@link FlatModule} and returns a set of {@link Module} . + * @param allModules + * List of FlatModules to be transformed. The order matters when reporting circular imports. + * @param previousModules + * A set of Modules already built. New modules will be added to this set. + * @return + * The set of Modules, directly connected and maximally shared. */ - def toModules(allModules:Seq[FlatModule], previousModules:Set[Module]):Set[Module] = { - val memoization:mutable.HashMap[String, Module] = collection.mutable.HashMap[String, Module]() + def toModules(allModules: Seq[FlatModule], previousModules: Set[Module]): Set[Module] = { + val memoization: mutable.HashMap[String, Module] = collection.mutable.HashMap[String, Module]() previousModules.map(m => memoization.put(m.name, m)) - def toModuleRec(m:FlatModule, visitedModules: Seq[FlatModule]):Module = { + def toModuleRec(m: FlatModule, visitedModules: Seq[FlatModule]): Module = { if (visitedModules.contains(m)) { var msg = "Found circularity in module imports: " visitedModules.reverse.foreach(m => msg += m.name + " < ") msg += visitedModules.last.name throw KEMException.compilerError(msg) } - memoization.getOrElseUpdate(m.name, { - // transform all imports into Module - val f = (i: FlatImport) => Import(memoization.getOrElse(i.name - // if can't find the Module in memoization, build a new one - , toModuleRec(allModules.find(f => f.name.equals(i.name)) - .getOrElse(throw KEMException.compilerError("Could not find module: " + i.name, i)) - , visitedModules :+ m)), i.isPublic) - val newImports = m.imports.map(f) - val newM = new Module(m.name, newImports, m.localSentences, m.att) - newM.checkSorts() - newM.checkUserLists() - newM - }) + memoization.getOrElseUpdate( + m.name, { + // transform all imports into Module + val f = (i: FlatImport) => + Import( + memoization.getOrElse( + i.name + // if can't find the Module in memoization, build a new one + , + toModuleRec( + allModules + .find(f => f.name.equals(i.name)) + .getOrElse( + throw KEMException.compilerError("Could not find module: " + i.name, i) + ), + visitedModules :+ m + ) + ), + i.isPublic + ) + val newImports = m.imports.map(f) + val newM = new Module(m.name, newImports, m.localSentences, m.att) + newM.checkSorts() + newM.checkUserLists() + newM + } + ) } allModules.map(m => toModuleRec(m, Seq())) memoization.values.toSet diff --git a/kore/src/main/scala/org/kframework/definition/outer-to-string.scala b/kore/src/main/scala/org/kframework/definition/outer-to-string.scala index 074820b90ad..db25c936381 100644 --- a/kore/src/main/scala/org/kframework/definition/outer-to-string.scala +++ b/kore/src/main/scala/org/kframework/definition/outer-to-string.scala @@ -1,21 +1,21 @@ // Copyright (c) K Team. All Rights Reserved. package org.kframework.definition -import org.kframework.attributes.{Location,Source} -import org.kframework.utils.StringUtil import collection._ +import org.kframework.attributes.Location +import org.kframework.attributes.Source +import org.kframework.utils.StringUtil trait ModuleToString { self: Module => override def toString = "module " + name + att.postfixString + "\n" + - prettyPrintSet(fullImports map {"imports " + _.name}) + + prettyPrintSet(fullImports.map("imports " + _.name)) + prettyPrintSet(localSentences) + "endmodule" - def prettyPrintSet(s: Set[_]) = { + def prettyPrintSet(s: Set[_]) = s.toList.map(_.toString).sorted.reverse.map(" " + _).mkString("\n") + (if (s.size > 0) "\n" else "") - } } trait DefinitionToString { @@ -25,17 +25,21 @@ trait DefinitionToString { trait RuleToString { self: Rule => - override def toString = Seq("rule", body, "requires", requires, "ensures", ensures, att).mkString(" ") + override def toString = + Seq("rule", body, "requires", requires, "ensures", ensures, att).mkString(" ") } trait ClaimToString { self: Claim => - override def toString = Seq("claim", body, "requires", requires, "ensures", ensures, att).mkString(" ") + override def toString = + Seq("claim", body, "requires", requires, "ensures", ensures, att).mkString(" ") } trait ProductionToString { self: Production => - override def toString = "syntax " + (if (params.nonEmpty) { "{" + params.mkString(", ") + "} " } else "") + sort + " ::= " + items.mkString(" ") + att.remove(classOf[Source]).remove(classOf[Location]).postfixString + override def toString = "syntax " + (if (params.nonEmpty) { "{" + params.mkString(", ") + "} " } + else "") + sort + " ::= " + items + .mkString(" ") + att.remove(classOf[Source]).remove(classOf[Location]).postfixString } trait SyntaxSortToString { @@ -50,7 +54,8 @@ trait SortSynonymToString { trait SyntaxLexicalToString { self: SyntaxLexical => - override def toString() = "syntax lexical " + name + " = r" + StringUtil.enquoteKString(regex) + att.postfixString + override def toString() = + "syntax lexical " + name + " = r" + StringUtil.enquoteKString(regex) + att.postfixString } trait TerminalToString { @@ -65,21 +70,20 @@ trait NonTerminalToString { trait RegexTerminalToString { self: RegexTerminal => - override def toString = { + override def toString = "r" + StringUtil.enquoteKString( - (if ("#" == precedeRegex) "" else "(? override def toString = { val assocString = assoc match { - case Associativity.Left => "left" - case Associativity.Right => "right" + case Associativity.Left => "left" + case Associativity.Right => "right" case Associativity.NonAssoc => "non-assoc" } "syntax associativity " + assocString + " " + tags.mkString(" ") + att.postfixString @@ -98,7 +102,7 @@ trait ContextAliasToString { trait SyntaxPriorityToString { self: SyntaxPriority => - override def toString = "syntax priority " + priorities.map {_.mkString(" ")}.mkString(" > ") + override def toString = "syntax priority " + priorities.map(_.mkString(" ")).mkString(" > ") } trait TagToString { diff --git a/kore/src/main/scala/org/kframework/definition/outer.scala b/kore/src/main/scala/org/kframework/definition/outer.scala index 6931bc8914b..81673ae59b0 100644 --- a/kore/src/main/scala/org/kframework/definition/outer.scala +++ b/kore/src/main/scala/org/kframework/definition/outer.scala @@ -2,33 +2,30 @@ package org.kframework.definition +import dk.brics.automaton.RegExp +import dk.brics.automaton.RunAutomaton +import dk.brics.automaton.SpecialOperations import java.util.Optional -import java.lang.Comparable import javax.annotation.Nonnull - -import dk.brics.automaton.{BasicAutomata, RegExp, RunAutomaton, SpecialOperations} -import org.kframework.POSet -import org.kframework.attributes.{Att, AttValue, HasLocation, Location, Source} +import org.kframework.attributes._ +import org.kframework.builtin.Sorts import org.kframework.definition.Constructors._ -import org.kframework.kore.Unapply.{KApply, KLabel} -import org.kframework.kore -import org.kframework.kore.KORE.Sort import org.kframework.kore._ +import org.kframework.kore.KORE.Sort import org.kframework.utils.errorsystem.KEMException -import org.kframework.builtin.Sorts - +import org.kframework.POSet import scala.annotation.meta.param +import scala.collection._ import scala.collection.JavaConverters._ -import collection._ import scala.collection.Set trait OuterKORE case class NonTerminalsWithUndefinedSortException(nonTerminals: Set[NonTerminal]) - extends AssertionError(nonTerminals.toString()) + extends AssertionError(nonTerminals.toString()) case class DivergingAttributesForTheSameKLabel(ps: Set[Production]) - extends AssertionError(ps.toString) + extends AssertionError(ps.toString) //object NonTerminalsWithUndefinedSortException { // def apply(nonTerminals: Set[NonTerminal]) = @@ -36,121 +33,139 @@ case class DivergingAttributesForTheSameKLabel(ps: Set[Production]) // //} -case class Definition( - mainModule: Module, - entryModules: Set[Module], - att: Att) - extends DefinitionToString with OuterKORE with AttValue { +case class Definition(mainModule: Module, entryModules: Set[Module], att: Att) + extends DefinitionToString + with OuterKORE + with AttValue { private def allModules(m: Module): Set[Module] = m.importedModules + m - lazy val modules = entryModules flatMap allModules + lazy val modules = entryModules.flatMap(allModules) - def getModule(name: String): Option[Module] = modules find { case m: Module => m.name == name; case _ => false } + def getModule(name: String): Option[Module] = modules.find { + case m: Module => m.name == name; case _ => false + } override def hashCode = mainModule.hashCode override def equals(that: Any) = that match { case Definition(`mainModule`, `entryModules`, _) => true - case _ => false + case _ => false } - def parMap(f: Module => Module): java.util.Map[String, Module] = { - (entryModules | entryModules.flatMap(_.importedModules)).par.map(f).seq.map(m => m.name -> m).toMap.asJava - } + def parMap(f: Module => Module): java.util.Map[String, Module] = + (entryModules | entryModules + .flatMap(_.importedModules)).par.map(f).seq.map(m => m.name -> m).toMap.asJava } trait Sorting { def computeSubsortPOSet(sentences: Set[Sentence], syntactic: Boolean) = { - val subsortRelations: Set[(Sort, Sort)] = sentences collect { - case Production(klabel, Seq(), endSort, Seq(NonTerminal(startSort, _)), att) if klabel.isEmpty || syntactic => (startSort, endSort) + val subsortRelations: Set[(Sort, Sort)] = sentences.collect { + case Production(klabel, Seq(), endSort, Seq(NonTerminal(startSort, _)), att) + if klabel.isEmpty || syntactic => + (startSort, endSort) } POSet(subsortRelations) } def computeOverloadPOSet(subsorts: POSet[Sort], prods: Set[Production]): POSet[Production] = { - def isLessThan(p1: Production, p2: Production): Boolean = { - p1.klabel.isDefined && + def isLessThan(p1: Production, p2: Production): Boolean = + p1.klabel.isDefined && p1.klabelAtt == p2.klabelAtt && p1.nonterminals.size == p2.nonterminals.size && subsorts.lessThanEq(p1.sort, p2.sort) && - p1.nonterminals.zip(p2.nonterminals).forall(pair => subsorts.lessThanEq(pair._1.sort, pair._2.sort)) && + p1.nonterminals + .zip(p2.nonterminals) + .forall(pair => subsorts.lessThanEq(pair._1.sort, pair._2.sort)) && (p1.sort != p2.sort || p1.nonterminals.map(_.sort) != p2.nonterminals.map(_.sort)) && p1 != p2 - } val prodsForOverloads = prods.toSeq.filter(_.klabelAtt.isDefined).groupBy(_.klabelAtt) - val pairs: Iterable[(Production, Production)] = for (x <- prodsForOverloads.values; p1 <- x; p2 <- x; if isLessThan(p1, p2)) yield (p1, p2) + val pairs: Iterable[(Production, Production)] = for { + x <- prodsForOverloads.values + p1 <- x + p2 <- x if isLessThan(p1, p2) + } yield (p1, p2) POSet(pairs.toSet) } } object Module { - def apply(name: String, unresolvedLocalSentences: Set[Sentence]): Module = { + def apply(name: String, unresolvedLocalSentences: Set[Sentence]): Module = new Module(name, Set(), unresolvedLocalSentences, Att.empty) - } } case class Import(val module: Module, val isPublic: Boolean) -case class Module(val name: String, val imports: Set[Import], localSentences: Set[Sentence], @(Nonnull@param) val att: Att = Att.empty) - extends ModuleToString with OuterKORE with Sorting with Serializable with AttValue { +case class Module( + val name: String, + val imports: Set[Import], + localSentences: Set[Sentence], + @(Nonnull @param) val att: Att = Att.empty +) extends ModuleToString + with OuterKORE + with Sorting + with Serializable + with AttValue { assert(att != null) lazy val fullImports: Set[Module] = imports.map(_.module) - private lazy val importedSentences = fullImports flatMap {_.sentences} + private lazy val importedSentences = fullImports.flatMap(_.sentences) lazy val sentences: Set[Sentence] = localSentences | importedSentences - lazy val labeled: Map[String, Set[Sentence]] = sentences.filter(_.label.isPresent).groupBy(_.label.get) + lazy val labeled: Map[String, Set[Sentence]] = + sentences.filter(_.label.isPresent).groupBy(_.label.get) /** All the imported modules, calculated recursively. */ - lazy val importedModules: Set[Module] = fullImports | (fullImports flatMap { + lazy val importedModules: Set[Module] = fullImports | (fullImports.flatMap { _.importedModules }) lazy val importedModuleNames: Set[String] = importedModules.map(_.name) - lazy val productions: Set[Production] = sentences collect { case p: Production => p } + lazy val productions: Set[Production] = sentences.collect { case p: Production => p } - lazy val publicSentences: Set[Sentence] = { + lazy val publicSentences: Set[Sentence] = if (att.contains(Att.PRIVATE)) { localSentences.filter(_.att.contains(Att.PUBLIC)) } else { localSentences.filter(!_.att.contains(Att.PRIVATE)) } - } lazy val signature: Module = { - val f = ModuleTransformer.from(m => Module(m.name, m.imports.filter(_.isPublic), m.publicSentences, m.att), "compute module signature") + val f = ModuleTransformer.from( + m => Module(m.name, m.imports.filter(_.isPublic), m.publicSentences, m.att), + "compute module signature" + ) Module(name, imports.map(i => Import(f(i.module), i.isPublic)), localSentences, att) } - lazy val functions: Set[KLabel] = productions.filter(_.att.contains(Att.FUNCTION)).map(_.klabel.get.head) + lazy val functions: Set[KLabel] = + productions.filter(_.att.contains(Att.FUNCTION)).map(_.klabel.get.head) - def isFunction(t: K): Boolean = { + def isFunction(t: K): Boolean = t match { - case Unapply.KApply(lbl, _) if functions(lbl) => true + case Unapply.KApply(lbl, _) if functions(lbl) => true case Unapply.KRewrite(Unapply.KApply(lbl, _), _) if functions(lbl) => true - case _ => false + case _ => false } - } lazy val sortedProductions: Seq[Production] = productions.toSeq.sorted - lazy val localProductions: Set[Production] = localSentences collect { case p: Production => p } + lazy val localProductions: Set[Production] = localSentences.collect { case p: Production => p } lazy val productionsFor: Map[KLabel, Set[Production]] = productions - .collect({ case p if p.klabel != None => p }) + .collect { case p if p.klabel != None => p } .groupBy(_.klabel.get.head) .map { case (l, ps) => (l, ps) } lazy val localProductionsFor: Map[KLabel, Set[Production]] = localProductions - .collect({ case p if p.klabel != None => p }) + .collect { case p if p.klabel != None => p } .groupBy(_.klabel.get) .map { case (l, ps) => (l, ps) } @@ -170,23 +185,29 @@ case class Module(val name: String, val imports: Set[Import], localSentences: Se productionsForSort .get(Sorts.Layout.head) .getOrElse(Set[Production]()) - .collect({ - case Production(_, _, _, Seq(RegexTerminal(_, terminalRegex, _)), _) => terminalRegex - case p => throw KEMException.compilerError("Productions of sort `#Layout` must be exactly one `RegexTerminal`.", p) - }) + .collect { + case Production(_, _, _, Seq(RegexTerminal(_, terminalRegex, _)), _) => terminalRegex + case p => + throw KEMException.compilerError( + "Productions of sort `#Layout` must be exactly one `RegexTerminal`.", + p + ) + } lazy val layout: String = "(" + layouts.mkString(")|(") + ")" @transient lazy val definedKLabels: Set[KLabel] = - (productionsFor.keys.toSet).filter(!_.isInstanceOf[KVariable]).map(_.head) + productionsFor.keys.toSet.filter(!_.isInstanceOf[KVariable]).map(_.head) @transient lazy val localKLabels: Set[KLabel] = - (localProductionsFor.keys.toSet).filter(!_.isInstanceOf[KVariable]) + localProductionsFor.keys.toSet.filter(!_.isInstanceOf[KVariable]) lazy val klabelsDefinedInRules: Map[KLabel, Int] = { - def mergeMultiset(map1: Map[KLabel, Int], map2: Map[KLabel, Int]) = map1 ++ map2.map { case (k, v) => k -> (v + map1.getOrElse(k, 0)) } + def mergeMultiset(map1: Map[KLabel, Int], map2: Map[KLabel, Int]) = map1 ++ map2.map { + case (k, v) => k -> (v + map1.getOrElse(k, 0)) + } val transformer = new FoldK[Map[KLabel, Int]] { override def apply(k: KApply): Map[KLabel, Int] = merge(apply(k.klist), Map((k.klabel, 1))) @@ -197,77 +218,91 @@ case class Module(val name: String, val imports: Set[Import], localSentences: Se def merge(map1: Map[KLabel, Int], map2: Map[KLabel, Int]) = mergeMultiset(map1, map2) } - rules.map(r => { - mergeMultiset(transformer.apply(r.body), mergeMultiset(transformer.apply(r.requires), transformer.apply(r.ensures))) - }).fold(Map())(mergeMultiset) + rules + .map { r => + mergeMultiset( + transformer.apply(r.body), + mergeMultiset(transformer.apply(r.requires), transformer.apply(r.ensures)) + ) + } + .fold(Map())(mergeMultiset) } - lazy val tokenSorts: Set[Sort] = { - sentences.collect({ case p:Production if p.att.contains(Att.TOKEN) => p.sort - case s:SyntaxSort if s.att.contains(Att.TOKEN) => s.sort}) - } + lazy val tokenSorts: Set[Sort] = + sentences.collect { + case p: Production if p.att.contains(Att.TOKEN) => p.sort + case s: SyntaxSort if s.att.contains(Att.TOKEN) => s.sort + } lazy val tokenProductionsFor: Map[Sort, Set[Production]] = productions - .collect({ case p if p.att.contains(Att.TOKEN) => p }) + .collect { case p if p.att.contains(Att.TOKEN) => p } .groupBy(_.sort) .map { case (s, ps) => (s, ps) } - def tokenProductionFor(s: Sort): Production = { + def tokenProductionFor(s: Sort): Production = if (tokenProductionsFor.contains(s)) tokenProductionsFor.apply(s).head else Production(None, Seq(), s, Seq(), Att.empty.add(Att.TOKEN)) - } - lazy val allModuleNames : Set[String] = importedModuleNames + name + lazy val allModuleNames: Set[String] = importedModuleNames + name def importedSentencesExcept(m: Module): Set[Sentence] = - importedModules flatMap { i => if (m.allModuleNames contains i.name) Set.empty[Sentence] else i.localSentences } + importedModules.flatMap { i => + if (m.allModuleNames contains i.name) Set.empty[Sentence] else i.localSentences + } def sentencesExcept(m: Module): Set[Sentence] = importedSentencesExcept(m) | localSentences lazy val bracketProductionsFor: Map[Sort, List[Production]] = productions - .collect({ case p if p.att.contains(Att.BRACKET) => p }) + .collect { case p if p.att.contains(Att.BRACKET) => p } .groupBy(_.sort) .map { case (s, ps) => (s, ps.toList.sortBy(_.sort)(subsorts.asOrdering)) } - @transient lazy val sortFor: Map[KLabel, Sort] = productionsFor mapValues {_.head.sort} + @transient lazy val sortFor: Map[KLabel, Sort] = productionsFor.mapValues(_.head.sort) def isSort(klabel: KLabel, s: Sort): Boolean = subsorts.<(sortFor(klabel), s) - lazy val claims: Set[Claim] = sentences collect { case c: Claim => c } - lazy val rules: Set[Rule] = sentences collect { case r: Rule => r } + lazy val claims: Set[Claim] = sentences.collect { case c: Claim => c } + lazy val rules: Set[Rule] = sentences.collect { case r: Rule => r } lazy val rulesAndClaims: Set[RuleOrClaim] = Set[RuleOrClaim]().++(claims).++(rules) lazy val rulesFor: Map[KLabel, Set[Rule]] = rules.groupBy(r => matchKLabel(r)) - lazy val macroKLabels: Set[KLabel] = macroKLabelsFromRules++macroKLabelsFromProductions - lazy val macroKLabelsFromRules: Set[KLabel] = rules.filter(r => r.isMacro).map(r => matchKLabel(r)) - lazy val macroKLabelsFromProductions: Set[KLabel] = productions.filter(p => p.isMacro).map(p => matchKLabel(p)) + lazy val macroKLabels: Set[KLabel] = macroKLabelsFromRules ++ macroKLabelsFromProductions + lazy val macroKLabelsFromRules: Set[KLabel] = + rules.filter(r => r.isMacro).map(r => matchKLabel(r)) + lazy val macroKLabelsFromProductions: Set[KLabel] = + productions.filter(p => p.isMacro).map(p => matchKLabel(p)) def matchKLabel(r: Rule): KLabel = r.body match { case Unapply.KApply(Unapply.KLabel("#withConfig"), Unapply.KApply(s, _) :: _) => s - case Unapply.KApply(Unapply.KLabel("#withConfig"), Unapply.KRewrite(Unapply.KApply(s, _), _) :: _) => s - case Unapply.KApply(s, _) => s + case Unapply.KApply( + Unapply.KLabel("#withConfig"), + Unapply.KRewrite(Unapply.KApply(s, _), _) :: _ + ) => + s + case Unapply.KApply(s, _) => s case Unapply.KRewrite(Unapply.KApply(s, _), _) => s - case _ => KORE.KLabel("") + case _ => KORE.KLabel("") } private def matchKLabel(p: Production) = p.klabel match { case Some(klabel) => klabel - case _ => KORE.KLabel("") + case _ => KORE.KLabel("") } def ruleLhsHasMacroKLabel(r: Rule): Boolean = r.body match { - case Unapply.KRewrite(Unapply.KApply(l @ Unapply.KLabel(_), _), _) => macroKLabelsFromProductions.contains(l) + case Unapply.KRewrite(Unapply.KApply(l @ Unapply.KLabel(_), _), _) => + macroKLabelsFromProductions.contains(l) case _ => false } - lazy val contexts: Set[Context] = sentences collect { case r: Context => r } + lazy val contexts: Set[Context] = sentences.collect { case r: Context => r } lazy val sortedRules: Seq[Rule] = rules.toSeq.sorted - lazy val localRules: Set[Rule] = localSentences collect { case r: Rule => r } - lazy val localClaims: Set[Claim] = localSentences collect { case r: Claim => r } + lazy val localRules: Set[Rule] = localSentences.collect { case r: Rule => r } + lazy val localClaims: Set[Claim] = localSentences.collect { case r: Claim => r } lazy val localRulesAndClaims: Set[RuleOrClaim] = Set[RuleOrClaim]().++(localClaims).++(localRules) // Check that productions with the same klabel have identical attributes @@ -277,22 +312,22 @@ case class Module(val name: String, val imports: Set[Import], localSentences: Se // throw DivergingAttributesForTheSameKLabel(ps) // } - @transient lazy val attributesFor: Map[KLabel, Att] = productionsFor mapValues {mergeAttributes(_)} + @transient lazy val attributesFor: Map[KLabel, Att] = productionsFor.mapValues { + mergeAttributes(_) + } @transient lazy val signatureFor: Map[KLabel, Set[(Seq[Sort], Sort)]] = - productionsFor mapValues { - ps: Set[Production] => - ps.filter { p: Production => p.params.isEmpty } - .map { - p: Production => - val params: Seq[Sort] = p.items collect { case NonTerminal(sort, _) => sort } - (params, p.sort) + productionsFor.mapValues { ps: Set[Production] => + ps.filter { p: Production => p.params.isEmpty } + .map { p: Production => + val params: Seq[Sort] = p.items.collect { case NonTerminal(sort, _) => sort } + (params, p.sort) } } - lazy val sortDeclarations: Set[SyntaxSort] = sentences.collect({ case s: SyntaxSort => s }) - lazy val sortSynonyms: Set[SortSynonym] = sentences.collect({ case s: SortSynonym => s }) - lazy val lexicalIdentifiers: Set[SyntaxLexical] = sentences.collect({ case s: SyntaxLexical => s }) + lazy val sortDeclarations: Set[SyntaxSort] = sentences.collect { case s: SyntaxSort => s } + lazy val sortSynonyms: Set[SortSynonym] = sentences.collect { case s: SortSynonym => s } + lazy val lexicalIdentifiers: Set[SyntaxLexical] = sentences.collect { case s: SyntaxLexical => s } lazy val sortSynonymMap: Map[Sort, Sort] = sortSynonyms.map(s => (s.newSort, s.oldSort)).toMap @@ -300,107 +335,162 @@ case class Module(val name: String, val imports: Set[Import], localSentences: Se (sortDeclarations ++ allSorts.map(s => SyntaxSort(Seq(), s, Att.empty))) .groupBy(_.sort.head) - @transient lazy val sortAttributesFor: Map[SortHead, Att] = sortDeclarationsFor mapValues {mergeAttributes(_)} + @transient lazy val sortAttributesFor: Map[SortHead, Att] = sortDeclarationsFor.mapValues { + mergeAttributes(_) + } - private def mergeAttributes[T <: Sentence](p: Set[T]) = { + private def mergeAttributes[T <: Sentence](p: Set[T]) = Att.mergeAttributes(p.map(_.att)) - } - lazy val definedSorts: Set[SortHead] = (productions filter {p => !p.isSortVariable(p.sort)} map {_.sort.head}) ++ (sortDeclarations filter { s => s.params.isEmpty } map {_.sort.head}) ++ definedInstantiations.values.flatten.flatMap(_.params).filter(_.isNat).map(_.head) + lazy val definedSorts: Set[SortHead] = (productions + .filter(p => !p.isSortVariable(p.sort)) + .map(_.sort.head)) ++ (sortDeclarations.filter(s => s.params.isEmpty).map { + _.sort.head + }) ++ definedInstantiations.values.flatten.flatMap(_.params).filter(_.isNat).map(_.head) lazy val definedInstantiations: Map[SortHead, Set[Sort]] = { - val nonempty = ((productions filter {p => p.sort.params.nonEmpty && !p.params.contains(p.sort) && (p.sort.params.toSet & p.params.toSet).isEmpty} map {_.sort}) ++ (sortDeclarations filter { s => s.params.isEmpty && s.sort.params.nonEmpty} map {_.sort})) groupBy {_.head} - ((productions filter {p => p.sort.params.nonEmpty} map {_.sort.head}) ++ (sortDeclarations filter { s => s.sort.params.nonEmpty} map { _.sort.head})).map(s => s -> nonempty.getOrElse(s, Set())).toMap - } - lazy val allSorts: Set[Sort] = (definedSorts -- definedInstantiations.keys).map(Sort(_)) ++ definedInstantiations.values.flatten + val nonempty = ((productions + .filter { p => + p.sort.params.nonEmpty && !p.params + .contains(p.sort) && (p.sort.params.toSet & p.params.toSet).isEmpty + } + .map(_.sort)) ++ (sortDeclarations + .filter(s => s.params.isEmpty && s.sort.params.nonEmpty) + .map(_.sort))).groupBy(_.head) + ((productions.filter(p => p.sort.params.nonEmpty).map(_.sort.head)) ++ (sortDeclarations + .filter(s => s.sort.params.nonEmpty) + .map(_.sort.head))).map(s => s -> nonempty.getOrElse(s, Set())).toMap + } + lazy val allSorts: Set[Sort] = (definedSorts -- definedInstantiations.keys).map( + Sort(_) + ) ++ definedInstantiations.values.flatten lazy val sortedDefinedSorts: Seq[SortHead] = definedSorts.toSeq.sorted - lazy val sortedAllSorts: Seq[Sort] = allSorts.toSeq.sorted - lazy val usedCellSorts: Set[Sort] = productions.flatMap { p => p.items.collect { case NonTerminal(s, _) => s } - .filter(s => s.name.endsWith("Cell") || s.name.endsWith("CellFragment")) + lazy val sortedAllSorts: Seq[Sort] = allSorts.toSeq.sorted + lazy val usedCellSorts: Set[Sort] = productions.flatMap { p => + p.items + .collect { case NonTerminal(s, _) => s } + .filter(s => s.name.endsWith("Cell") || s.name.endsWith("CellFragment")) } - lazy val listSorts: Set[Sort] = sentences.collect({ case Production(_, _, srt, _, att1) if att1.contains(Att.USER_LIST) => - srt - }) + lazy val listSorts: Set[Sort] = sentences.collect { + case Production(_, _, srt, _, att1) if att1.contains(Att.USER_LIST) => + srt + } - lazy val subsorts: POSet[Sort] = computeSubsortPOSet(sentences, false) + lazy val subsorts: POSet[Sort] = computeSubsortPOSet(sentences, false) lazy val syntacticSubsorts: POSet[Sort] = computeSubsortPOSet(sentences, true) - lazy val overloads: POSet[Production] = computeOverloadPOSet(subsorts, productions) + lazy val overloads: POSet[Production] = computeOverloadPOSet(subsorts, productions) private lazy val expressedPriorities: Set[(Tag, Tag)] = sentences - .collect({ case SyntaxPriority(ps, _) => ps }) + .collect { case SyntaxPriority(ps, _) => ps } .map { ps: Seq[Set[Tag]] => val pairSetAndPenultimateTagSet = ps.foldLeft((Set[(Tag, Tag)](), Set[Tag]())) { case ((all, prev), current) => - val newPairs = for (a <- prev; b <- current) yield (a, b) + val newPairs = for { + a <- prev + b <- current + } yield (a, b) (newPairs | all, current) } pairSetAndPenultimateTagSet._1 // we're only interested in the pair set part of the fold - }.flatten + } + .flatten lazy val priorities = POSet(expressedPriorities) - lazy val leftAssoc = buildAssoc(Associativity.Left) + lazy val leftAssoc = buildAssoc(Associativity.Left) lazy val rightAssoc = buildAssoc(Associativity.Right) - private def buildAssoc(side: Associativity): Set[(Tag, Tag)] = { + private def buildAssoc(side: Associativity): Set[(Tag, Tag)] = sentences - .collect({ case SyntaxAssociativity(`side` | Associativity.NonAssoc, ps, _) => ps }) + .collect { case SyntaxAssociativity(`side` | Associativity.NonAssoc, ps, _) => ps } .map { ps: Set[Tag] => - for (a <- ps; b <- ps) yield (a, b) - }.flatten - } + for { + a <- ps + b <- ps + } yield (a, b) + } + .flatten @transient lazy val freshFunctionFor: Map[Sort, KLabel] = - productions.groupBy(_.sort).mapValues(_.filter(_.att.contains(Att.FRESH_GENERATOR))) - .filter(_._2.nonEmpty).mapValues(_.map(p => p.klabel.get)).mapValues { set => { - if (set.size > 1) - throw KEMException.compilerError("Found more than one fresh generator for sort " + sortFor(set.head) - + ". Found: " + set) - else - set.head - } - } + productions + .groupBy(_.sort) + .mapValues(_.filter(_.att.contains(Att.FRESH_GENERATOR))) + .filter(_._2.nonEmpty) + .mapValues(_.map(p => p.klabel.get)) + .mapValues { set => + if (set.size > 1) + throw KEMException.compilerError( + "Found more than one fresh generator for sort " + sortFor(set.head) + + ". Found: " + set + ) + else + set.head + } // check that non-terminals have a defined sort - def checkSorts (): Unit = localSentences foreach { - case p@Production(_, params, _, items, _) => - val res = items collect - { case nt: NonTerminal if !p.isSortVariable(nt.sort) && !definedSorts.contains(nt.sort.head) && !sortSynonymMap.contains(nt.sort) => nt.sort - case nt: NonTerminal if nt.sort.params.nonEmpty && (nt.sort.params.toSet & params.toSet).isEmpty && !definedInstantiations.getOrElse(nt.sort.head, Set()).contains(nt.sort) => nt.sort + def checkSorts(): Unit = localSentences.foreach { + case p @ Production(_, params, _, items, _) => + val res = items.collect { + case nt: NonTerminal + if !p.isSortVariable(nt.sort) && !definedSorts.contains(nt.sort.head) && !sortSynonymMap + .contains(nt.sort) => + nt.sort + case nt: NonTerminal + if nt.sort.params.nonEmpty && (nt.sort.params.toSet & params.toSet).isEmpty && !definedInstantiations + .getOrElse(nt.sort.head, Set()) + .contains(nt.sort) => + nt.sort } if (res.nonEmpty) throw KEMException.compilerError("Could not find sorts: " + res.asJava, p) case _ => } - def checkUserLists(): Unit = localSentences foreach { - case p@Production(_, _, srt, _, atts) => + def checkUserLists(): Unit = localSentences.foreach { + case p @ Production(_, _, srt, _, atts) => if (atts.contains(Att.USER_LIST)) { - val prev = importedSentences.find(s => s.isInstanceOf[Production] - && s.asInstanceOf[Production].sort.equals(srt) - && s.att.contains(Att.USER_LIST)) + val prev = importedSentences.find(s => + s.isInstanceOf[Production] + && s.asInstanceOf[Production].sort.equals(srt) + && s.att.contains(Att.USER_LIST) + ) if (prev.isDefined) - throw KEMException.compilerError("Sort " + srt + " previously declared as a user list at " - + prev.get.source.get() + " and " - + prev.get.location.get(), p) + throw KEMException.compilerError( + "Sort " + srt + " previously declared as a user list at " + + prev.get.source.get() + " and " + + prev.get.location.get(), + p + ) } case _ => } - lazy val recordProjections = productions.flatMap(p => p.nonterminals.filter(_.name.isDefined).map(nt => "project:" ++ p.klabel.get.name ++ ":" ++ nt.name.get)) - lazy val semanticCasts = allSorts.map("#SemanticCastTo" + _) + lazy val recordProjections = productions.flatMap(p => + p.nonterminals + .filter(_.name.isDefined) + .map(nt => "project:" ++ p.klabel.get.name ++ ":" ++ nt.name.get) + ) + lazy val semanticCasts = allSorts.map("#SemanticCastTo" + _) lazy val sortProjections = allSorts.map("project:" + _) - lazy val sortPredicates = allSorts.map("is" + _) + lazy val sortPredicates = allSorts.map("is" + _) override lazy val hashCode: Int = name.hashCode - def flattened() : FlatModule = new FlatModule(name, imports.map(i => FlatImport(i.module.name, i.isPublic, Att.empty)), localSentences, att) - def flatModules() : (String, Set[FlatModule]) = (name, Set(flattened) ++ fullImports.map(m => m.flatModules._2).flatten) + def flattened(): FlatModule = new FlatModule( + name, + imports.map(i => FlatImport(i.module.name, i.isPublic, Att.empty)), + localSentences, + att + ) + def flatModules(): (String, Set[FlatModule]) = + (name, Set(flattened) ++ fullImports.map(m => m.flatModules._2).flatten) } trait HasAtt { val att: Att - def isMacro: Boolean = att.contains(Att.MACRO) || att.contains(Att.MACRO_REC) || att.contains(Att.ALIAS) || att.contains(Att.ALIAS_REC) + def isMacro: Boolean = att.contains(Att.MACRO) || att.contains(Att.MACRO_REC) || att.contains( + Att.ALIAS + ) || att.contains(Att.ALIAS_REC) } trait Sentence extends HasLocation with HasAtt with AttValue { @@ -410,101 +500,114 @@ trait Sentence extends HasLocation with HasAtt with AttValue { val att: Att def withAtt(att: Att): Sentence def location: Optional[Location] = att.getOptional(classOf[Location]) - def source: Optional[Source] = att.getOptional(classOf[Source]) - def label: Optional[String] = att.getOptional(Att.LABEL) + def source: Optional[Source] = att.getOptional(classOf[Source]) + def label: Optional[String] = att.getOptional(Att.LABEL) } object Sentence { implicit val ord = new Ordering[Sentence] { - def compare(a: Sentence, b: Sentence): Int = { + def compare(a: Sentence, b: Sentence): Int = (a, b) match { - case (c:SyntaxSort, d:SyntaxSort) => Ordering[SyntaxSort].compare(c, d) - case (c:SortSynonym, d:SortSynonym) => Ordering[SortSynonym].compare(c, d) - case (c:SyntaxLexical, d:SyntaxLexical) => Ordering[SyntaxLexical].compare(c, d) - case (c:Production, d:Production) => Ordering[Production].compare(c, d) - case (c:SyntaxAssociativity, d:SyntaxAssociativity) => Ordering[SyntaxAssociativity].compare(c, d) - case (c:SyntaxPriority, d:SyntaxPriority) => Ordering[SyntaxPriority].compare(c, d) - case (c:ContextAlias, d:ContextAlias) => Ordering[ContextAlias].compare(c, d) - case (c:Context, d:Context) => Ordering[Context].compare(c, d) - case (c:Rule, d:Rule) => Ordering[Rule].compare(c, d) - case (c:Claim, d:Claim) => Ordering[Claim].compare(c, d) - case (_:SyntaxSort, _) => -1 - case (_, _:SyntaxSort) => 1 - case (_:SortSynonym, _) => -1 - case (_, _:SortSynonym) => 1 - case (_:SyntaxLexical, _) => -1 - case (_, _:SyntaxLexical) => 1 - case (_:Production, _) => -1 - case (_, _:Production) => 1 - case (_:SyntaxAssociativity, _) => -1 - case (_, _:SyntaxAssociativity) => 1 - case (_:SyntaxPriority, _) => -1 - case (_, _:SyntaxPriority) => 1 - case (_:ContextAlias, _) => -1 - case (_, _:ContextAlias) => 1 - case (_:Context, _) => -1 - case (_, _:Context) => 1 - case (_:Rule, _) => -1 - case (_, _:Rule) => 1 - case (_:Claim, _) => -1 - case (_, _:Claim) => 1 - case (_, _) => throw KEMException.internalError("Cannot order these sentences:\n" + a.toString() + "\n" + b.toString()) + case (c: SyntaxSort, d: SyntaxSort) => Ordering[SyntaxSort].compare(c, d) + case (c: SortSynonym, d: SortSynonym) => Ordering[SortSynonym].compare(c, d) + case (c: SyntaxLexical, d: SyntaxLexical) => Ordering[SyntaxLexical].compare(c, d) + case (c: Production, d: Production) => Ordering[Production].compare(c, d) + case (c: SyntaxAssociativity, d: SyntaxAssociativity) => + Ordering[SyntaxAssociativity].compare(c, d) + case (c: SyntaxPriority, d: SyntaxPriority) => Ordering[SyntaxPriority].compare(c, d) + case (c: ContextAlias, d: ContextAlias) => Ordering[ContextAlias].compare(c, d) + case (c: Context, d: Context) => Ordering[Context].compare(c, d) + case (c: Rule, d: Rule) => Ordering[Rule].compare(c, d) + case (c: Claim, d: Claim) => Ordering[Claim].compare(c, d) + case (_: SyntaxSort, _) => -1 + case (_, _: SyntaxSort) => 1 + case (_: SortSynonym, _) => -1 + case (_, _: SortSynonym) => 1 + case (_: SyntaxLexical, _) => -1 + case (_, _: SyntaxLexical) => 1 + case (_: Production, _) => -1 + case (_, _: Production) => 1 + case (_: SyntaxAssociativity, _) => -1 + case (_, _: SyntaxAssociativity) => 1 + case (_: SyntaxPriority, _) => -1 + case (_, _: SyntaxPriority) => 1 + case (_: ContextAlias, _) => -1 + case (_, _: ContextAlias) => 1 + case (_: Context, _) => -1 + case (_, _: Context) => 1 + case (_: Rule, _) => -1 + case (_, _: Rule) => 1 + case (_: Claim, _) => -1 + case (_, _: Claim) => 1 + case (_, _) => + throw KEMException.internalError( + "Cannot order these sentences:\n" + a.toString() + "\n" + b.toString() + ) } - } } } // deprecated -case class Context(body: K, requires: K, att: Att = Att.empty) extends Sentence with OuterKORE with ContextToString { - override val isSyntax = false - override val isNonSyntax = true +case class Context(body: K, requires: K, att: Att = Att.empty) + extends Sentence + with OuterKORE + with ContextToString { + override val isSyntax = false + override val isNonSyntax = true override def withAtt(att: Att) = Context(body, requires, att) } object Context { - implicit val ord: Ordering[Context] = Ordering.by[Context, (K, K, Att)](s => (s.body, s.requires, s.att)) + implicit val ord: Ordering[Context] = + Ordering.by[Context, (K, K, Att)](s => (s.body, s.requires, s.att)) } -case class ContextAlias(body: K, requires: K, att: Att = Att.empty) extends Sentence with OuterKORE with ContextAliasToString { - override val isSyntax = true - override val isNonSyntax = false +case class ContextAlias(body: K, requires: K, att: Att = Att.empty) + extends Sentence + with OuterKORE + with ContextAliasToString { + override val isSyntax = true + override val isNonSyntax = false override def withAtt(att: Att) = ContextAlias(body, requires, att) } object ContextAlias { - implicit val ord: Ordering[ContextAlias] = { + implicit val ord: Ordering[ContextAlias] = Ordering.by[ContextAlias, (K, K, Att)](s => (s.body, s.requires, s.att)) - } } abstract class RuleOrClaim extends Sentence { def body: K def requires: K def ensures: K - override val isSyntax = false + override val isSyntax = false override val isNonSyntax = true def newInstance(body: K, requires: K, ensures: K, att: Att = Att.empty): RuleOrClaim } -case class Claim(body: K, requires: K, ensures: K, att: Att = Att.empty) extends RuleOrClaim with ClaimToString with OuterKORE { +case class Claim(body: K, requires: K, ensures: K, att: Att = Att.empty) + extends RuleOrClaim + with ClaimToString + with OuterKORE { override def withAtt(att: Att): Claim = Claim(body, requires, ensures, att) override def newInstance(body: K, requires: K, ensures: K, att: Att = Att.empty): Claim = Claim(body, requires, ensures, att) } object Claim { - implicit val ord: Ordering[Claim] = { + implicit val ord: Ordering[Claim] = Ordering.by[Claim, (K, K, K, Att)](s => (s.body, s.requires, s.ensures, s.att)) - } } -case class Rule(body: K, requires: K, ensures: K, att: Att = Att.empty) extends RuleOrClaim with RuleToString with OuterKORE { +case class Rule(body: K, requires: K, ensures: K, att: Att = Att.empty) + extends RuleOrClaim + with RuleToString + with OuterKORE { override def withAtt(att: Att): Rule = Rule(body, requires, ensures, att) override def newInstance(body: K, requires: K, ensures: K, att: Att = Att.empty): Rule = Rule(body, requires, ensures, att) } object Rule { - implicit val ord: Ordering[Rule] = { + implicit val ord: Ordering[Rule] = Ordering.by[Rule, (K, K, K, Att)](r => (r.body, r.requires, r.ensures, r.att)) - } } // hooked @@ -512,31 +615,36 @@ object Rule { // syntax declarations case class SyntaxPriority(priorities: Seq[Set[Tag]], att: Att = Att.empty) - extends Sentence with SyntaxPriorityToString with OuterKORE { - override val isSyntax = true - override val isNonSyntax = false + extends Sentence + with SyntaxPriorityToString + with OuterKORE { + override val isSyntax = true + override val isNonSyntax = false override def withAtt(att: Att) = SyntaxPriority(priorities, att) } object SyntaxPriority { implicit val ord: Ordering[SyntaxPriority] = { import scala.math.Ordering.Implicits._ - Ordering.by[SyntaxPriority, (Seq[Seq[Tag]], Att)](s => (s.priorities.map(_.toSeq.sorted), s.att)) + Ordering.by[SyntaxPriority, (Seq[Seq[Tag]], Att)](s => + (s.priorities.map(_.toSeq.sorted), s.att) + ) } } -case class SyntaxAssociativity( - assoc: Associativity, - tags: Set[Tag], - att: Att = Att.empty) - extends Sentence with SyntaxAssociativityToString with OuterKORE { - override val isSyntax = true - override val isNonSyntax = false +case class SyntaxAssociativity(assoc: Associativity, tags: Set[Tag], att: Att = Att.empty) + extends Sentence + with SyntaxAssociativityToString + with OuterKORE { + override val isSyntax = true + override val isNonSyntax = false override def withAtt(att: Att) = SyntaxAssociativity(assoc, tags, att) } object SyntaxAssociativity { implicit val ord: Ordering[SyntaxAssociativity] = { import scala.math.Ordering.Implicits._ - Ordering.by[SyntaxAssociativity, (Associativity, Seq[Tag], Att)](s => (s.assoc, s.tags.toSeq.sorted, s.att)) + Ordering.by[SyntaxAssociativity, (Associativity, Seq[Tag], Att)](s => + (s.assoc, s.tags.toSeq.sorted, s.att) + ) } } @@ -554,62 +662,76 @@ object Tag { // att.get(Production.kLabelAttribute).headOption map { case KList(KToken(s, _, _)) => s } map { KLabel(_) } //} -case class SyntaxSort(params: Seq[Sort], sort: Sort, att: Att = Att.empty) extends Sentence - with SyntaxSortToString with OuterKORE { +case class SyntaxSort(params: Seq[Sort], sort: Sort, att: Att = Att.empty) + extends Sentence + with SyntaxSortToString + with OuterKORE { def items = Seq() - override val isSyntax = true - override val isNonSyntax = false + override val isSyntax = true + override val isNonSyntax = false override def withAtt(att: Att) = SyntaxSort(params, sort, att) } object SyntaxSort { implicit val ord: Ordering[SyntaxSort] = { import scala.math.Ordering.Implicits._ - Ordering.by[SyntaxSort, (Seq[String], String, Att)](s => (s.params.map(_.name), s.sort.name, s.att)) + Ordering.by[SyntaxSort, (Seq[String], String, Att)](s => + (s.params.map(_.name), s.sort.name, s.att) + ) } } -case class SortSynonym(newSort: Sort, oldSort: Sort, att: Att = Att.empty) extends Sentence - with SortSynonymToString with OuterKORE { +case class SortSynonym(newSort: Sort, oldSort: Sort, att: Att = Att.empty) + extends Sentence + with SortSynonymToString + with OuterKORE { - override val isSyntax = true - override val isNonSyntax = false + override val isSyntax = true + override val isNonSyntax = false override def withAtt(att: Att) = SortSynonym(newSort, oldSort, att) } object SortSynonym { - implicit val ord: Ordering[SortSynonym] = { + implicit val ord: Ordering[SortSynonym] = Ordering.by[SortSynonym, (String, String, Att)](s => (s.newSort.name, s.oldSort.name, s.att)) - } } -case class SyntaxLexical(name: String, regex: String, att: Att = Att.empty) extends Sentence - with SyntaxLexicalToString with OuterKORE { +case class SyntaxLexical(name: String, regex: String, att: Att = Att.empty) + extends Sentence + with SyntaxLexicalToString + with OuterKORE { - override val isSyntax = true - override val isNonSyntax = false + override val isSyntax = true + override val isNonSyntax = false override def withAtt(att: Att) = SyntaxLexical(name, regex, att) } object SyntaxLexical { - implicit val ord: Ordering[SyntaxLexical] = { + implicit val ord: Ordering[SyntaxLexical] = Ordering.by[SyntaxLexical, (String, String, Att)](s => (s.name, s.regex, s.att)) - } } -case class Production(klabel: Option[KLabel], params: Seq[Sort], sort: Sort, items: Seq[ProductionItem], att: Att) - extends Sentence with ProductionToString { +case class Production( + klabel: Option[KLabel], + params: Seq[Sort], + sort: Sort, + items: Seq[ProductionItem], + att: Att +) extends Sentence + with ProductionToString { lazy val klabelAtt: Option[String] = att.getOption(Att.KLABEL).orElse(klabel.map(_.name)) - lazy val parseLabel: KLabel = klabel.getOrElse(att.get(Att.BRACKET_LABEL, classOf[KLabel])) + lazy val parseLabel: KLabel = klabel.getOrElse(att.get(Att.BRACKET_LABEL, classOf[KLabel])) override def equals(that: Any): Boolean = that match { - case p@Production(`klabel`, `params`, `sort`, `items`, _) => ( this.klabelAtt == p.klabelAtt - && this.att.getOption(Att.FUNCTION) == p.att.getOption(Att.FUNCTION) - && this.att.getOption(Att.SYMBOL) == p.att.getOption(Att.SYMBOL) - ) + case p @ Production(`klabel`, `params`, `sort`, `items`, _) => ( + this.klabelAtt == p.klabelAtt + && this.att.getOption(Att.FUNCTION) == p.att.getOption(Att.FUNCTION) + && this.att.getOption(Att.SYMBOL) == p.att.getOption(Att.SYMBOL) + ) case _ => false } - override lazy val hashCode: Int = ((sort.hashCode() * 31 + items.hashCode()) * 31 + klabel.hashCode() * 31) + params.hashCode() + override lazy val hashCode: Int = + ((sort.hashCode() * 31 + items.hashCode()) * 31 + klabel.hashCode() * 31) + params.hashCode() lazy val isSyntacticSubsort: Boolean = items.size == 1 && items.head.isInstanceOf[NonTerminal] @@ -627,114 +749,172 @@ case class Production(klabel: Option[KLabel], params: Seq[Sort], sort: Sort, ite def nonterminal(i: Int): NonTerminal = nonterminals(i) def substitute(args: Seq[Sort]): Production = { - val subst = (params zip args).toMap - Production(klabel.map(l => ADT.KLabel(l.name, args:_*)), Seq(), subst.getOrElse(sort, sort.substitute(subst)), items.map({ - case NonTerminal(sort, name) => NonTerminal(subst.getOrElse(sort, sort.substitute(subst)), name) - case i => i - }), att) - } - - def isSortVariable(s: Sort): Boolean = { + val subst = params.zip(args).toMap + Production( + klabel.map(l => ADT.KLabel(l.name, args: _*)), + Seq(), + subst.getOrElse(sort, sort.substitute(subst)), + items.map { + case NonTerminal(sort, name) => + NonTerminal(subst.getOrElse(sort, sort.substitute(subst)), name) + case i => i + }, + att + ) + } + + def isSortVariable(s: Sort): Boolean = params.contains(s) - } private def computePrefixProduction: Boolean = { var state = 0 - for (item <- items) { + for (item <- items) if (state == 0) { // some sequence of terminals ending in an open parens item match { case terminal: Terminal if terminal.value == "(" => state = 1 - case _: Terminal => - case _ => return false + case _: Terminal => + case _ => return false } } else if (state == 1) { // a nonterminal or a close paren item match { - case _: NonTerminal => state = 2 + case _: NonTerminal => state = 2 case terminal: Terminal if terminal.value == ")" => state = 4 - case _ => return false + case _ => return false } } else if (state == 2) { // a close paren or a comma item match { case terminal: Terminal if terminal.value == "," => state = 3 case terminal: Terminal if terminal.value == ")" => state = 4 - case _ => return false + case _ => return false } } else if (state == 3) { // a nonterminal item match { case _: NonTerminal => state = 2 - case _ => return false + case _ => return false } } else { return false } - } state == 4 } lazy val isPrefixProduction: Boolean = computePrefixProduction /** - * Generate lists to parse record productions efficiently - * syntax S ::= prefix(... Uid) [main] - * syntax Uid ::= "" [empty] - * syntax Uid ::= UidNe [subsort] - * syntax UidNe ::= UidNe "," UidItem [repeat] - * syntax UidNe ::= UidItem [subsort2] - * syntax UidItem ::= "name" ":" Sort [item] + * Generate lists to parse record productions efficiently syntax S ::= prefix(... Uid) [main] + * syntax Uid ::= "" [empty] syntax Uid ::= UidNe [subsort] syntax UidNe ::= UidNe "," UidItem + * [repeat] syntax UidNe ::= UidItem [subsort2] syntax UidItem ::= "name" ":" Sort [item] */ - def recordProductions(uid:UidProvider): Set[Production] = { + def recordProductions(uid: UidProvider): Set[Production] = { assert(isPrefixProduction) - val namedNts = items.filter(_.isInstanceOf[NonTerminal]).map(_.asInstanceOf[NonTerminal]).filter(_.name.isDefined) + val namedNts = items + .filter(_.isInstanceOf[NonTerminal]) + .map(_.asInstanceOf[NonTerminal]) + .filter(_.name.isDefined) val prefix = items.takeWhile(_.isInstanceOf[Terminal]) :+ Terminal("...") val suffix = items.last val newAtt = Att.empty.add(Att.RECORD_PRD, classOf[Production], this) - if (namedNts.isEmpty) // if it doesn't contain named NTs, don't generate the extra list productions + if (namedNts.isEmpty) + // if it doesn't contain named NTs, don't generate the extra list productions Set(Production(klabel, params, sort, prefix :+ suffix, newAtt.add(Att.RECORD_PRD_ZERO))) - else if(namedNts.size == 1) { + else if (namedNts.size == 1) { val main = Production(klabel, params, sort, prefix :+ suffix, newAtt.add(Att.RECORD_PRD_ZERO)) - val one = Production(klabel, params, sort, prefix :+ Terminal(namedNts.head.name.get) :+ Terminal(":") :+ namedNts.head :+ suffix, newAtt.add(Att.RECORD_PRD_ONE, namedNts.head.name.get)) + val one = Production( + klabel, + params, + sort, + prefix :+ Terminal(namedNts.head.name.get) :+ Terminal(":") :+ namedNts.head :+ suffix, + newAtt.add(Att.RECORD_PRD_ONE, namedNts.head.name.get) + ) Set(main, one) } else { val baseName = items.head.asInstanceOf[Terminal].value + "-" + uid - val main = Production(klabel, params, sort, prefix :+ NonTerminal(Sort(baseName), None) :+ suffix, newAtt.add(Att.RECORD_PRD_MAIN)) - val empty = Production(klabel, Seq(), Sort(baseName), Seq(Terminal("")), newAtt.add(Att.RECORD_PRD_EMPTY)) - val subsort = Production(None, Seq(), Sort(baseName), Seq(NonTerminal(Sort(baseName + "Ne"), None)), newAtt.add(Att.RECORD_PRD_SUBSORT)) - val repeat = Production(klabel, Seq(), Sort(baseName + "Ne"), Seq(NonTerminal(Sort(baseName + "Ne"), None), Terminal(","), NonTerminal(Sort(baseName + "Item"), None)), newAtt.add(Att.RECORD_PRD_REPEAT)) - val subsort2 = Production(None, Seq(), Sort(baseName + "Ne"), Seq(NonTerminal(Sort(baseName + "Item"), None)), newAtt.add(Att.RECORD_PRD_SUBSORT)) - val namedItems: Set[Production] = namedNts.map(nt => Production(klabel, Seq(), Sort(baseName + "Item"), Seq(Terminal(nt.name.get), Terminal(":"), NonTerminal(nt.sort, None)), newAtt.add(Att.RECORD_PRD_ITEM, nt.name.get))).toSet + val main = Production( + klabel, + params, + sort, + prefix :+ NonTerminal(Sort(baseName), None) :+ suffix, + newAtt.add(Att.RECORD_PRD_MAIN) + ) + val empty = Production( + klabel, + Seq(), + Sort(baseName), + Seq(Terminal("")), + newAtt.add(Att.RECORD_PRD_EMPTY) + ) + val subsort = Production( + None, + Seq(), + Sort(baseName), + Seq(NonTerminal(Sort(baseName + "Ne"), None)), + newAtt.add(Att.RECORD_PRD_SUBSORT) + ) + val repeat = Production( + klabel, + Seq(), + Sort(baseName + "Ne"), + Seq( + NonTerminal(Sort(baseName + "Ne"), None), + Terminal(","), + NonTerminal(Sort(baseName + "Item"), None) + ), + newAtt.add(Att.RECORD_PRD_REPEAT) + ) + val subsort2 = Production( + None, + Seq(), + Sort(baseName + "Ne"), + Seq(NonTerminal(Sort(baseName + "Item"), None)), + newAtt.add(Att.RECORD_PRD_SUBSORT) + ) + val namedItems: Set[Production] = namedNts + .map(nt => + Production( + klabel, + Seq(), + Sort(baseName + "Item"), + Seq(Terminal(nt.name.get), Terminal(":"), NonTerminal(nt.sort, None)), + newAtt.add(Att.RECORD_PRD_ITEM, nt.name.get) + ) + ) + .toSet namedItems + main + empty + subsort + repeat + subsort2 } } - override val isSyntax = true - override val isNonSyntax = false + override val isSyntax = true + override val isNonSyntax = false override def withAtt(att: Att) = Production(klabel, params, sort, items, att) } object Production { - implicit val ord: Ordering[Production] = { + implicit val ord: Ordering[Production] = Ordering.by[Production, (Option[String], Att)](s => (s.klabel.map(_.name), s.att)) - } - def apply(klabel: KLabel, params: Seq[Sort], sort: Sort, items: Seq[ProductionItem], att: Att = Att.empty): Production = { + def apply( + klabel: KLabel, + params: Seq[Sort], + sort: Sort, + items: Seq[ProductionItem], + att: Att = Att.empty + ): Production = Production(Some(klabel), params, sort, items, att) - } - def apply(params: Seq[Sort], sort: Sort, items: Seq[ProductionItem], att: Att): Production = { + def apply(params: Seq[Sort], sort: Sort, items: Seq[ProductionItem], att: Att): Production = if (att.contains(Att.KLABEL)) { Production(Some(KORE.KLabel(att.get(Att.KLABEL))), params, sort, items, att) } else { Production(None, params, sort, items, att) } - } } // a way to deterministically generate unique IDs dependent on module name -case class UidProvider(modName:String) { - private var uid = 0 - override def toString:String = { uid = uid + 1; modName + "+" + uid} +case class UidProvider(modName: String) { + private var uid = 0 + override def toString: String = { uid = uid + 1; modName + "+" + uid } } // hooked but problematic, see kast-core.k @@ -743,15 +923,16 @@ sealed trait ProductionItem extends OuterKORE // marker -sealed trait TerminalLike extends ProductionItem with Comparable[TerminalLike] { -} +sealed trait TerminalLike extends ProductionItem with Comparable[TerminalLike] {} -case class NonTerminal(sort: Sort, name: Option[String]) extends ProductionItem - with NonTerminalToString +case class NonTerminal(sort: Sort, name: Option[String]) + extends ProductionItem + with NonTerminalToString -case class RegexTerminal(precedeRegex: String, regex: String, followRegex: String) extends TerminalLike with - RegexTerminalToString { - lazy val pattern = new RunAutomaton(new RegExp(regex).toAutomaton, false) +case class RegexTerminal(precedeRegex: String, regex: String, followRegex: String) + extends TerminalLike + with RegexTerminalToString { + lazy val pattern = new RunAutomaton(new RegExp(regex).toAutomaton, false) lazy val followPattern = new RunAutomaton(new RegExp(followRegex).toAutomaton, false) lazy val precedePattern = { val unreversed = new RegExp(precedeRegex).toAutomaton @@ -767,8 +948,9 @@ case class RegexTerminal(precedeRegex: String, regex: String, followRegex: Strin } } -case class Terminal(value: String) extends TerminalLike // hooked - with TerminalToString { +case class Terminal(value: String) + extends TerminalLike // hooked + with TerminalToString { def compareTo(t: TerminalLike): Int = { if (t.isInstanceOf[RegexTerminal]) { diff --git a/kore/src/main/scala/org/kframework/definition/transformers.scala b/kore/src/main/scala/org/kframework/definition/transformers.scala index 7e6fbaa414d..dce6dda23a8 100644 --- a/kore/src/main/scala/org/kframework/definition/transformers.scala +++ b/kore/src/main/scala/org/kframework/definition/transformers.scala @@ -2,98 +2,135 @@ package org.kframework.definition -import java.util.Optional import java.util.function.BiFunction -import org.kframework.attributes.{Location, Source} +import java.util.Optional +import org.kframework.attributes.Location +import org.kframework.attributes.Source import org.kframework.definition -import org.kframework.kore.{AttCompare, K, KApply, KToken} +import org.kframework.kore.AttCompare +import org.kframework.kore.K +import org.kframework.kore.KApply +import org.kframework.kore.KToken import org.kframework.utils.errorsystem.KEMException object ModuleTransformer { - def from(f: java.util.function.UnaryOperator[Module], name: String): ModuleTransformer = ModuleTransformer(f(_), name) + def from(f: java.util.function.UnaryOperator[Module], name: String): ModuleTransformer = + ModuleTransformer(f(_), name) - def fromSentenceTransformer(f: java.util.function.UnaryOperator[Sentence], name: String): ModuleTransformer = + def fromSentenceTransformer( + f: java.util.function.UnaryOperator[Sentence], + name: String + ): ModuleTransformer = fromSentenceTransformer((m: Module, s: Sentence) => f(s), name) def fromSentenceTransformer(f: (Module, Sentence) => Sentence, name: String): ModuleTransformer = - ModuleTransformer(m => { - val newSentences = m.localSentences map { s => - try { - f(m, s) - } catch { - case e: KEMException => - val extraInfo = Optional.of(" on sentence at") - .flatMap[String](prefix => s.source.map[String](src => prefix + "\n\t" + src.toString)) - .flatMap[String](prefix => s.location.map[String](loc => prefix + "\n\t" + loc.toString)).orElse("") - - e.exception.addTraceFrame("while executing phase \"" + name + "\"" + extraInfo) - throw e + ModuleTransformer( + m => { + val newSentences = m.localSentences.map { s => + try + f(m, s) + catch { + case e: KEMException => + val extraInfo = Optional + .of(" on sentence at") + .flatMap[String](prefix => + s.source.map[String](src => prefix + "\n\t" + src.toString) + ) + .flatMap[String](prefix => + s.location.map[String](loc => prefix + "\n\t" + loc.toString) + ) + .orElse("") + + e.exception.addTraceFrame("while executing phase \"" + name + "\"" + extraInfo) + throw e + } } - } - //TODO(compare attributes) - if (newSentences != m.localSentences) - Module(m.name, m.imports, newSentences, m.att) - else - m - }, name) + // TODO(compare attributes) + if (newSentences != m.localSentences) + Module(m.name, m.imports, newSentences, m.att) + else + m + }, + name + ) def fromRuleBodyTransformer(f: K => K, name: String): ModuleTransformer = fromRuleBodyTransformerWithRule((rule, k) => f(k), name) - def fromRuleBodyTransformerWithRule(f: (RuleOrClaim, K) => K, name: String) : ModuleTransformer = - fromSentenceTransformer(_ match { case r: Rule => r.copy(body = f(r, r.body)); - case c: Claim => c.copy(body = f(c, c.body)); - case s => s }, name) + def fromRuleBodyTransformerWithRule(f: (RuleOrClaim, K) => K, name: String): ModuleTransformer = + fromSentenceTransformer( + _ match { + case r: Rule => r.copy(body = f(r, r.body)); + case c: Claim => c.copy(body = f(c, c.body)); + case s => s + }, + name + ) def fromKTransformerWithModuleInfo(ff: (Module, K) => K, name: String): ModuleTransformer = - fromSentenceTransformer((module, sentence) => { - sentence match { - case r: Rule => Rule.apply(ff(module, r.body), ff(module, r.requires), ff(module, r.ensures), r.att) - case c: Claim => Claim.apply(ff(module, c.body), ff(module, c.requires), ff(module, c.ensures), c.att) - case c: Context => Context.apply(ff(module, c.body), ff(module, c.requires), c.att) - case c: ContextAlias => ContextAlias.apply(ff(module, c.body), ff(module, c.requires), c.att) - case o => o - } - }, name) + fromSentenceTransformer( + (module, sentence) => + sentence match { + case r: Rule => + Rule.apply(ff(module, r.body), ff(module, r.requires), ff(module, r.ensures), r.att) + case c: Claim => + Claim.apply(ff(module, c.body), ff(module, c.requires), ff(module, c.ensures), c.att) + case c: Context => Context.apply(ff(module, c.body), ff(module, c.requires), c.att) + case c: ContextAlias => + ContextAlias.apply(ff(module, c.body), ff(module, c.requires), c.att) + case o => o + }, + name + ) def fromKTransformer(f: K => K, name: String): ModuleTransformer = fromKTransformerWithModuleInfo((mod, k) => f(k), name) def apply(f: Module => Module, name: String): ModuleTransformer = f match { case f: ModuleTransformer => f - case _ => new ModuleTransformer(f, name) + case _ => new ModuleTransformer(f, name) } } /** - * Transform all modules, transforming each module after its imports. - * The f function take a module with all the imported modules already transformed, and changes the current module. - */ + * Transform all modules, transforming each module after its imports. The f function take a module + * with all the imported modules already transformed, and changes the current module. + */ class ModuleTransformer(f: Module => Module, name: String) extends (Module => Module) { val memoization = collection.concurrent.TrieMap[Module, Module]() - override def apply(input: Module): Module = { - memoization.getOrElseUpdate(input, { - var newImports = input.imports map (i => Import(this(i.module), i.isPublic)) - if (newImports != input.imports) - f(Module(input.name, newImports, input.localSentences, input.att)) - else - f(input) - }) - } + override def apply(input: Module): Module = + memoization.getOrElseUpdate( + input, { + var newImports = input.imports.map(i => Import(this(i.module), i.isPublic)) + if (newImports != input.imports) + f(Module(input.name, newImports, input.localSentences, input.att)) + else + f(input) + } + ) } object DefinitionTransformer { - def fromSentenceTransformer(f: java.util.function.UnaryOperator[Sentence], name: String): DefinitionTransformer = + def fromSentenceTransformer( + f: java.util.function.UnaryOperator[Sentence], + name: String + ): DefinitionTransformer = DefinitionTransformer(ModuleTransformer.fromSentenceTransformer(f, name)) - def fromSentenceTransformer(f: (Module, Sentence) => Sentence, name: String): DefinitionTransformer = + def fromSentenceTransformer( + f: (Module, Sentence) => Sentence, + name: String + ): DefinitionTransformer = DefinitionTransformer(ModuleTransformer.fromSentenceTransformer(f, name)) def fromRuleBodyTransformer(f: K => K, name: String): DefinitionTransformer = DefinitionTransformer(ModuleTransformer.fromRuleBodyTransformer(f, name)) - def fromRuleBodyTransformerWithRule(f: (RuleOrClaim, K) => K, name: String): DefinitionTransformer = + def fromRuleBodyTransformerWithRule( + f: (RuleOrClaim, K) => K, + name: String + ): DefinitionTransformer = DefinitionTransformer(ModuleTransformer.fromRuleBodyTransformerWithRule(f, name)) def fromKTransformer(f: K => K, name: String): DefinitionTransformer = @@ -102,40 +139,44 @@ object DefinitionTransformer { def fromKTransformerWithModuleInfo(f: (Module, K) => K, name: String): DefinitionTransformer = DefinitionTransformer(ModuleTransformer.fromKTransformerWithModuleInfo(f, name)) - def from(f: Module => Module, name: String): DefinitionTransformer = DefinitionTransformer(f, name) + def from(f: Module => Module, name: String): DefinitionTransformer = + DefinitionTransformer(f, name) def apply(f: Module => Module): DefinitionTransformer = new DefinitionTransformer(f) - def apply(f: Module => Module, name: String): DefinitionTransformer = new DefinitionTransformer(ModuleTransformer(f, name)) + def apply(f: Module => Module, name: String): DefinitionTransformer = new DefinitionTransformer( + ModuleTransformer(f, name) + ) } -class DefinitionTransformer(moduleTransformer: Module => Module) extends (Definition => Definition) { - override def apply(d: Definition): Definition = { +class DefinitionTransformer(moduleTransformer: Module => Module) + extends (Definition => Definition) { + override def apply(d: Definition): Definition = definition.Definition( moduleTransformer(d.mainModule), - d.entryModules map moduleTransformer, - d.att) - } + d.entryModules.map(moduleTransformer), + d.att + ) } object KViz { - def from(f: java.util.function.UnaryOperator[K], name:String):KViz = KViz(f(_), name) + def from(f: java.util.function.UnaryOperator[K], name: String): KViz = KViz(f(_), name) def apply(f: K => K, name: String): KViz = f match { case f: KViz => f - case _ => new KViz(f, name) + case _ => new KViz(f, name) } } class KViz(f: K => K, name: String) extends (K => K) { - override def apply(input: K): K = { + override def apply(input: K): K = input match { - case c: KToken => f(c) + case c: KToken => f(c) case tc: KApply => f(tc) tc.items.forEach(apply) tc - case _ => throw new AssertionError("Not expected downed term in visitor " + name + " term: " + input) + case _ => + throw new AssertionError("Not expected downed term in visitor " + name + " term: " + input) } - } } diff --git a/kore/src/main/scala/org/kframework/kore/ADT.scala b/kore/src/main/scala/org/kframework/kore/ADT.scala index 1e1c708ed9a..dc9d9cc186c 100644 --- a/kore/src/main/scala/org/kframework/kore/ADT.scala +++ b/kore/src/main/scala/org/kframework/kore/ADT.scala @@ -1,52 +1,55 @@ // Copyright (c) K Team. All Rights Reserved. package org.kframework.kore -import org.kframework.builtin.{KLabels, Sorts} +import collection.JavaConverters._ +import org.kframework.attributes._ +import org.kframework.builtin.KLabels +import org.kframework.builtin.Sorts import org.kframework.kore import org.kframework.kore.KORE.Sort -import org.kframework.attributes._ - -import collection.JavaConverters._ /** * Abstract Data Types: basic implementations for the inner KORE interfaces. * - * Tools using inner KORE data structures can either use these classes directly or have their own implementations. + * Tools using inner KORE data structures can either use these classes directly or have their own + * implementations. */ - object ADT { case class KLabel(name: String, params: kore.Sort*) extends kore.KLabel { - override def toString = { + override def toString = if (params.isEmpty) { name } else { name + "{" + params.map(_.toString).reduce((s1, s2) => s1 + "," + s2) + "}" } - } } - case class KApply[KK <: K](klabel: kore.KLabel, klist: kore.KList, att: Att = Att.empty) extends kore.KApply { - def items = klist.items - def size = klist.size + case class KApply[KK <: K](klabel: kore.KLabel, klist: kore.KList, att: Att = Att.empty) + extends kore.KApply { + def items = klist.items + def size = klist.size def asIterable = klist.asIterable } - class KSequence private(val elements: List[K], val att: Att = Att.empty) extends kore.KSequence { - val items: java.util.List[K] = elements.asJava - val size: Int = elements.size + class KSequence private (val elements: List[K], val att: Att = Att.empty) extends kore.KSequence { + val items: java.util.List[K] = elements.asJava + val size: Int = elements.size val asIterable: java.lang.Iterable[K] = new org.kframework.List(elements) - lazy val kApply: kore.KApply = items.asScala reduceRightOption { (a, b) => KLabels.KSEQ.apply(a, b) } getOrElse { KLabels.DOTK.apply() } match { - case k: kore.KApply => k - case x => KLabels.KSEQ(x, KLabels.DOTK()) - } + lazy val kApply: kore.KApply = + items.asScala.reduceRightOption((a, b) => KLabels.KSEQ.apply(a, b)).getOrElse { + KLabels.DOTK.apply() + } match { + case k: kore.KApply => k + case x => KLabels.KSEQ(x, KLabels.DOTK()) + } def iterator: Iterator[K] = elements.iterator override def equals(that: Any) = that match { case s: KSequence => s.elements == elements - case _ => false + case _ => false } } @@ -57,10 +60,13 @@ object ADT { new KSequence(elements, emptyAtt) def apply(elements: List[K], att: Att = Att.empty): KSequence = - new KSequence(elements.foldLeft(List[K]()) { - case (sum, s: KSequence) => sum ++ s.items.asScala - case (sum, t) => sum :+ t - }, att) + new KSequence( + elements.foldLeft(List[K]()) { + case (sum, s: KSequence) => sum ++ s.items.asScala + case (sum, t) => sum :+ t + }, + att + ) } case class KVariable(name: String, att: Att = Att.empty) extends kore.KVariable { @@ -68,31 +74,29 @@ object ADT { } case class Sort(name: String, params: kore.Sort*) extends kore.Sort { - override def toString = { + override def toString = if (params.isEmpty) { name } else { name + "{" + params.map(_.toString).reduce((s1, s2) => s1 + "," + s2) + "}" } - } } case class SortHead(name: String, params: Int) extends kore.SortHead { - override def toString = { + override def toString = if (params == 0) { name } else { name + "{" + (0 until params).map("S" + _.toString).reduce((s1, s2) => s1 + "," + s2) + "}" } - } } case class KToken(s: String, sort: kore.Sort, att: Att = Att.empty) extends kore.KToken case class KList(elements: List[K]) extends kore.KList { lazy val items: java.util.List[K] = elements.asJava - def iterator: Iterator[K] = elements.iterator - lazy val size = elements.size - lazy val asIterable = new org.kframework.List(elements) + def iterator: Iterator[K] = elements.iterator + lazy val size = elements.size + lazy val asIterable = new org.kframework.List(elements) } case class KRewrite(left: kore.K, right: kore.K, att: Att = Att.empty) extends kore.KRewrite @@ -106,16 +110,17 @@ object ADT { object SortedADT { case class SortedKVariable(name: String, att: Att = Att.empty) extends kore.KVariable { - val sort: Sort = if (att.contains(Att.CELL_SORT)) Sorts.K else att.getOptional(classOf[Sort]).orElse(Sorts.K) + val sort: Sort = + if (att.contains(Att.CELL_SORT)) Sorts.K else att.getOptional(classOf[Sort]).orElse(Sorts.K) def params = Seq() override def equals(other: Any) = other match { case v: SortedKVariable => name == v.name && sort == v.sort - // case v: KVariable => throw new UnsupportedOperationException(s"should not mix SortedKVariables with KVariables for variable $this and $v") + // case v: KVariable => throw new UnsupportedOperationException(s"should not mix + // SortedKVariables with KVariables for variable $this and $v") case _ => false } } } - diff --git a/kore/src/main/scala/org/kframework/kore/Assoc.scala b/kore/src/main/scala/org/kframework/kore/Assoc.scala index 0c90636f841..5afd5ae7073 100644 --- a/kore/src/main/scala/org/kframework/kore/Assoc.scala +++ b/kore/src/main/scala/org/kframework/kore/Assoc.scala @@ -3,7 +3,6 @@ package org.kframework.kore import org.kframework.attributes.Att import org.kframework.definition.Module - import scala.collection.JavaConverters._ /** @@ -11,12 +10,11 @@ import scala.collection.JavaConverters._ */ object Assoc extends { - def flatten(label: KLabel, list: java.util.List[K], m: Module): java.util.List[K] = { + def flatten(label: KLabel, list: java.util.List[K], m: Module): java.util.List[K] = flatten(label, list.asScala, ADT.KLabel(m.attributesFor(label).get(Att.UNIT))).asJava - } - def flatten(label: KLabel, list: java.util.List[K], unit: KToken) : java.util.List[K] = { - list.asScala flatMap { + def flatten(label: KLabel, list: java.util.List[K], unit: KToken): java.util.List[K] = + list.asScala.flatMap { case k: KApply => if (k.klabel == label) flatten(label, k.klist.items, unit).asScala @@ -29,15 +27,13 @@ object Assoc extends { List(k) case other => List(other) } asJava - } - - def flatten(label: KLabel, list: java.util.List[K], unit: KLabel): java.util.List[K] = { + def flatten(label: KLabel, list: java.util.List[K], unit: KLabel): java.util.List[K] = flatten(label, list.asScala, unit).asJava - } - def flatten(label:KLabel, list:Seq[K], unit: KLabel): Seq[K] = { - list flatMap { case k: KApply => + def flatten(label: KLabel, list: Seq[K], unit: KLabel): Seq[K] = + list.flatMap { + case k: KApply => if (k.klabel == label) flatten(label, k.klist.items.asScala, unit) else if (k.klabel == unit) @@ -46,5 +42,4 @@ object Assoc extends { List(k) case other => List(other) } - } } diff --git a/kore/src/main/scala/org/kframework/kore/Constructors.scala b/kore/src/main/scala/org/kframework/kore/Constructors.scala index 1a151d649f8..e9ebfb96237 100644 --- a/kore/src/main/scala/org/kframework/kore/Constructors.scala +++ b/kore/src/main/scala/org/kframework/kore/Constructors.scala @@ -2,7 +2,6 @@ package org.kframework.kore import org.kframework.attributes._ - import scala.collection.JavaConverters._ trait Constructors { @@ -18,23 +17,25 @@ trait Constructors { def InjectedKLabel(klabel: KLabel, att: Att): InjectedKLabel // default methods: - @annotation.varargs def KList(items: K*): KList = KList(items.asJava) - @annotation.varargs def KApply(klabel: KLabel, items: K*): KApply = KApply(klabel, KList(items.asJava), Att.empty) - @annotation.varargs def KSequence(list: K*): KSequence = KSequence(list.toList.asJava, Att.empty) + @annotation.varargs + def KList(items: K*): KList = KList(items.asJava) + @annotation.varargs + def KApply(klabel: KLabel, items: K*): KApply = KApply(klabel, KList(items.asJava), Att.empty) + @annotation.varargs + def KSequence(list: K*): KSequence = KSequence(list.toList.asJava, Att.empty) def KVariable(name: String): KVariable = KVariable(name, Att.empty) def convert(l: KLabel): KLabel = l match { case Unapply.KLabel(name) => KLabel(name) } - def convert(k: K): K = k match { - case t@Unapply.KVariable(name) => KVariable(name, t.att) - case t@Unapply.KToken(v, s) => KToken(v, s, t.att) - case t@Unapply.KRewrite(left, right) => KRewrite(convert(left), convert(right), t.att) - case t@Unapply.KSequence(s) => KSequence((s map convert).asJava, t.att) - case t@Unapply.KApply(label, list) => KApply(label, KList((list map convert).asJava), t.att) + def convert(k: K): K = k match { + case t @ Unapply.KVariable(name) => KVariable(name, t.att) + case t @ Unapply.KToken(v, s) => KToken(v, s, t.att) + case t @ Unapply.KRewrite(left, right) => KRewrite(convert(left), convert(right), t.att) + case t @ Unapply.KSequence(s) => KSequence(s.map(convert).asJava, t.att) + case t @ Unapply.KApply(label, list) => KApply(label, KList(list.map(convert).asJava), t.att) } } abstract class AbstractConstructors extends Constructors - diff --git a/kore/src/main/scala/org/kframework/kore/KORE.scala b/kore/src/main/scala/org/kframework/kore/KORE.scala index 6fb6b5bc607..4dd72fa00a1 100644 --- a/kore/src/main/scala/org/kframework/kore/KORE.scala +++ b/kore/src/main/scala/org/kframework/kore/KORE.scala @@ -1,22 +1,20 @@ // Copyright (c) K Team. All Rights Reserved. package org.kframework.kore -import org.kframework.{CombinerFromBuilder, Collector, attributes} +import collection._ +import collection.JavaConverters._ +import org.kframework.attributes import org.kframework.attributes.Att - +import org.kframework.Collector +import org.kframework.CombinerFromBuilder import scala.collection.mutable.ListBuffer -import collection.JavaConverters._ -import collection._ /** - * - * Basic implementation of a Constructor of inner KORE classes. - * It can be used by either creating a KORE object, or by importing - * the class statically. + * Basic implementation of a Constructor of inner KORE classes. It can be used by either creating a + * KORE object, or by importing the class statically. * * See the wiki for more details: * https://github.com/runtimeverification/k/wiki/KORE-data-structures-guide - * */ object KORE extends Constructors with ScalaSugared { val c = KORE @@ -25,8 +23,8 @@ object KORE extends Constructors with ScalaSugared { lazy val Att = attributes.Att.empty - def Location(startLine: Int, startColumn: Int, endLine: Int, endColumn: Int) = attributes.Location(startLine, - startColumn, endLine, endColumn) + def Location(startLine: Int, startColumn: Int, endLine: Int, endColumn: Int) = + attributes.Location(startLine, startColumn, endLine, endColumn) def KApply(klabel: KLabel, klist: KList): KApply = KApply(klabel, klist, Att) @@ -46,23 +44,26 @@ object KORE extends Constructors with ScalaSugared { // def toKSequence: Collector[K, KSequence] = // Collector(() => new CombinerFromBuilder(KSequence.newBuilder())) - @annotation.varargs override def KLabel(name: String, params: Sort*): KLabel = ADT.KLabel(name, params:_*) + @annotation.varargs + override def KLabel(name: String, params: Sort*): KLabel = ADT.KLabel(name, params: _*) - override def KApply(klabel: KLabel, klist: KList, att: Att): KApply = ADT.KApply(klabel, klist, att) + override def KApply(klabel: KLabel, klist: KList, att: Att): KApply = + ADT.KApply(klabel, klist, att) - override def KSequence(items: java.util.List[K], att: Att): KSequence = ADT.KSequence(items.asScala - .toList, att) + override def KSequence(items: java.util.List[K], att: Att): KSequence = + ADT.KSequence(items.asScala.toList, att) override def KVariable(name: String, att: Att): KVariable = ADT.KVariable(name, att) - @annotation.varargs override def Sort(name: String, params: Sort*): Sort = ADT.Sort(name, params:_*) + @annotation.varargs + override def Sort(name: String, params: Sort*): Sort = ADT.Sort(name, params: _*) def Sort(name: SortHead): Sort = { assert(name.params == 0) ADT.Sort(name.name) } - def Sort(name: String, params: java.util.List[Sort]): Sort = ADT.Sort(name, params.asScala:_*) + def Sort(name: String, params: java.util.List[Sort]): Sort = ADT.Sort(name, params.asScala: _*) def SortHead(name: String, params: Int): SortHead = ADT.SortHead(name, params) @@ -76,9 +77,11 @@ object KORE extends Constructors with ScalaSugared { def KList(items: List[K]): KList = ADT.KList(items) - override def InjectedKLabel(klabel: KLabel, att: Att): InjectedKLabel = ADT.InjectedKLabel(klabel, att) + override def InjectedKLabel(klabel: KLabel, att: Att): InjectedKLabel = + ADT.InjectedKLabel(klabel, att) def self = this - @annotation.varargs override def KApply(klabel: KLabel, items: K*): KApply = KApply(klabel, KList(items.asJava), Att) + @annotation.varargs + override def KApply(klabel: KLabel, items: K*): KApply = KApply(klabel, KList(items.asJava), Att) } diff --git a/kore/src/main/scala/org/kframework/kore/Rich.scala b/kore/src/main/scala/org/kframework/kore/Rich.scala index dc0fedebfb3..d402691809e 100644 --- a/kore/src/main/scala/org/kframework/kore/Rich.scala +++ b/kore/src/main/scala/org/kframework/kore/Rich.scala @@ -1,16 +1,15 @@ // Copyright (c) K Team. All Rights Reserved. package org.kframework.kore +import collection.JavaConverters._ import org.kframework.attributes.Att import org.kframework.definition.Module -import collection.JavaConverters._ case class Rich(theModule: Module) { private val module = theModule - implicit class RichKApply(k: KApply) { - } + implicit class RichKApply(k: KApply) {} implicit class RichKLabel(klabel: KLabel) { def productions = module.productionsFor(klabel) diff --git a/kore/src/main/scala/org/kframework/kore/ScalaSugar.scala b/kore/src/main/scala/org/kframework/kore/ScalaSugar.scala index 77e85fb1d27..ec9db531bfc 100644 --- a/kore/src/main/scala/org/kframework/kore/ScalaSugar.scala +++ b/kore/src/main/scala/org/kframework/kore/ScalaSugar.scala @@ -2,9 +2,9 @@ package org.kframework.kore import org.kframework.attributes.Att -import org.kframework.builtin.{KLabels, Sorts} +import org.kframework.builtin.KLabels +import org.kframework.builtin.Sorts import org.kframework.kore - import scala.collection.JavaConverters._ trait ScalaSugared { @@ -13,28 +13,29 @@ trait ScalaSugared { import c._ implicit def stringToToken(s: String) = KToken(s, Sorts.String, Att.empty) - def stringToId(s: String): K = KToken(s, Sorts.Id, Att.empty) + def stringToId(s: String): K = KToken(s, Sorts.Id, Att.empty) implicit def symbolToLabel(l: Symbol) = KLabel(l.name) - implicit def intToToken(n: Int): K = KToken(n.toString, Sorts.Int, Att.empty) + implicit def intToToken(n: Int): K = KToken(n.toString, Sorts.Int, Att.empty) implicit class ApplicableKLabel(klabel: KLabel) { def apply(l: K*): K = c.KApply(klabel, l: _*) } implicit class EnhancedK(k: K) { - def ~>(other: K) = KSequence(Seq(k, other).asJava, Att.empty) + def ~>(other: K) = KSequence(Seq(k, other).asJava, Att.empty) def ==>(other: K) = KRewrite(k, other, Att.empty) - def +(other: K) = KLabel("+")(k, other) - def -(other: K) = KLabel("-")(k, other) - def *(other: K) = KLabel("*")(k, other) - def /(other: K) = KLabel("/")(k, other) - def &(other: K) = KLabel("&")(k, other) - def ~(other: K) = KLabel("~")(k, other) - def &&(other: K) = KLabels.AND.apply(k, other) - def ||(other: K) = KLabels.OR.apply(k, other) + def +(other: K) = KLabel("+")(k, other) + def -(other: K) = KLabel("-")(k, other) + def *(other: K) = KLabel("*")(k, other) + def /(other: K) = KLabel("/")(k, other) + def &(other: K) = KLabel("&")(k, other) + def ~(other: K) = KLabel("~")(k, other) + def &&(other: K) = KLabels.AND.apply(k, other) + def ||(other: K) = KLabels.OR.apply(k, other) } def KList(ks: Seq[K]): KList = c.KList(ks.asJava) - def KApply(klabel: KLabel, ks: Seq[K], att: Att = Att.empty): KApply = c.KApply(klabel, c.KList(ks.asJava), att) + def KApply(klabel: KLabel, ks: Seq[K], att: Att = Att.empty): KApply = + c.KApply(klabel, c.KList(ks.asJava), att) } diff --git a/kore/src/main/scala/org/kframework/kore/Unapply.scala b/kore/src/main/scala/org/kframework/kore/Unapply.scala index 53eb32dac32..eb70f8078ff 100644 --- a/kore/src/main/scala/org/kframework/kore/Unapply.scala +++ b/kore/src/main/scala/org/kframework/kore/Unapply.scala @@ -1,8 +1,8 @@ // Copyright (c) K Team. All Rights Reserved. package org.kframework.kore -import org.kframework.kore import collection.JavaConverters._ +import org.kframework.kore /** * Scala deconstructors for inner KORE objects. diff --git a/kore/src/main/scala/org/kframework/kore/interface.scala b/kore/src/main/scala/org/kframework/kore/interface.scala index 6e6d8486416..cfd6a12600c 100644 --- a/kore/src/main/scala/org/kframework/kore/interface.scala +++ b/kore/src/main/scala/org/kframework/kore/interface.scala @@ -2,16 +2,13 @@ package org.kframework.kore import java.util.Optional - import org.kframework.attributes._ import org.kframework.unparser.ToKast import org.kframework.utils.errorsystem.KEMException - import scala.collection.JavaConverters._ /** - * This file contains all inner KORE interfaces. - * The the wiki for documentation: + * This file contains all inner KORE interfaces. The the wiki for documentation: * https://github.com/runtimeverification/k/wiki/KORE-data-structures-guide */ @@ -26,7 +23,7 @@ trait K extends Serializable with HasLocation with AttValue { def computeHashCode: Int def location: Optional[Location] = att.getOptional(classOf[Location]) - def source: Optional[Source] = att.getOptional(classOf[Source]) + def source: Optional[Source] = att.getOptional(classOf[Source]) } object K { @@ -34,28 +31,38 @@ object K { def compare(a: K, b: K): Int = { import scala.math.Ordering.Implicits._ (a, b) match { - case (c: KToken, d: KToken) => Ordering.Tuple2(Ordering[String], Ordering[Sort]).compare((c.s, c.sort), (d.s, d.sort)) - case (c: KApply, d: KApply) => Ordering.Tuple2(KLabelOrdering, seqDerivedOrdering[Seq, K](this)).compare((c.klabel, c.klist.items.asScala), (d.klabel, d.klist.items.asScala)) - case (c: KSequence, d: KSequence) => seqDerivedOrdering(this).compare(c.items.asScala, d.items.asScala) + case (c: KToken, d: KToken) => + Ordering.Tuple2(Ordering[String], Ordering[Sort]).compare((c.s, c.sort), (d.s, d.sort)) + case (c: KApply, d: KApply) => + Ordering + .Tuple2(KLabelOrdering, seqDerivedOrdering[Seq, K](this)) + .compare((c.klabel, c.klist.items.asScala), (d.klabel, d.klist.items.asScala)) + case (c: KSequence, d: KSequence) => + seqDerivedOrdering(this).compare(c.items.asScala, d.items.asScala) case (c: KVariable, d: KVariable) => Ordering[String].compare(c.name, d.name) - case (c: KAs, d: KAs) => Ordering.Tuple2(this, this).compare((c.pattern, c.alias), (d.pattern, d.alias)) - case (c: KRewrite, d: KRewrite) => Ordering.Tuple2(this, this).compare((c.left, c.right), (d.left, d.right)) + case (c: KAs, d: KAs) => + Ordering.Tuple2(this, this).compare((c.pattern, c.alias), (d.pattern, d.alias)) + case (c: KRewrite, d: KRewrite) => + Ordering.Tuple2(this, this).compare((c.left, c.right), (d.left, d.right)) case (c: InjectedKLabel, d: InjectedKLabel) => KLabelOrdering.compare(c.klabel, d.klabel) - case (_:KToken, _) => 1 - case (_, _:KToken) => -1 - case (_:KApply, _) => 1 - case (_, _:KApply) => -1 - case (_:KSequence, _) => 1 - case (_, _:KSequence) => -1 - case (_:KVariable, _) => 1 - case (_, _:KVariable) => -1 - case (_:KAs, _) => 1 - case (_, _:KAs) => -1 - case (_:KRewrite, _) => 1 - case (_, _:KRewrite) => -1 - case (_:InjectedKLabel, _) => 1 - case (_, _:InjectedKLabel) => -1 - case (_, _) => throw KEMException.internalError("Cannot order these terms:\n" + a.toString() + "\n" + b.toString()) + case (_: KToken, _) => 1 + case (_, _: KToken) => -1 + case (_: KApply, _) => 1 + case (_, _: KApply) => -1 + case (_: KSequence, _) => 1 + case (_, _: KSequence) => -1 + case (_: KVariable, _) => 1 + case (_, _: KVariable) => -1 + case (_: KAs, _) => 1 + case (_, _: KAs) => -1 + case (_: KRewrite, _) => 1 + case (_, _: KRewrite) => -1 + case (_: InjectedKLabel, _) => 1 + case (_, _: InjectedKLabel) => -1 + case (_, _) => + throw KEMException.internalError( + "Cannot order these terms:\n" + a.toString() + "\n" + b.toString() + ) } } } @@ -68,7 +75,7 @@ trait KLabel extends AttValue { def params: Seq[Sort] override def equals(other: Any) = other match { case l: KLabel => name == l.name && params == l.params - case _ => false + case _ => false } override def hashCode = name.hashCode * 29 + params.hashCode @@ -80,7 +87,9 @@ trait KLabel extends AttValue { object KLabelOrdering extends Ordering[KLabel] { def compare(a: KLabel, b: KLabel): Int = { import scala.math.Ordering.Implicits._ - Ordering.Tuple2(Ordering[String], seqDerivedOrdering[Seq, Sort](Ordering[Sort])).compare((a.name, a.params), (b.name, b.params)) + Ordering + .Tuple2(Ordering[String], seqDerivedOrdering[Seq, Sort](Ordering[Sort])) + .compare((a.name, a.params), (b.name, b.params)) } } @@ -89,7 +98,7 @@ trait KToken extends KItem { def s: String override def equals(other: Any) = other match { case other: KToken => sort == other.sort && s == other.s - case _ => false + case _ => false } def computeHashCode = sort.hashCode() * 13 + s.hashCode } @@ -99,35 +108,34 @@ trait Sort extends Ordered[Sort] with AttValue { def params: Seq[Sort] override def equals(other: Any) = other match { case other: Sort => name == other.name && params == other.params - case _ => false + case _ => false } override def hashCode = name.hashCode * 23 + params.hashCode - + def compare(that: Sort): Int = { import scala.math.Ordering.Implicits._ - Ordering.Tuple2(Ordering[String], seqDerivedOrdering[Seq, Sort](Ordering.ordered(identity))).compare((this.name, this.params), (this.name, this.params)) + Ordering + .Tuple2(Ordering[String], seqDerivedOrdering[Seq, Sort](Ordering.ordered(identity))) + .compare((this.name, this.params), (this.name, this.params)) } def head: SortHead = ADT.SortHead(name, params.size) - def substitute(subst: Map[Sort, Sort]): Sort = { - ADT.Sort(name, params.map(p => subst.getOrElse(p, p.substitute(subst))):_*) - } + def substitute(subst: Map[Sort, Sort]): Sort = + ADT.Sort(name, params.map(p => subst.getOrElse(p, p.substitute(subst))): _*) - def contains(sort: Sort): Boolean = { + def contains(sort: Sort): Boolean = this == sort || params.exists(_.contains(sort)) - } override def toString: String = name + (if (params.nonEmpty) "{" + params.mkString(",") + "}") - lazy val isNat: Boolean = { + lazy val isNat: Boolean = try { name.toInt true } catch { - case _:NumberFormatException => false + case _: NumberFormatException => false } - } } trait SortHead extends Ordered[SortHead] { @@ -135,14 +143,14 @@ trait SortHead extends Ordered[SortHead] { def params: Int override def equals(other: Any) = other match { case other: SortHead => name == other.name && params == other.params - case _ => false + case _ => false } override def hashCode = name.hashCode * 23 + params.hashCode - def compare(that: SortHead): Int = { - Ordering.Tuple2(Ordering[String], Ordering[Int]).compare((this.name, this.params), (this.name, this.params)) - } - + def compare(that: SortHead): Int = + Ordering + .Tuple2(Ordering[String], Ordering[Int]) + .compare((this.name, this.params), (this.name, this.params)) } @@ -155,15 +163,14 @@ trait KCollection { override def equals(that: Any): Boolean = hashCode == that.hashCode && (that match { case that: AnyRef if that.asInstanceOf[AnyRef] eq this => true - case that: KCollection => this.items == that.items - case _ => false + case that: KCollection => this.items == that.items + case _ => false }) def computeHashCode = items.hashCode } -trait KList extends KCollection with AttValue { -} +trait KList extends KCollection with AttValue {} trait KApply extends KItem with KCollection { def klabel: KLabel @@ -196,7 +203,7 @@ trait KAs extends K { hashCode == that.hashCode && (that match { case that: AnyRef if that.asInstanceOf[AnyRef] eq this => true case that: KAs => this.pattern == that.pattern && this.alias == that.alias - case _ => false + case _ => false }) def computeHashCode = pattern.hashCode * 19 + alias.hashCode @@ -210,7 +217,7 @@ trait KRewrite extends K { hashCode == that.hashCode && (that match { case that: AnyRef if that.asInstanceOf[AnyRef] eq this => true case that: KRewrite => this.left == that.left && this.right == that.right - case _ => false + case _ => false }) def computeHashCode = left.hashCode * 19 + right.hashCode @@ -222,8 +229,8 @@ trait InjectedKLabel extends KItem { override def equals(that: Any): Boolean = hashCode == that.hashCode && (that match { case that: AnyRef if that.asInstanceOf[AnyRef] eq this => true - case that: InjectedKLabel => this.klabel == that.klabel - case _ => false + case that: InjectedKLabel => this.klabel == that.klabel + case _ => false }) def computeHashCode = klabel.hashCode diff --git a/kore/src/main/scala/org/kframework/kore/transformers.scala b/kore/src/main/scala/org/kframework/kore/transformers.scala index bedf054fe9c..31e4ef7c4cc 100644 --- a/kore/src/main/scala/org/kframework/kore/transformers.scala +++ b/kore/src/main/scala/org/kframework/kore/transformers.scala @@ -8,13 +8,13 @@ import JavaConverters._ trait KTransformer[T] extends ((K) => T) with java.util.function.Function[K, T] { def apply(k: K): T = k match { - case k: KApply => apply(k: KApply) - case k: KRewrite => apply(k) - case k: KToken => apply(k) - case k: KVariable => apply(k) - case k: KSequence => apply(k: KSequence) + case k: KApply => apply(k: KApply) + case k: KRewrite => apply(k) + case k: KToken => apply(k) + case k: KVariable => apply(k) + case k: KSequence => apply(k: KSequence) case k: InjectedKLabel => apply(k) - case k: KAs => apply(k) + case k: KAs => apply(k) } def apply(k: KApply): T @@ -33,8 +33,9 @@ trait KTransformer[T] extends ((K) => T) with java.util.function.Function[K, T] } /** - * Folds a K term into a T. T must be a monoid with the identity defined by unit and the operation by merge. - */ + * Folds a K term into a T. T must be a monoid with the identity defined by unit and the operation + * by merge. + */ abstract class FoldK[T] extends KTransformer[T] { def apply(k: KApply): T = merge( @@ -56,7 +57,7 @@ abstract class FoldK[T] extends KTransformer[T] { def apply(k: InjectedKLabel): T = k match { case v: KVariable => apply(v.asInstanceOf[KVariable]) - case _ => unit + case _ => unit } def unit: T @@ -64,9 +65,7 @@ abstract class FoldK[T] extends KTransformer[T] { def merge(a: T, b: T): T } -trait FoldKSetTransformer[E] extends FoldK[Set[E]] { - -} +trait FoldKSetTransformer[E] extends FoldK[Set[E]] {} class KVisitor extends java.util.function.Consumer[K] { @@ -74,22 +73,22 @@ class KVisitor extends java.util.function.Consumer[K] { def apply(k: K) { k match { - case k: KApply => apply(k: KApply) - case k: KRewrite => apply(k) - case k: KToken => apply(k) - case k: KVariable => apply(k) - case k: KSequence => apply(k: KSequence) + case k: KApply => apply(k: KApply) + case k: KRewrite => apply(k) + case k: KToken => apply(k) + case k: KVariable => apply(k) + case k: KSequence => apply(k: KSequence) case k: InjectedKLabel => apply(k) - case k: KAs => apply(k) + case k: KAs => apply(k) } } def apply(k: KApply): Unit = { k.klabel match { case k: InjectedKLabel => apply(k) - case _ => + case _ => } - k.items forEach apply + k.items.forEach(apply) } def apply(k: KRewrite): Unit = { @@ -106,13 +105,12 @@ class KVisitor extends java.util.function.Consumer[K] { def apply(k: KVariable): Unit = {} - def apply(k: KSequence): Unit = { - k.items forEach apply - } + def apply(k: KSequence): Unit = + k.items.forEach(apply) def apply(k: InjectedKLabel): Unit = k match { case v: KVariable => apply(v.asInstanceOf[KVariable]) - case _ => + case _ => } } diff --git a/kore/src/main/scala/org/kframework/parser/Transformer.scala b/kore/src/main/scala/org/kframework/parser/Transformer.scala index bf1305b6a75..b59a0eb94c2 100644 --- a/kore/src/main/scala/org/kframework/parser/Transformer.scala +++ b/kore/src/main/scala/org/kframework/parser/Transformer.scala @@ -2,12 +2,10 @@ package org.kframework.parser -import org.kframework.Collections._ - import java.util +import org.kframework.Collections._ import scala.collection.JavaConverters._ - class Ignore object Ignore extends Ignore @@ -16,49 +14,52 @@ abstract class ChildrenMapping[E, W] { def applyTerm(t: Term): (Either[E, Term], W) - protected def simpleError(err:E) : (Either[E, Term], W) = (Left(err),warningUnit) - protected def simpleResult(result:Term): (Either[E, Term], W) = (Right(result),warningUnit) + protected def simpleError(err: E): (Either[E, Term], W) = (Left(err), warningUnit) + protected def simpleResult(result: Term): (Either[E, Term], W) = (Right(result), warningUnit) /** - * Transforms all children of the current item. If any of them is problematic, - * it merge(...)es all problems and returns Left(...). - * If everything is ok, replace children, and merge all warnings. + * Transforms all children of the current item. If any of them is problematic, it merge(...)es all + * problems and returns Left(...). If everything is ok, replace children, and merge all warnings. */ def mapChildrenStrict(t: HasChildren): (Either[E, Term], W) = { val allResults = t.items.asScala.map(applyTerm) // visit all children val (eithers: Iterable[Either[E, Term]], warnings: Iterable[W]) = allResults.unzip val mergedWarnings = warnings.foldLeft(warningUnit)(mergeWarnings) - if (eithers.exists { t => t.isLeft }) { - val mergedErrors = (eithers collect { case Left(err) => err }).foldLeft(errorUnit)(mergeErrors) + if (eithers.exists(t => t.isLeft)) { + val mergedErrors = eithers.collect { case Left(err) => err }.foldLeft(errorUnit)(mergeErrors) (Left(mergedErrors), mergedWarnings) } else { - val newChildren: Iterable[Term] = eithers map { _.right.get } + val newChildren: Iterable[Term] = eithers.map(_.right.get) (Right(t.replaceChildren(newChildren.asJavaCollection)), mergedWarnings) } } /** * Transforms all children of the current item: - * - if all children are problematic (i.e., Left(...)), then return the - * merge(...) of all problems. - * - if one child is left, return that child. - * - otherwise, i.e., a few of the children are correct, disregard all problems and - * replace the children of the current element with the correct transformed children. + * - if all children are problematic (i.e., Left(...)), then return the merge(...) of all + * problems. + * - if one child is left, return that child. + * - otherwise, i.e., a few of the children are correct, disregard all problems and replace the + * children of the current element with the correct transformed children. */ def mapChildren(t: HasChildren): (Either[E, Term], W) = { val allResults1 = t.items.asScala.map(applyTerm) // visit all children - val allResults = allResults1 flatMap { - case (Right(Ambiguity(items)), warns) => immutable(items) map { t => (Right(t): Either[E, Term], warns) } - case x => Set(x) - } + val allResults = allResults1.flatMap { + case (Right(Ambiguity(items)), warns) => + immutable(items).map(t => (Right(t): Either[E, Term], warns)) + case x => Set(x) + } val (eithers: Iterable[Either[E, Term]], warnings: Iterable[W]) = allResults.unzip - val newCorrectItems: List[(Term, W)] = allResults.collect { case (Right(v), w) => (v, w) }.toList + val newCorrectItems: List[(Term, W)] = allResults.collect { case (Right(v), w) => + (v, w) + }.toList newCorrectItems match { case List() => val mergedWarnings = warnings.foldLeft(warningUnit)(mergeWarnings) - val mergedErrors = (eithers collect { case Left(err) => err }).foldLeft(errorUnit)(mergeErrors) + val mergedErrors = + eithers.collect { case Left(err) => err }.foldLeft(errorUnit)(mergeErrors) (Left(mergedErrors), mergedWarnings) case List((term, w)) => (Right(term), w) case l => @@ -75,6 +76,7 @@ abstract class ChildrenMapping[E, W] { val warningUnit: W val errorUnit: E + /** * Merges the set of problematic (i.e., Left) results. */ @@ -82,11 +84,12 @@ abstract class ChildrenMapping[E, W] { } /** - * Visitor pattern for the front end classes. - * Applies the visitor transformation on each node, and returns a tuple of either a term, or a set of errors, and - * a set of possible warnings. - * @tparam E container for errors. - * @tparam W container for warnings. + * Visitor pattern for the front end classes. Applies the visitor transformation on each node, and + * returns a tuple of either a term, or a set of errors, and a set of possible warnings. + * @tparam E + * container for errors. + * @tparam W + * container for warnings. */ abstract class GeneralTransformer[E, W] extends ChildrenMapping[E, W] { // we expect this data structures to represent a DAG, so we @@ -101,7 +104,7 @@ abstract class GeneralTransformer[E, W] extends ChildrenMapping[E, W] { } val res = t match { - case a: Ambiguity => apply(a) + case a: Ambiguity => apply(a) case p: ProductionReference => apply(p) } cache.put(t, res) @@ -110,16 +113,17 @@ abstract class GeneralTransformer[E, W] extends ChildrenMapping[E, W] { def apply(p: ProductionReference): (Either[E, Term], W) = p match { case tc: TermCons => apply(tc) - case c: Constant => apply(c) + case c: Constant => apply(c) } def apply(a: Ambiguity): (Either[E, Term], W) = mapChildren(a) def apply(tc: TermCons): (Either[E, Term], W) = mapChildrenStrict(tc) - def apply(c: Constant): (Either[E, Term], W) = simpleResult(c) + def apply(c: Constant): (Either[E, Term], W) = simpleResult(c) } abstract class SetsGeneralTransformer[E, W] - extends GeneralTransformer[java.util.Set[E], java.util.Set[W]] { + extends GeneralTransformer[java.util.Set[E], java.util.Set[W]] { + /** * Merges the set of problematic (i.e., Left) results. */ @@ -144,9 +148,10 @@ abstract class SetsGeneralTransformer[E, W] } /** - * Visitor pattern for the front end classes. - * Applies the visitor transformation on each node, and returns either a term, or a set of errors. (no warnings) - * @tparam E container for errors. + * Visitor pattern for the front end classes. Applies the visitor transformation on each node, and + * returns either a term, or a set of errors. (no warnings) + * @tparam E + * container for errors. */ abstract class TransformerWithErrors[E] extends ChildrenMapping[E, Ignore] { @@ -161,7 +166,7 @@ abstract class TransformerWithErrors[E] extends ChildrenMapping[E, Ignore] { } val res = t match { - case a: Ambiguity => apply(a) + case a: Ambiguity => apply(a) case p: ProductionReference => apply(p) } cache.put(t, res) @@ -170,19 +175,19 @@ abstract class TransformerWithErrors[E] extends ChildrenMapping[E, Ignore] { def apply(p: ProductionReference): Either[E, Term] = p match { case tc: TermCons => apply(tc) - case c: Constant => apply(c) + case c: Constant => apply(c) } def apply(a: Ambiguity): Either[E, Term] = mapChildren(a)._1 def apply(tc: TermCons): Either[E, Term] = mapChildrenStrict(tc)._1 - def apply(c: Constant): Either[E, Term] = Right(c) + def apply(c: Constant): Either[E, Term] = Right(c) override def mergeWarnings(a: Ignore, b: Ignore): Ignore = Ignore - override val warningUnit: Ignore = Ignore + override val warningUnit: Ignore = Ignore } -abstract class SetsTransformerWithErrors[E] - extends TransformerWithErrors[java.util.Set[E]] { +abstract class SetsTransformerWithErrors[E] extends TransformerWithErrors[java.util.Set[E]] { + /** * Merges the set of problematic (i.e., Left) results. */ @@ -196,8 +201,8 @@ abstract class SetsTransformerWithErrors[E] } /** - * Visitor pattern for the front end classes. - * Applies the visitor transformation on each node, and returns a term. (no errors and no warnings) + * Visitor pattern for the front end classes. Applies the visitor transformation on each node, and + * returns a term. (no errors and no warnings) */ abstract class SafeTransformer extends ChildrenMapping[Ignore, Ignore] { @@ -212,7 +217,7 @@ abstract class SafeTransformer extends ChildrenMapping[Ignore, Ignore] { } val res = t match { - case a: Ambiguity => apply(a) + case a: Ambiguity => apply(a) case p: ProductionReference => apply(p) } cache.put(t, res) @@ -221,15 +226,15 @@ abstract class SafeTransformer extends ChildrenMapping[Ignore, Ignore] { def apply(p: ProductionReference): Term = p match { case tc: TermCons => apply(tc) - case c: Constant => apply(c) + case c: Constant => apply(c) } def apply(a: Ambiguity): Term = mapChildren(a)._1.right.get def apply(tc: TermCons): Term = mapChildrenStrict(tc)._1.right.get - def apply(c: Constant): Term = c + def apply(c: Constant): Term = c def mergeWarnings(a: Ignore, b: Ignore): Ignore = Ignore - val warningUnit: Ignore = Ignore - def mergeErrors(a: Ignore, b: Ignore): Ignore = Ignore - val errorUnit: Ignore = Ignore + val warningUnit: Ignore = Ignore + def mergeErrors(a: Ignore, b: Ignore): Ignore = Ignore + val errorUnit: Ignore = Ignore } diff --git a/kore/src/main/scala/org/kframework/parser/TreeNodesToKORE.scala b/kore/src/main/scala/org/kframework/parser/TreeNodesToKORE.scala index e59c04ee5c6..f4c6c162219 100644 --- a/kore/src/main/scala/org/kframework/parser/TreeNodesToKORE.scala +++ b/kore/src/main/scala/org/kframework/parser/TreeNodesToKORE.scala @@ -3,94 +3,127 @@ package org.kframework.parser import java.util import java.util.Optional - -import org.kframework.attributes.{Att, Location, Source} +import org.kframework.{ kore => k } +import org.kframework.attributes.Att +import org.kframework.attributes.Location +import org.kframework.attributes.Source import org.kframework.builtin.Sorts import org.kframework.definition.Production -import org.kframework.{kore => k} -import org.kframework.kore.Unapply._ import org.kframework.kore._ +import org.kframework.kore.Unapply._ import org.kframework.utils.errorsystem.KEMException - import scala.collection.JavaConverters._ class TreeNodesToKORE(parseSort: java.util.function.Function[String, Sort]) { - import org.kframework.kore.KORE.{KApply, KLabel, KList, KToken, KVariable, KSequence, KAs, KRewrite, InjectedKLabel} + import org.kframework.kore.KORE.InjectedKLabel + import org.kframework.kore.KORE.KApply + import org.kframework.kore.KORE.KAs + import org.kframework.kore.KORE.KLabel + import org.kframework.kore.KORE.KList + import org.kframework.kore.KORE.KRewrite + import org.kframework.kore.KORE.KSequence + import org.kframework.kore.KORE.KToken + import org.kframework.kore.KORE.KVariable def apply(t: Term): K = t match { - case c@Constant(s, p) => KToken(s, p.sort, locationToAtt(c.location, c.source) - .add(classOf[Production], c.production.att.getOption(Att.ORIGINAL_PRD, classOf[Production]).getOrElse(c.production))) - case t@TermCons(_, _) => termConsToKApply(t) - case Ambiguity(items) => KApply(KLabel("amb"), KList(items.asScala.toList map apply asJava), Att.empty) + case c @ Constant(s, p) => + KToken( + s, + p.sort, + locationToAtt(c.location, c.source) + .add( + classOf[Production], + c.production.att + .getOption(Att.ORIGINAL_PRD, classOf[Production]) + .getOrElse(c.production) + ) + ) + case t @ TermCons(_, _) => termConsToKApply(t) + case Ambiguity(items) => + KApply(KLabel("amb"), KList(items.asScala.toList.map(apply) asJava), Att.empty) } def termConsToKApply(t: TermCons): K = { - val realProd = if (t.production.att.contains(Att.ORIGINAL_PRD, classOf[Production])) t.production.att.get(Att.ORIGINAL_PRD, classOf[Production]) else t.production + val realProd = + if (t.production.att.contains(Att.ORIGINAL_PRD, classOf[Production])) + t.production.att.get(Att.ORIGINAL_PRD, classOf[Production]) + else t.production if (t.production.att.contains(Att.BRACKET)) return apply(t.items.get(0)) if (t.production.klabel.isEmpty) throw KEMException.internalError("Missing klabel in production: " + t.production, t) - val klabel = if (t.production.klabel.get.name == "#OuterCast") KLabel("project:" ++ t.production.sort.toString) else t.production.klabel.get - KApply(klabel.head, KList(new util.ArrayList(t.items).asScala.reverse map apply asJava), locationToAtt(t.location, t.source).add(classOf[Production], realProd)) + val klabel = + if (t.production.klabel.get.name == "#OuterCast") + KLabel("project:" ++ t.production.sort.toString) + else t.production.klabel.get + KApply( + klabel.head, + KList(new util.ArrayList(t.items).asScala.reverse.map(apply) asJava), + locationToAtt(t.location, t.source).add(classOf[Production], realProd) + ) } def down(t: K): K = t match { - case t@KToken(s, sort) if sort == Sorts.KVariable => + case t @ KToken(s, sort) if sort == Sorts.KVariable => KVariable(s.trim, t.att) case t: k.KToken => t - case t@KApply(KLabel("#KSequence"), items) => + case t @ KApply(KLabel("#KSequence"), items) => KSequence(downList(items).asJava, t.att) case KApply(KLabel("#EmptyK"), items) if items.isEmpty => KSequence(List.empty[K].asJava, t.att) - case t@KApply(KLabel("#KRewrite"), items) => - val it = items.iterator + case t @ KApply(KLabel("#KRewrite"), items) => + val it = items.iterator val res = KRewrite(down(it.next()), down(it.next()), t.att) assert(!it.hasNext) res + case t @ KApply(KLabel("#KApply"), items) => + KApply( + downKLabel(items(0)), + KList(downList(Assoc.flatten(KLabel("#KList"), items.tail, KLabel("#EmptyKList")))), + t.att + ) - case t@KApply(KLabel("#KApply"), items) => - KApply(downKLabel(items(0)), - KList(downList(Assoc.flatten(KLabel("#KList"), items.tail, KLabel("#EmptyKList")))), t.att) - - case t@KApply(KLabel("#KAs"), items) => - val it = items.iterator + case t @ KApply(KLabel("#KAs"), items) => + val it = items.iterator val res = KAs(down(it.next()), down(it.next()), t.att) assert(!it.hasNext) res - case t@KApply(KLabel("#WrappedKLabel"), items) => + case t @ KApply(KLabel("#WrappedKLabel"), items) => InjectedKLabel(downKLabel(items(0)), t.att) - case t@KApply(KLabel("#KToken"), items) => + case t @ KApply(KLabel("#KToken"), items) => def removeQuotes(s: String) = s.drop(1).dropRight(1).replace("\\\"", "\"") - KToken(removeQuotes(items.head.asInstanceOf[KToken].s), parseSort(removeQuotes(items.tail.head.asInstanceOf[KToken].s)), t.att) + KToken( + removeQuotes(items.head.asInstanceOf[KToken].s), + parseSort(removeQuotes(items.tail.head.asInstanceOf[KToken].s)), + t.att + ) - case t@KApply(l, items) => - KApply(l, KList((items map down _).asJava), t.att) + case t @ KApply(l, items) => + KApply(l, KList(items.map(down _).asJava), t.att) } - def unquote(t: K): String = { + def unquote(t: K): String = t.asInstanceOf[KToken].s.stripPrefix("`").stripSuffix("`") - } - def downList(items: Seq[K]): Seq[K] = { - items map down _ - } + def downList(items: Seq[K]): Seq[K] = + items.map(down _) def downKLabel(t: K): KLabel = t match { - case t@KToken(s, sort) if sort == Sorts.KVariable => + case t @ KToken(s, sort) if sort == Sorts.KVariable => KVariable(s.trim, t.att) - case t@KToken(s, sort) if sort == Sorts.KLabel => + case t @ KToken(s, sort) if sort == Sorts.KLabel => KLabel(unquote(t)) - case t@KApply(KLabel(s), items) if s.startsWith("#SemanticCastTo") => + case t @ KApply(KLabel(s), items) if s.startsWith("#SemanticCastTo") => downKLabel(items.head) } diff --git a/kore/src/main/scala/org/kframework/parser/kore/Default.scala b/kore/src/main/scala/org/kframework/parser/kore/Default.scala index c7c2b2b9e47..ac990141273 100644 --- a/kore/src/main/scala/org/kframework/parser/kore/Default.scala +++ b/kore/src/main/scala/org/kframework/parser/kore/Default.scala @@ -1,7 +1,7 @@ // Copyright (c) K Team. All Rights Reserved. package org.kframework.parser.kore -import org.kframework.parser.{kore => i} +import org.kframework.parser.{ kore => i } object implementation { @@ -13,19 +13,40 @@ object implementation { case class Import(name: String, att: i.Attributes) extends i.Import - case class SortDeclaration(params: Seq[i.SortVariable], sort: i.Sort, att: i.Attributes) extends i.SortDeclaration - - case class HookSortDeclaration(params: Seq[i.SortVariable], sort: i.Sort, att: i.Attributes) extends i.HookSortDeclaration - - case class SymbolDeclaration(symbol: i.Symbol, argSorts: Seq[i.Sort], returnSort: i.Sort, att: i.Attributes) extends i.SymbolDeclaration - - case class HookSymbolDeclaration(symbol: i.Symbol, argSorts: Seq[i.Sort], returnSort: i.Sort, att: i.Attributes) extends i.HookSymbolDeclaration - - case class AliasDeclaration(alias: i.Alias, argSorts: Seq[i.Sort], returnSort: i.Sort, leftPattern: i.Pattern, rightPattern: i.Pattern, att: i.Attributes) extends i.AliasDeclaration - - case class AxiomDeclaration(params: Seq[i.SortVariable], pattern: i.Pattern, att: i.Attributes) extends i.AxiomDeclaration - - case class ClaimDeclaration(params: Seq[i.SortVariable], pattern: i.Pattern, att: i.Attributes) extends i.ClaimDeclaration + case class SortDeclaration(params: Seq[i.SortVariable], sort: i.Sort, att: i.Attributes) + extends i.SortDeclaration + + case class HookSortDeclaration(params: Seq[i.SortVariable], sort: i.Sort, att: i.Attributes) + extends i.HookSortDeclaration + + case class SymbolDeclaration( + symbol: i.Symbol, + argSorts: Seq[i.Sort], + returnSort: i.Sort, + att: i.Attributes + ) extends i.SymbolDeclaration + + case class HookSymbolDeclaration( + symbol: i.Symbol, + argSorts: Seq[i.Sort], + returnSort: i.Sort, + att: i.Attributes + ) extends i.HookSymbolDeclaration + + case class AliasDeclaration( + alias: i.Alias, + argSorts: Seq[i.Sort], + returnSort: i.Sort, + leftPattern: i.Pattern, + rightPattern: i.Pattern, + att: i.Attributes + ) extends i.AliasDeclaration + + case class AxiomDeclaration(params: Seq[i.SortVariable], pattern: i.Pattern, att: i.Attributes) + extends i.AxiomDeclaration + + case class ClaimDeclaration(params: Seq[i.SortVariable], pattern: i.Pattern, att: i.Attributes) + extends i.ClaimDeclaration case class Attributes(patterns: Seq[i.Pattern]) extends i.Attributes @@ -72,17 +93,17 @@ object implementation { case class StringLiteral(str: String) extends i.StringLiteral case class SortVariable(name: String) extends i.SortVariable { - override def toString = name + override def toString = name override lazy val hashCode: Int = scala.runtime.ScalaRunTime._hashCode(this) } case class CompoundSort(ctr: String, params: Seq[i.Sort]) extends i.CompoundSort { - override lazy val toString = ctr + "{" + params.map(_.toString).mkString(", ") + "}" + override lazy val toString = ctr + "{" + params.map(_.toString).mkString(", ") + "}" override lazy val hashCode: Int = scala.runtime.ScalaRunTime._hashCode(this) } case class SymbolOrAlias(ctr: String, params: Seq[i.Sort]) extends i.SymbolOrAlias { - override lazy val toString = ctr + "{" + params.map(_.toString).mkString(", ") + "}" + override lazy val toString = ctr + "{" + params.map(_.toString).mkString(", ") + "}" override lazy val hashCode: Int = scala.runtime.ScalaRunTime._hashCode(this) } @@ -93,27 +114,63 @@ object implementation { object DefaultBuilders extends i.Builders { - import org.kframework.parser.kore.implementation.{ConcreteClasses => d} + import org.kframework.parser.kore.implementation.{ ConcreteClasses => d } - def Definition(att: i.Attributes, modules: Seq[i.Module]): i.Definition = d.Definition(att, modules) + def Definition(att: i.Attributes, modules: Seq[i.Module]): i.Definition = + d.Definition(att, modules) - def Module(name: String, decls: Seq[i.Declaration], att: i.Attributes): i.Module = d.Module(name, decls, att) + def Module(name: String, decls: Seq[i.Declaration], att: i.Attributes): i.Module = + d.Module(name, decls, att) def Import(name: String, att: i.Attributes): i.Declaration = d.Import(name, att) - def SortDeclaration(params: Seq[i.SortVariable], sort: i.Sort, att: i.Attributes): i.Declaration = d.SortDeclaration(params, sort, att) - - def HookSortDeclaration(params: Seq[i.SortVariable], sort: i.Sort, att: i.Attributes): i.Declaration = d.HookSortDeclaration(params, sort, att) - - def SymbolDeclaration(symbol: i.Symbol, argSorts: Seq[i.Sort], returnSort: i.Sort, att: i.Attributes): i.Declaration = d.SymbolDeclaration(symbol, argSorts, returnSort, att) - - def HookSymbolDeclaration(symbol: i.Symbol, argSorts: Seq[i.Sort], returnSort: i.Sort, att: i.Attributes): i.Declaration = d.HookSymbolDeclaration(symbol, argSorts, returnSort, att) - - def AliasDeclaration(alias: i.Alias, argSorts: Seq[i.Sort], returnSort: i.Sort, leftPattern: i.Pattern, rightPattern: i.Pattern, att: i.Attributes): i.Declaration = d.AliasDeclaration(alias, argSorts, returnSort, leftPattern, rightPattern, att) - - def AxiomDeclaration(params: Seq[i.SortVariable], _1: i.Pattern, att: i.Attributes): i.Declaration = d.AxiomDeclaration(params, _1, att) - - def ClaimDeclaration(params: Seq[i.SortVariable], _1: i.Pattern, att: i.Attributes): i.Declaration = d.ClaimDeclaration(params, _1, att) + def SortDeclaration( + params: Seq[i.SortVariable], + sort: i.Sort, + att: i.Attributes + ): i.Declaration = d.SortDeclaration(params, sort, att) + + def HookSortDeclaration( + params: Seq[i.SortVariable], + sort: i.Sort, + att: i.Attributes + ): i.Declaration = d.HookSortDeclaration(params, sort, att) + + def SymbolDeclaration( + symbol: i.Symbol, + argSorts: Seq[i.Sort], + returnSort: i.Sort, + att: i.Attributes + ): i.Declaration = d.SymbolDeclaration(symbol, argSorts, returnSort, att) + + def HookSymbolDeclaration( + symbol: i.Symbol, + argSorts: Seq[i.Sort], + returnSort: i.Sort, + att: i.Attributes + ): i.Declaration = d.HookSymbolDeclaration(symbol, argSorts, returnSort, att) + + def AliasDeclaration( + alias: i.Alias, + argSorts: Seq[i.Sort], + returnSort: i.Sort, + leftPattern: i.Pattern, + rightPattern: i.Pattern, + att: i.Attributes + ): i.Declaration = + d.AliasDeclaration(alias, argSorts, returnSort, leftPattern, rightPattern, att) + + def AxiomDeclaration( + params: Seq[i.SortVariable], + _1: i.Pattern, + att: i.Attributes + ): i.Declaration = d.AxiomDeclaration(params, _1, att) + + def ClaimDeclaration( + params: Seq[i.SortVariable], + _1: i.Pattern, + att: i.Attributes + ): i.Declaration = d.ClaimDeclaration(params, _1, att) def Attributes(patterns: Seq[Pattern]): i.Attributes = d.Attributes(patterns) @@ -121,7 +178,8 @@ object implementation { def SetVariable(name: String, sort: i.Sort): i.SetVariable = d.SetVariable(name, sort) - def Application(head: i.SymbolOrAlias, args: Seq[i.Pattern]): i.Pattern = d.Application(head, args) + def Application(head: i.SymbolOrAlias, args: Seq[i.Pattern]): i.Pattern = + d.Application(head, args) def Top(s: i.Sort): i.Pattern = d.Top(s) @@ -129,23 +187,21 @@ object implementation { def And(s: i.Sort, _1: i.Pattern, _2: i.Pattern): i.Pattern = d.And(s, Seq(_1, _2)) - def And(s: i.Sort, args: Seq[i.Pattern]): i.Pattern = { + def And(s: i.Sort, args: Seq[i.Pattern]): i.Pattern = args.size match { case 0 => Top(s) case 1 => args(0) case _ => d.And(s, args) } - } def Or(s: i.Sort, _1: i.Pattern, _2: i.Pattern): i.Pattern = d.Or(s, Seq(_1, _2)) - def Or(s: i.Sort, args: Seq[i.Pattern]): i.Pattern = { + def Or(s: i.Sort, args: Seq[i.Pattern]): i.Pattern = args.size match { case 0 => Bottom(s) case 1 => args(0) case _ => d.Or(s, args) } - } def Not(s: i.Sort, _1: i.Pattern): i.Pattern = d.Not(s, _1) @@ -165,35 +221,36 @@ object implementation { def Floor(s: i.Sort, rs: i.Sort, p: Pattern): i.Pattern = d.Floor(s, rs, p) - def Equals(s: i.Sort, rs: i.Sort, _1: i.Pattern, _2: i.Pattern): i.Equals = d.Equals(s, rs, _1, _2) + def Equals(s: i.Sort, rs: i.Sort, _1: i.Pattern, _2: i.Pattern): i.Equals = + d.Equals(s, rs, _1, _2) def Mem(s: i.Sort, rs: i.Sort, p: i.Pattern, q: i.Pattern): i.Pattern = d.Mem(s, rs, p, q) def DomainValue(s: i.Sort, str: String): i.Pattern = d.DomainValue(s, str) - // def Subset(s: i.Sort, rs: i.Sort, _1: Pattern, _2: Pattern): i.Pattern = d.Subset(s, rs, _1, _2) + // def Subset(s: i.Sort, rs: i.Sort, _1: Pattern, _2: Pattern): i.Pattern = d.Subset(s, rs, _1, + // _2) def StringLiteral(str: String): i.Pattern = d.StringLiteral(str) - // def DomainValue(sortStr: String, valueStr: String): Pattern = d.DomainValue(sortStr, valueStr) + // def DomainValue(sortStr: String, valueStr: String): Pattern = d.DomainValue(sortStr, + // valueStr) def SortVariable(name: String): i.SortVariable = d.SortVariable(name) def CompoundSort(ctr: String, params: Seq[i.Sort]): i.CompoundSort = d.CompoundSort(ctr, params) - def SymbolOrAlias(ctr: String, params: Seq[i.Sort]): i.SymbolOrAlias = d.SymbolOrAlias(ctr, params) + def SymbolOrAlias(ctr: String, params: Seq[i.Sort]): i.SymbolOrAlias = + d.SymbolOrAlias(ctr, params) def Symbol(ctr: String, params: Seq[i.Sort]): i.Symbol = d.Symbol(ctr, params) def Alias(ctr: String, params: Seq[i.Sort]): i.Alias = d.Alias(ctr, params) - def LeftAssoc(ctr: (i.Pattern, i.Pattern) => i.Pattern, args: Seq[i.Pattern]): i.Pattern = { + def LeftAssoc(ctr: (i.Pattern, i.Pattern) => i.Pattern, args: Seq[i.Pattern]): i.Pattern = args.reduceLeft((accum, p) => ctr(accum, p)) - } - def RightAssoc(ctr: (i.Pattern, i.Pattern) => i.Pattern, args: Seq[i.Pattern]): i.Pattern = { + def RightAssoc(ctr: (i.Pattern, i.Pattern) => i.Pattern, args: Seq[i.Pattern]): i.Pattern = args.reduceRight((p, accum) => ctr(p, accum)) - } } } - diff --git a/kore/src/main/scala/org/kframework/parser/kore/Interface.scala b/kore/src/main/scala/org/kframework/parser/kore/Interface.scala index 2121936d6c9..54ac5161443 100644 --- a/kore/src/main/scala/org/kframework/parser/kore/Interface.scala +++ b/kore/src/main/scala/org/kframework/parser/kore/Interface.scala @@ -23,7 +23,8 @@ trait Module { } object Module { - def unapply(arg: Module): Option[(String, Seq[Declaration], Attributes)] = Some(arg.name, arg.decls, arg.att) + def unapply(arg: Module): Option[(String, Seq[Declaration], Attributes)] = + Some(arg.name, arg.decls, arg.att) } trait Declaration @@ -47,16 +48,15 @@ trait SortDeclaration extends Declaration { } object SortDeclaration { - def unapply(arg: SortDeclaration): Option[(Seq[SortVariable], Sort, Attributes)] - = Some(arg.params, arg.sort, arg.att) + def unapply(arg: SortDeclaration): Option[(Seq[SortVariable], Sort, Attributes)] = + Some(arg.params, arg.sort, arg.att) } -trait HookSortDeclaration extends SortDeclaration { -} +trait HookSortDeclaration extends SortDeclaration {} object HookSortDeclaration { - def unapply(arg: HookSortDeclaration): Option[(Seq[SortVariable], Sort, Attributes)] - = Some(arg.params, arg.sort, arg.att) + def unapply(arg: HookSortDeclaration): Option[(Seq[SortVariable], Sort, Attributes)] = + Some(arg.params, arg.sort, arg.att) } trait SymbolDeclaration extends Declaration { @@ -70,16 +70,15 @@ trait SymbolDeclaration extends Declaration { } object SymbolDeclaration { - def unapply(arg: SymbolDeclaration): Option[(Symbol, Seq[Sort], Sort, Attributes)] - = Some(arg.symbol, arg.argSorts, arg.returnSort, arg.att) + def unapply(arg: SymbolDeclaration): Option[(Symbol, Seq[Sort], Sort, Attributes)] = + Some(arg.symbol, arg.argSorts, arg.returnSort, arg.att) } -trait HookSymbolDeclaration extends SymbolDeclaration { -} +trait HookSymbolDeclaration extends SymbolDeclaration {} object HookSymbolDeclaration { - def unapply(arg: HookSymbolDeclaration): Option[(Symbol, Seq[Sort], Sort, Attributes)] - = Some(arg.symbol, arg.argSorts, arg.returnSort, arg.att) + def unapply(arg: HookSymbolDeclaration): Option[(Symbol, Seq[Sort], Sort, Attributes)] = + Some(arg.symbol, arg.argSorts, arg.returnSort, arg.att) } trait AliasDeclaration extends Declaration { @@ -97,8 +96,10 @@ trait AliasDeclaration extends Declaration { } object AliasDeclaration { - def unapply(arg: AliasDeclaration): Option[(Alias, Seq[Sort], Sort, Pattern, Pattern, Attributes)] - = Some(arg.alias, arg.argSorts, arg.returnSort, arg.leftPattern, arg.rightPattern, arg.att) + def unapply( + arg: AliasDeclaration + ): Option[(Alias, Seq[Sort], Sort, Pattern, Pattern, Attributes)] = + Some(arg.alias, arg.argSorts, arg.returnSort, arg.leftPattern, arg.rightPattern, arg.att) } trait AxiomDeclaration extends Declaration { @@ -112,8 +113,8 @@ trait AxiomDeclaration extends Declaration { trait ClaimDeclaration extends AxiomDeclaration {} object AxiomDeclaration { - def unapply(arg: AxiomDeclaration): Option[(Seq[SortVariable], Pattern, Attributes)] - = Some(arg.params, arg.pattern, arg.att) + def unapply(arg: AxiomDeclaration): Option[(Seq[SortVariable], Pattern, Attributes)] = + Some(arg.params, arg.pattern, arg.att) } trait Attributes { @@ -133,65 +134,67 @@ object AlphanumOrdering extends Ordering[String] { } object Pattern { - implicit val ord: Ordering[Pattern] = (a: Pattern, b: Pattern) => { + implicit val ord: Ordering[Pattern] = (a: Pattern, b: Pattern) => (a, b) match { - case (c: Variable, d: Variable) => Ordering[Variable].compare(c, d) - case (c: Application, d: Application) => Ordering[Application].compare(c, d) - case (c: Top, d: Top) => Ordering[Top].compare(c, d) - case (c: Bottom, d: Bottom) => Ordering[Bottom].compare(c, d) - case (c: And, d: And) => Ordering[And].compare(c, d) - case (c: Or, d: Or) => Ordering[Or].compare(c, d) - case (c: Not, d: Not) => Ordering[Not].compare(c, d) - case (c: Implies, d: Implies) => Ordering[Implies].compare(c, d) - case (c: Iff, d: Iff) => Ordering[Iff].compare(c, d) - case (c: Exists, d: Exists) => Ordering[Exists].compare(c, d) - case (c: Forall, d: Forall) => Ordering[Forall].compare(c, d) - case (c: Ceil, d: Ceil) => Ordering[Ceil].compare(c, d) - case (c: Floor, d: Floor) => Ordering[Floor].compare(c, d) - case (c: Rewrites, d: Rewrites) => Ordering[Rewrites].compare(c, d) - case (c: Equals, d: Equals) => Ordering[Equals].compare(c, d) - case (c: Mem, d: Mem) => Ordering[Mem].compare(c, d) - case (c: DomainValue, d: DomainValue) => Ordering[DomainValue].compare(c, d) + case (c: Variable, d: Variable) => Ordering[Variable].compare(c, d) + case (c: Application, d: Application) => Ordering[Application].compare(c, d) + case (c: Top, d: Top) => Ordering[Top].compare(c, d) + case (c: Bottom, d: Bottom) => Ordering[Bottom].compare(c, d) + case (c: And, d: And) => Ordering[And].compare(c, d) + case (c: Or, d: Or) => Ordering[Or].compare(c, d) + case (c: Not, d: Not) => Ordering[Not].compare(c, d) + case (c: Implies, d: Implies) => Ordering[Implies].compare(c, d) + case (c: Iff, d: Iff) => Ordering[Iff].compare(c, d) + case (c: Exists, d: Exists) => Ordering[Exists].compare(c, d) + case (c: Forall, d: Forall) => Ordering[Forall].compare(c, d) + case (c: Ceil, d: Ceil) => Ordering[Ceil].compare(c, d) + case (c: Floor, d: Floor) => Ordering[Floor].compare(c, d) + case (c: Rewrites, d: Rewrites) => Ordering[Rewrites].compare(c, d) + case (c: Equals, d: Equals) => Ordering[Equals].compare(c, d) + case (c: Mem, d: Mem) => Ordering[Mem].compare(c, d) + case (c: DomainValue, d: DomainValue) => Ordering[DomainValue].compare(c, d) case (c: StringLiteral, d: StringLiteral) => Ordering[StringLiteral].compare(c, d) - case (_: Variable, _) => -1 - case (_, _: Variable) => 1 - case (_: Application, _) => -1 - case (_, _: Application) => 1 - case (_: Top, _) => -1 - case (_, _: Top) => 1 - case (_: Bottom, _) => -1 - case (_, _: Bottom) => 1 - case (_: And, _) => -1 - case (_, _: And) => 1 - case (_: Or, _) => -1 - case (_, _: Or) => 1 - case (_: Not, _) => -1 - case (_, _: Not) => 1 - case (_: Implies, _) => -1 - case (_, _: Implies) => 1 - case (_: Iff, _) => -1 - case (_, _: Iff) => 1 - case (_: Exists, _) => -1 - case (_, _: Exists) => 1 - case (_: Forall, _) => -1 - case (_, _: Forall) => 1 - case (_: Ceil, _) => -1 - case (_, _: Ceil) => 1 - case (_: Floor, _) => -1 - case (_, _: Floor) => 1 - case (_: Rewrites, _) => -1 - case (_, _: Rewrites) => 1 - case (_: Equals, _) => -1 - case (_, _: Equals) => 1 - case (_: Mem, _) => -1 - case (_, _: Mem) => 1 - case (_: DomainValue, _) => -1 - case (_, _: DomainValue) => 1 - case (_: StringLiteral, _) => -1 - case (_, _: StringLiteral) => 1 - case (_, _) => throw KEMException.internalError("Cannot order these patterns:\n" + a.toString + "\n" + b.toString) + case (_: Variable, _) => -1 + case (_, _: Variable) => 1 + case (_: Application, _) => -1 + case (_, _: Application) => 1 + case (_: Top, _) => -1 + case (_, _: Top) => 1 + case (_: Bottom, _) => -1 + case (_, _: Bottom) => 1 + case (_: And, _) => -1 + case (_, _: And) => 1 + case (_: Or, _) => -1 + case (_, _: Or) => 1 + case (_: Not, _) => -1 + case (_, _: Not) => 1 + case (_: Implies, _) => -1 + case (_, _: Implies) => 1 + case (_: Iff, _) => -1 + case (_, _: Iff) => 1 + case (_: Exists, _) => -1 + case (_, _: Exists) => 1 + case (_: Forall, _) => -1 + case (_, _: Forall) => 1 + case (_: Ceil, _) => -1 + case (_, _: Ceil) => 1 + case (_: Floor, _) => -1 + case (_, _: Floor) => 1 + case (_: Rewrites, _) => -1 + case (_, _: Rewrites) => 1 + case (_: Equals, _) => -1 + case (_, _: Equals) => 1 + case (_: Mem, _) => -1 + case (_, _: Mem) => 1 + case (_: DomainValue, _) => -1 + case (_, _: DomainValue) => 1 + case (_: StringLiteral, _) => -1 + case (_, _: StringLiteral) => 1 + case (_, _) => + throw KEMException.internalError( + "Cannot order these patterns:\n" + a.toString + "\n" + b.toString + ) } - } } trait Variable extends Pattern { @@ -314,7 +317,8 @@ object Iff { } trait Exists extends Pattern { - def s: Sort // this is the sort of the whole exists pattern, not the sort of the binding variable v + // this is the sort of the whole exists pattern, not the sort of the binding variable v + def s: Sort def v: Variable @@ -387,10 +391,9 @@ trait GeneralizedRewrite { } /** - * \rewrites(P, Q) is defined as a predicate pattern floor(P implies Q) - * Therefore a rewrites-to pattern is parametric on two sorts. - * One is the sort of patterns P and Q; - * The other is the sort of the context. + * \rewrites(P, Q) is defined as a predicate pattern floor(P implies Q) Therefore a rewrites-to + * pattern is parametric on two sorts. One is the sort of patterns P and Q; The other is the sort of + * the context. */ trait Rewrites extends Pattern with GeneralizedRewrite { def s: Sort // the sort of the two patterns P and Q @@ -432,7 +435,8 @@ trait Equals extends Pattern with GeneralizedRewrite { } object Equals { - def unapply(arg: Equals): Option[(Sort, Sort, Pattern, Pattern)] = Some(arg.s, arg.rs, arg._1, arg._2) + def unapply(arg: Equals): Option[(Sort, Sort, Pattern, Pattern)] = + Some(arg.s, arg.rs, arg._1, arg._2) implicit val ord: Ordering[Equals] = Ordering.by(unapply) } @@ -516,27 +520,28 @@ object StringLiteral { // def unapply(arg: DomainValue): Option[(String, String)] = Some(arg.sortStr, arg.valueStr) // } - -/** A sort can be either a sort variable or of the form C{s1,...,sn} - * where C is called the sort constructor and s1,...,sn are sort parameters. - * We call sorts that are of the form C{s1,...,sn} compound sorts because - * I don't know a better name. +/** + * A sort can be either a sort variable or of the form C{s1,...,sn} where C is called the sort + * constructor and s1,...,sn are sort parameters. We call sorts that are of the form C{s1,...,sn} + * compound sorts because I don't know a better name. */ trait Sort object Sort { - implicit val ord: Ordering[Sort] = (a: Sort, b: Sort) => { + implicit val ord: Ordering[Sort] = (a: Sort, b: Sort) => (a, b) match { case (c: SortVariable, d: SortVariable) => Ordering[SortVariable].compare(c, d) case (c: CompoundSort, d: CompoundSort) => Ordering[CompoundSort].compare(c, d) - case (_: SortVariable, _) => -1 - case (_, _: SortVariable) => 1 - case (_: CompoundSort, _) => -1 - case (_, _: CompoundSort) => 1 - case (_, _) => throw KEMException.internalError("Cannot order these sorts:\n" + a.toString + "\n" + b.toString) + case (_: SortVariable, _) => -1 + case (_, _: SortVariable) => 1 + case (_: CompoundSort, _) => -1 + case (_, _: CompoundSort) => 1 + case (_, _) => + throw KEMException.internalError( + "Cannot order these sorts:\n" + a.toString + "\n" + b.toString + ) } - } } trait SortVariable extends Sort { @@ -549,9 +554,9 @@ object SortVariable { implicit val ord: Ordering[SortVariable] = Ordering.by(unapply) } -/** A compound sort is of the form C{s1,...,sn} - * For example: - * Nat{} List{Nat{}} List{S} Map{S,List{S}} Map{Map{Nat{},Nat{}},Nat{}} +/** + * A compound sort is of the form C{s1,...,sn} For example: Nat{} List{Nat{}} List{S} Map{S,List{S}} + * Map{Map{Nat{},Nat{}},Nat{}} */ trait CompoundSort extends Sort { def ctr: String // sort constructor @@ -568,9 +573,9 @@ object CompoundSort { implicit val ord: Ordering[CompoundSort] = Ordering.by(unapply) } -/** A symbol-or-alias is of the form C{s1,...,sn} - * where C is called a constructor and s1,...,sn are sort parameters. - * In the Semantics of K document, SymbolOrAlias is called the nonterminal +/** + * A symbol-or-alias is of the form C{s1,...,sn} where C is called a constructor and s1,...,sn are + * sort parameters. In the Semantics of K document, SymbolOrAlias is called the nonterminal */ trait SymbolOrAlias { def ctr: String @@ -608,38 +613,36 @@ trait Builders { def Import(name: String, att: Attributes): Declaration - def SortDeclaration(params: Seq[SortVariable], - sort: Sort, - att: Attributes): Declaration - - def HookSortDeclaration(params: Seq[SortVariable], - sort: Sort, - att: Attributes): Declaration - - def SymbolDeclaration(symbol: Symbol, - argSorts: Seq[Sort], - returnSort: Sort, - att: Attributes): Declaration - - def HookSymbolDeclaration(symbol: Symbol, - argSorts: Seq[Sort], - returnSort: Sort, - att: Attributes): Declaration - - def AliasDeclaration(alias: Alias, - argSorts: Seq[Sort], - returnSort: Sort, - leftPattern: Pattern, - rightPattern: Pattern, - att: Attributes): Declaration - - def AxiomDeclaration(params: Seq[SortVariable], - pattern: Pattern, - att: Attributes): Declaration - - def ClaimDeclaration(params: Seq[SortVariable], - pattern: Pattern, - att: Attributes): Declaration + def SortDeclaration(params: Seq[SortVariable], sort: Sort, att: Attributes): Declaration + + def HookSortDeclaration(params: Seq[SortVariable], sort: Sort, att: Attributes): Declaration + + def SymbolDeclaration( + symbol: Symbol, + argSorts: Seq[Sort], + returnSort: Sort, + att: Attributes + ): Declaration + + def HookSymbolDeclaration( + symbol: Symbol, + argSorts: Seq[Sort], + returnSort: Sort, + att: Attributes + ): Declaration + + def AliasDeclaration( + alias: Alias, + argSorts: Seq[Sort], + returnSort: Sort, + leftPattern: Pattern, + rightPattern: Pattern, + att: Attributes + ): Declaration + + def AxiomDeclaration(params: Seq[SortVariable], pattern: Pattern, att: Attributes): Declaration + + def ClaimDeclaration(params: Seq[SortVariable], pattern: Pattern, att: Attributes): Declaration def Attributes(att: Seq[Pattern]): Attributes diff --git a/kore/src/main/scala/org/kframework/parser/kore/parser/KoreToK.scala b/kore/src/main/scala/org/kframework/parser/kore/parser/KoreToK.scala index 539cf201420..943a7650bc4 100644 --- a/kore/src/main/scala/org/kframework/parser/kore/parser/KoreToK.scala +++ b/kore/src/main/scala/org/kframework/parser/kore/parser/KoreToK.scala @@ -1,18 +1,18 @@ // Copyright (c) K Team. All Rights Reserved. package org.kframework.parser.kore.parser -import org.kframework.builtin.{KLabels, Sorts} -import org.kframework.kore.Assoc -import org.kframework.kore.KVariable -import org.kframework.kore.KORE +import org.kframework.{ kore => k } import org.kframework.attributes.Att +import org.kframework.builtin.KLabels +import org.kframework.builtin.Sorts import org.kframework.kore.ADT.KVariable +import org.kframework.kore.Assoc +import org.kframework.kore.KORE +import org.kframework.kore.KVariable import org.kframework.parser.kore import org.kframework.utils.StringUtil -import org.kframework.{kore => k} - -import scala.collection.Map import scala.collection.JavaConverters._ +import scala.collection.Map /** Translation error exception. */ case class TranslationError(msg: String) extends RuntimeException(msg) @@ -20,7 +20,7 @@ case class TranslationError(msg: String) extends RuntimeException(msg) /** Conversion function from Kore to K. */ // sortAtt is a map from sort names to their hook attribute, if any -class KoreToK (sortAtt : Map[String, String]) { +class KoreToK(sortAtt: Map[String, String]) { val codes = Map( "Spce" -> " ", @@ -54,39 +54,38 @@ class KoreToK (sortAtt : Map[String, String]) { "LBra" -> "{", "Pipe" -> "|", "RBra" -> "}", - "Tild" -> "~") + "Tild" -> "~" + ) - def mapCode(code: String): String = { + def mapCode(code: String): String = try { val i = Integer.parseInt(code, 16) "\\u" + code } catch { case _: NumberFormatException => codes(code) } - } /** Returns a [[k.Sort]] from [[kore.Sort]]. */ def apply(s: kore.Sort): k.Sort = s match { - case kore.SortVariable(name) => - Sorts.K - case kore.CompoundSort(ctr, params) => - assert(ctr.startsWith("Sort")) - KORE.Sort(ctr.substring( 4), params.map(apply): _*); + case kore.SortVariable(name) => + Sorts.K + case kore.CompoundSort(ctr, params) => + assert(ctr.startsWith("Sort")) + KORE.Sort(ctr.substring(4), params.map(apply): _*); } /** Returns a [[k.KLabel]] from [[kore.SymbolOrAlias]] */ - def apply(head: kore.SymbolOrAlias): k.KLabel = { + def apply(head: kore.SymbolOrAlias): k.KLabel = KORE.KLabel(extractKLabel(head.ctr), head.params.map(p => apply(p)): _*) - } - private def extractKLabel(head: String): String = { + private def extractKLabel(head: String): String = if (head.startsWith("Lbl")) { extractKLabel(head.substring(3)) } else { var literal = true - var result = new StringBuilder() - var i = 0 - while (i < head.length) { + var result = new StringBuilder() + var i = 0 + while (i < head.length) if (head(i) == '\'') { literal = !literal i += 1 @@ -94,52 +93,60 @@ class KoreToK (sortAtt : Map[String, String]) { result.append(head(i)) i += 1 } else { - val code = head.substring(i, i+4) + val code = head.substring(i, i + 4) result.append(mapCode(code)) i += 4 } - } result.toString } - } - private def extractVarName(name: String): String = { + private def extractVarName(name: String): String = if (name.startsWith("Var")) { StringUtil.decodeKoreString(name.substring(3)) } else { StringUtil.decodeKoreString(name) } - } /** Returns a [[k.K]] from [[kore.Pattern]]. */ def apply(pat: kore.Pattern): k.K = pat match { case kore.Variable(name, sort) => - KORE.KVariable(extractVarName(name), Att.empty.add(classOf[org.kframework.kore.Sort], apply(sort))) - case kore.Application(head, args) => head.ctr match { - case "inj" => - apply(args.head) match { - case KVariable(name, att) => KORE.KVariable(name, att.add(Att.PRETTY_PRINT_WITH_SORT_ANNOTATION)) - case body => body - } - case "kseq" => - KORE.KSequence(args.map(apply(_)): _*) - case "append" => - KORE.KSequence(args.map(apply(_)): _*) - case "dotk" => - KORE.KSequence() - case _ => - KORE.KApply(apply(head), args.map((k) => apply(k))) - } + KORE.KVariable( + extractVarName(name), + Att.empty.add(classOf[org.kframework.kore.Sort], apply(sort)) + ) + case kore.Application(head, args) => + head.ctr match { + case "inj" => + apply(args.head) match { + case KVariable(name, att) => + KORE.KVariable(name, att.add(Att.PRETTY_PRINT_WITH_SORT_ANNOTATION)) + case body => body + } + case "kseq" => + KORE.KSequence(args.map(apply(_)): _*) + case "append" => + KORE.KSequence(args.map(apply(_)): _*) + case "dotk" => + KORE.KSequence() + case _ => + KORE.KApply(apply(head), args.map(k => apply(k))) + } case kore.Top(s) => KORE.KApply(KORE.KLabel(KLabels.ML_TRUE.name, apply(s))) case kore.Bottom(s) => KORE.KApply(KORE.KLabel(KLabels.ML_FALSE.name, apply(s))) case kore.And(s, items) => val and = KORE.KLabel(KLabels.ML_AND.name, apply(s)) - KORE.KApply(and, Assoc.flatten(and, items.map(apply), KORE.KLabel(KLabels.ML_TRUE.name, apply(s)))) + KORE.KApply( + and, + Assoc.flatten(and, items.map(apply), KORE.KLabel(KLabels.ML_TRUE.name, apply(s))) + ) case kore.Or(s, items) => val or = KORE.KLabel(KLabels.ML_OR.name, apply(s)) - KORE.KApply(or, Assoc.flatten(or, items.map(apply), KORE.KLabel(KLabels.ML_FALSE.name, apply(s)))) + KORE.KApply( + or, + Assoc.flatten(or, items.map(apply), KORE.KLabel(KLabels.ML_FALSE.name, apply(s))) + ) case kore.Not(s, p) => KORE.KApply(KORE.KLabel(KLabels.ML_NOT.name, apply(s)), apply(p)) case kore.Implies(s, p, q) => @@ -162,7 +169,12 @@ class KoreToK (sortAtt : Map[String, String]) { throw new TranslationError("Mem patterns currently unsupported") case kore.DomainValue(s, str) => val hookAtt = sortAtt.get(apply(s).name).getOrElse("") - KORE.KToken(if (hookAtt == "STRING.String") StringUtil.enquoteKString(str) else if (hookAtt == "BYTES.Bytes") "b" + StringUtil.enquoteKString(str) else str, apply(s)) + KORE.KToken( + if (hookAtt == "STRING.String") StringUtil.enquoteKString(str) + else if (hookAtt == "BYTES.Bytes") "b" + StringUtil.enquoteKString(str) + else str, + apply(s) + ) case kore.StringLiteral(str) => KORE.KToken(str, Sorts.KString) } diff --git a/kore/src/main/scala/org/kframework/parser/kore/parser/Scanner.scala b/kore/src/main/scala/org/kframework/parser/kore/parser/Scanner.scala index 78be4ce5d88..2907d039f14 100644 --- a/kore/src/main/scala/org/kframework/parser/kore/parser/Scanner.scala +++ b/kore/src/main/scala/org/kframework/parser/kore/parser/Scanner.scala @@ -1,35 +1,40 @@ // Copyright (c) K Team. All Rights Reserved. package org.kframework.parser.kore.parser -/** A scanner of an input stream. - * - * Should be initialized by [[init]] before use, - * and closed by [[close]] after use. - * - * @constructor Creates a new scanner. - */ +/** + * A scanner of an input stream. + * + * Should be initialized by [[init]] before use, and closed by [[close]] after use. + * + * @constructor + * Creates a new scanner. + */ class Scanner { - private var stream: io.Source = _ + private var stream: io.Source = _ private var lines: Iterator[String] = _ - private var input: Iterator[Char] = _ + private var input: Iterator[Char] = _ + /** The string of the line that this scanner currently reads. */ var line: String = _ + /** The line number of the current line. */ var lineNum: Int = _ + /** The column position of this scanner in the line. */ var columnNum: Int = _ - /** Initializes this scanner. - * - * @param src The stream to associate with this scanner. - */ + /** + * Initializes this scanner. + * + * @param src + * The stream to associate with this scanner. + */ def init(src: io.Source, firstLine: Integer): Unit = { stream = src lines = stream.getLines() - for (i <- 0 until firstLine) { + for (i <- 0 until firstLine) lines.next() - } line = "" lineNum = 0 columnNum = 0 @@ -37,12 +42,11 @@ class Scanner { } /** Closes the stream associated with this scanner. */ - def close(): Unit = { + def close(): Unit = stream.close() - } @throws(classOf[java.io.EOFException]) - private def readLine(): Unit = { + private def readLine(): Unit = if (lines.hasNext) { line = lines.next() // each line doesn't contain newline characters input = line.iterator @@ -52,14 +56,13 @@ class Scanner { // end of file throw new java.io.EOFException() } - } private var lookahead: Option[Char] = None - private var yieldEOL: Boolean = false + private var yieldEOL: Boolean = false - /** Returns the next character from the stream. - * Returns '\n' when a newline is encountered. - */ + /** + * Returns the next character from the stream. Returns '\n' when a newline is encountered. + */ @throws(classOf[java.io.EOFException]) def next(): Char = { columnNum += 1 @@ -82,10 +85,11 @@ class Scanner { } } - /** Puts back the character into the stream. - * - * Cannot put other characters until the inserted character has been read by [[next]]. - */ + /** + * Puts back the character into the stream. + * + * Cannot put other characters until the inserted character has been read by [[next]]. + */ def putback(c: Char): Unit = { columnNum -= 1 lookahead match { @@ -95,22 +99,22 @@ class Scanner { } } - /** Consumes the whitespace characters until a non-whitespace character is met. - */ + /** + * Consumes the whitespace characters until a non-whitespace character is met. + */ @throws(classOf[java.io.EOFException]) - def skipWhitespaces(): Unit = { + def skipWhitespaces(): Unit = next() match { case ' ' | '\n' => skipWhitespaces() - case '\t' => columnNum += 3; skipWhitespaces() - case '\r' => ??? // skipWhitespaces() // shouldn't be reachable. - case '/' => skipComments(); skipWhitespaces() - case c => putback(c) + case '\t' => columnNum += 3; skipWhitespaces() + case '\r' => ??? // skipWhitespaces() // shouldn't be reachable. + case '/' => skipComments(); skipWhitespaces() + case c => putback(c) } - } /** - * Consumes a comment - */ + * Consumes a comment + */ @throws(classOf[java.io.IOException]) def skipComments(): Unit = { next() match { @@ -121,34 +125,31 @@ class Scanner { case c => throw new ParseError("Invalid comments. Expect '/' or '*'") } - def skipLineComment(): Unit = { + def skipLineComment(): Unit = next() match { case '\n' => ; - case c => skipLineComment() + case c => skipLineComment() } - } /** - * Skip all until seeing STAR(*) SLASH(/) - */ - def skipBlockComment(): Unit = { + * Skip all until seeing STAR(*) SLASH(/) + */ + def skipBlockComment(): Unit = next() match { case '*' => skipBlockCommentAfterStar() case c => skipBlockComment() } - } /** - * Have seen a STAR(*) - */ - def skipBlockCommentAfterStar(): Unit = { + * Have seen a STAR(*) + */ + def skipBlockCommentAfterStar(): Unit = next() match { case '/' => ; case '*' => skipBlockCommentAfterStar() - case c => skipBlockComment() + case c => skipBlockComment() } - } } /** Returns the next non-whitespace character. */ @@ -157,20 +158,19 @@ class Scanner { next() } - /** Checks if EOF is reached. - * - * Side effect - * Consumes the whitespace characters until either a non-whitespace character or EOF is met. - */ - def isEOF(): Boolean = { + /** + * Checks if EOF is reached. + * + * Side effect Consumes the whitespace characters until either a non-whitespace character or EOF + * is met. + */ + def isEOF(): Boolean = try { putback(nextWithSkippingWhitespaces()) false } catch { case _: java.io.EOFException => true - case _: Throwable => ??? // shouldn't be reachable + case _: Throwable => ??? // shouldn't be reachable } - } } - diff --git a/kore/src/main/scala/org/kframework/parser/kore/parser/TextToKore.scala b/kore/src/main/scala/org/kframework/parser/kore/parser/TextToKore.scala index 6aebc0de4ac..f0f6247253c 100644 --- a/kore/src/main/scala/org/kframework/parser/kore/parser/TextToKore.scala +++ b/kore/src/main/scala/org/kframework/parser/kore/parser/TextToKore.scala @@ -1,36 +1,37 @@ // Copyright (c) K Team. All Rights Reserved. package org.kframework.parser.kore.parser -import org.kframework.parser.kore._ import org.kframework.parser.kore +import org.kframework.parser.kore._ import org.kframework.parser.kore.implementation.DefaultBuilders import org.kframework.utils.StringUtil /** Parsing error exception. */ -case class ParseError(msg: String) extends Exception(msg) { // ParseError.msg eq Exception.detailMessage, i.e., msg() == getMessage() +case class ParseError(msg: String) extends Exception(msg) { + // ParseError.msg eq Exception.detailMessage, i.e., msg() == getMessage() def this(message: String, cause: Throwable) { this(message) initCause(cause) } } -/** A parser for [[kore.Pattern]]. - * - * @constructor Creates a new parser. - */ +/** + * A parser for [[kore.Pattern]]. + * + * @constructor + * Creates a new parser. + */ class TextToKore(b: Builders = DefaultBuilders) { - def this() { + def this() = this(DefaultBuilders) - } private val scanner = new Scanner() /** - * ParsingLevel ::= None // both meta-level and object-level are allowed - * | Some(true) // only accept meta-level - * | Some(false) // only accept object-level - */ + * ParsingLevel ::= None // both meta-level and object-level are allowed \| Some(true) // only + * accept meta-level \| Some(false) // only accept object-level + */ private type ParsingLevel = Option[Boolean] @@ -42,118 +43,106 @@ class TextToKore(b: Builders = DefaultBuilders) { // Whenever a syntactic category is parsed, its parsing level (either object or meta) is // stored in previousParsingLevel. - // Recall that Identifier is the only lexicon syntactic category that decides if a syntactic category + // Recall that Identifier is the only lexicon syntactic category that decides if a syntactic + // category // (such as Sort or Variable) is object-level or meta-level. // Therefore, [[parseId]] is the only method that directly modifies previousParsingLevel. private var previousParsingLevel: ParsingLevel = both /** Parses the file and returns [[kore.Definition]]. */ @throws(classOf[ParseError]) - def parse(file: java.io.File): Definition = { + def parse(file: java.io.File): Definition = parse(io.Source.fromFile(file)) - } /** Parses the file and returns [[kore.Pattern]]. */ @throws(classOf[ParseError]) - def parsePattern(file: java.io.File, line: Integer): Pattern = { + def parsePattern(file: java.io.File, line: Integer): Pattern = parsePattern(io.Source.fromFile(file), line) - } /** Parses the string and returns [[kore.Pattern]]. */ @throws(classOf[ParseError]) - def parsePattern(str: String): Pattern = { + def parsePattern(str: String): Pattern = parsePattern(io.Source.fromString(str), 0) - } /** Parses the file and returns [[kore.Module]]. */ @throws(classOf[ParseError]) - def parseModule(file: java.io.File, line: Integer): Module = { + def parseModule(file: java.io.File, line: Integer): Module = parseModule(io.Source.fromFile(file), line) - } /** Parses the string and returns [[kore.Module]]. */ @throws(classOf[ParseError]) - def parseModule(str: String): Module = { + def parseModule(str: String): Module = parseModule(io.Source.fromString(str), 0) - } /** Parses from the stream and returns [[kore.Definition]]. */ @throws(classOf[ParseError]) - def parse(src: io.Source): Definition = { + def parse(src: io.Source): Definition = try { scanner.init(src, 0) parseDefinition() } catch { - case e: java.io.EOFException => throw new ParseError("ERROR: Unexpected end of file while parsing", e) - } finally { + case e: java.io.EOFException => + throw new ParseError("ERROR: Unexpected end of file while parsing", e) + } finally scanner.close() - } - } /** Parses from the stream and returns [[kore.Pattern]]. */ @throws(classOf[ParseError]) - def parsePattern(src: io.Source, line: Integer): Pattern = { + def parsePattern(src: io.Source, line: Integer): Pattern = try { scanner.init(src, line) parsePattern() } catch { - case e: java.io.EOFException => throw new ParseError("ERROR: Unexpected end of file while parsing", e) - } finally { + case e: java.io.EOFException => + throw new ParseError("ERROR: Unexpected end of file while parsing", e) + } finally scanner.close() - } - } /** Parses from the stream and returns [[kore.Module]]. */ @throws(classOf[ParseError]) - def parseModule(src: io.Source, line: Integer): Module = { + def parseModule(src: io.Source, line: Integer): Module = try { scanner.init(src, line) parseModule() } catch { - case e: java.io.EOFException => throw new ParseError("ERROR: Unexpected end of file while parsing", e) - } finally { + case e: java.io.EOFException => + throw new ParseError("ERROR: Unexpected end of file while parsing", e) + } finally scanner.close() - } - } - /** Read from the stream and return a canonical form [[String]], - * in which all consecutive whitespaces are deleted. - * FIXME:: should return a canonical form [[String]] in which all - * consecutive whitespaces are replaced by ' ' - * Mainly used for testing. */ + /** + * Read from the stream and return a canonical form [[String]], in which all consecutive + * whitespaces are deleted. FIXME:: should return a canonical form [[String]] in which all + * consecutive whitespaces are replaced by ' ' Mainly used for testing. + */ @throws(classOf[java.io.IOException]) - def canonicalString(file: java.io.File): String = { + def canonicalString(file: java.io.File): String = canonicalString(io.Source.fromFile(file)) - } @throws(classOf[java.io.IOException]) - def canonicalString(s: String): String = { + def canonicalString(s: String): String = canonicalString(io.Source.fromString(s)) - } @throws(classOf[java.io.IOException]) def canonicalString(src: io.Source): String = { - def loop(s: StringBuilder): String = { + def loop(s: StringBuilder): String = if (scanner.isEOF()) { return s.toString() - } - else { + } else { s += scanner.next() // s must be a nonwhitespace character loop(s) // tail recursive } - } try { scanner.init(src, 0) loop(new StringBuilder("")) - } - catch { + } catch { case e: java.io.EOFException => throw e } } // Definition = Attributes Module private def parseDefinition(): Definition = { - val att = parseAttributes() + val att = parseAttributes() val modules = parseModules() b.Definition(att, modules) } @@ -179,23 +168,22 @@ class TextToKore(b: Builders = DefaultBuilders) { // Module = module ModuleName Declarations endmodule Attributes private def parseModule(): Module = { consumeWithLeadingWhitespaces("module") - val name = parseId(parsingLevel = objt) + val name = parseId(parsingLevel = objt) val decls = parseDeclarations(Seq()).reverse consumeWithLeadingWhitespaces("endmodule") val att = parseAttributes() b.Module(name, decls, att) } - private def parseModules() : Seq[Module] = { + private def parseModules(): Seq[Module] = { var ms = Seq.empty[Module] - while(!scanner.isEOF()) { + while (!scanner.isEOF()) { val leading_char = scanner.nextWithSkippingWhitespaces() if (leading_char == 'm') { // a module starts scanner.putback('m') val m = parseModule() ms = ms :+ m - } - else + } else throw error('m', leading_char) } ms @@ -213,30 +201,30 @@ class TextToKore(b: Builders = DefaultBuilders) { if (c1 == 'e') { // endmodule scanner.putback('e') decls - } - else { + } else { val c2 = scanner.nextWithSkippingWhitespaces() (c1, c2) match { - case ('i', 'm') => // import - consume("port") - val nameStr = parseId() - val att = parseAttributes() - val decl = b.Import(nameStr, att) - parseDeclarations(decl +: decls) + case ('i', 'm') => // import + consume("port") + val nameStr = parseId() + val att = parseAttributes() + val decl = b.Import(nameStr, att) + parseDeclarations(decl +: decls) case ('s', 'o') => // sort declaration consume("rt") val ctr = parseId(parsingLevel = objt) consumeWithLeadingWhitespaces("{") val params = parseList(() => parseSortVariable(parsingLevel = objt), ',', '}') consumeWithLeadingWhitespaces("}") - val att = parseAttributes() + val att = parseAttributes() val decl = b.SortDeclaration(params, b.CompoundSort(ctr, params), att) parseDeclarations(decl +: decls) case ('s', 'y') => // symbol declaration consume("mbol") val ctr = parseId() // previousParsingLevel is set here consumeWithLeadingWhitespaces("{") - val params = parseList(() => parseSortVariable(parsingLevel = previousParsingLevel), ',', '}') + val params = + parseList(() => parseSortVariable(parsingLevel = previousParsingLevel), ',', '}') consumeWithLeadingWhitespaces("}") val symbol = b.Symbol(ctr, params) consumeWithLeadingWhitespaces("(") @@ -244,8 +232,8 @@ class TextToKore(b: Builders = DefaultBuilders) { consumeWithLeadingWhitespaces(")") consumeWithLeadingWhitespaces(":") val returnSort = parseSort(parsingLevel = previousParsingLevel) - val att = parseAttributes() - val decl = b.SymbolDeclaration(symbol, argSorts, returnSort, att) + val att = parseAttributes() + val decl = b.SymbolDeclaration(symbol, argSorts, returnSort, att) parseDeclarations(decl +: decls) case ('h', 'o') => // hook-sort or hook-symbol declaration consume("oked-") @@ -258,23 +246,25 @@ class TextToKore(b: Builders = DefaultBuilders) { consumeWithLeadingWhitespaces("{") val params = parseList(() => parseSortVariable(parsingLevel = objt), ',', '}') consumeWithLeadingWhitespaces("}") - val att = parseAttributes() + val att = parseAttributes() val decl = b.HookSortDeclaration(params, b.CompoundSort(ctr, params), att) parseDeclarations(decl +: decls) case ('s', 'y') => // hook-symbol consume("mbol") val ctr = parseId() // previousParsingLevel is set here consumeWithLeadingWhitespaces("{") - val params = parseList(() => parseSortVariable(parsingLevel = previousParsingLevel), ',', '}') + val params = + parseList(() => parseSortVariable(parsingLevel = previousParsingLevel), ',', '}') consumeWithLeadingWhitespaces("}") val symbol = b.Symbol(ctr, params) consumeWithLeadingWhitespaces("(") - val argSorts = parseList(() => parseSort(parsingLevel = previousParsingLevel), ',', ')') + val argSorts = + parseList(() => parseSort(parsingLevel = previousParsingLevel), ',', ')') consumeWithLeadingWhitespaces(")") consumeWithLeadingWhitespaces(":") val returnSort = parseSort(parsingLevel = previousParsingLevel) - val att = parseAttributes() - val decl = b.HookSymbolDeclaration(symbol, argSorts, returnSort, att) + val att = parseAttributes() + val decl = b.HookSymbolDeclaration(symbol, argSorts, returnSort, att) parseDeclarations(decl +: decls) case (e1, e2) => // error throw error("sort, symbol", e1) @@ -283,7 +273,8 @@ class TextToKore(b: Builders = DefaultBuilders) { consume("ias") val ctr = parseId() // previousParsingLevel is set here consumeWithLeadingWhitespaces("{") - val params = parseList(() => parseSortVariable(parsingLevel = previousParsingLevel), ',', '}') + val params = + parseList(() => parseSortVariable(parsingLevel = previousParsingLevel), ',', '}') consumeWithLeadingWhitespaces("}") val alias = b.Alias(ctr, params) consumeWithLeadingWhitespaces("(") @@ -295,7 +286,7 @@ class TextToKore(b: Builders = DefaultBuilders) { val leftPattern = parsePattern() consumeWithLeadingWhitespaces(":=") val rightPattern = parsePattern() - val att = parseAttributes() + val att = parseAttributes() val decl = b.AliasDeclaration(alias, argSorts, returnSort, leftPattern, rightPattern, att) parseDeclarations(decl +: decls) case ('a', 'x') => // axiom declaration @@ -304,25 +295,24 @@ class TextToKore(b: Builders = DefaultBuilders) { val params = parseList(() => parseSortVariable(parsingLevel = both), ',', '}') consumeWithLeadingWhitespaces("}") val pattern = parsePattern() - val att = parseAttributes() - val decl = b.AxiomDeclaration(params, pattern, att) + val att = parseAttributes() + val decl = b.AxiomDeclaration(params, pattern, att) parseDeclarations(decl +: decls) - case ('c', 'l') => // claim declaration + case ('c', 'l') => // claim declaration consume("aim") consumeWithLeadingWhitespaces("{") val params = parseList(() => parseSortVariable(parsingLevel = both), ',', '}') consumeWithLeadingWhitespaces("}") val pattern = parsePattern() - val att = parseAttributes() - val decl = b.ClaimDeclaration(params, pattern, att) + val att = parseAttributes() + val decl = b.ClaimDeclaration(params, pattern, att) parseDeclarations(decl +: decls) - case (e1, e2) => + case (e1, e2) => throw error("sort, symbol, alias, axiom", e1) } } } - // Import = ModuleName Attributes // private def parseImport(): Declaration = { // val name = parseModuleName() @@ -528,9 +518,11 @@ class TextToKore(b: Builders = DefaultBuilders) { scanner.putback(c) val id = parseId() // previousParsingLevel is set here consumeWithLeadingWhitespaces("{") - val params = parseList(() => parseSort(parsingLevel = previousParsingLevel), ',', '}') + val params = + parseList(() => parseSort(parsingLevel = previousParsingLevel), ',', '}') consumeWithLeadingWhitespaces("}") - (p1: kore.Pattern, p2: kore.Pattern) => b.Application(b.SymbolOrAlias(id, params), Seq(p1, p2)) + (p1: kore.Pattern, p2: kore.Pattern) => + b.Application(b.SymbolOrAlias(id, params), Seq(p1, p2)) } consumeWithLeadingWhitespaces("(") val args = parseList(() => parsePattern(), ',', ')') @@ -547,9 +539,11 @@ class TextToKore(b: Builders = DefaultBuilders) { scanner.putback(c) val id = parseId() // previousParsingLevel is set here consumeWithLeadingWhitespaces("{") - val params = parseList(() => parseSort(parsingLevel = previousParsingLevel), ',', '}') + val params = + parseList(() => parseSort(parsingLevel = previousParsingLevel), ',', '}') consumeWithLeadingWhitespaces("}") - (p1: kore.Pattern, p2: kore.Pattern) => b.Application(b.SymbolOrAlias(id, params), Seq(p1, p2)) + (p1: kore.Pattern, p2: kore.Pattern) => + b.Application(b.SymbolOrAlias(id, params), Seq(p1, p2)) } consumeWithLeadingWhitespaces("(") val args = parseList(() => parsePattern(), ',', ')') @@ -579,9 +573,19 @@ class TextToKore(b: Builders = DefaultBuilders) { // b.DomainValue(sortStr, valueStr) case (err1, err2) => val known = Seq( - "\\top", "\\bottom", "\\and", "\\or", "\\implies", - "\\iff", "\\exists", "\\forall", "\\ceil", "\\floor", - "\\equals", "\\in") + "\\top", + "\\bottom", + "\\and", + "\\or", + "\\implies", + "\\iff", + "\\exists", + "\\forall", + "\\ceil", + "\\floor", + "\\equals", + "\\in" + ) throw error(known.mkString(","), "'\\" + err1 + err2 + "'") } case '@' => // set variable @@ -628,17 +632,17 @@ class TextToKore(b: Builders = DefaultBuilders) { val c = scanner.next() s += c; c match { - case '\\' => - // Always grab one character after the escaping backslash. We do not - // need to grab the entire escape sequence now, because actual - // unquoting does not happen until we have the entire string literal; - // this is only to prevent parsing the final quote prematurely. - s += scanner.next(); - loop(s) - case '"' => - StringUtil.unquoteKString(s.toString()) - case c => - loop(s) + case '\\' => + // Always grab one character after the escaping backslash. We do not + // need to grab the entire escape sequence now, because actual + // unquoting does not happen until we have the entire string literal; + // this is only to prevent parsing the final quote prematurely. + s += scanner.next(); + loop(s) + case '"' => + StringUtil.unquoteKString(s.toString()) + case c => + loop(s) } } @@ -651,24 +655,32 @@ class TextToKore(b: Builders = DefaultBuilders) { } } - // Sort = SortVariable | Name { List{Sort, ",", ")"} } private def parseSort(parsingLevel: ParsingLevel = both): Sort = { val name = parseId(parsingLevel) scanner.nextWithSkippingWhitespaces() match { case '{' => if (previousParsingLevel == meta) { // name is a meta-level id - val metalevelSorts = Seq("#Char", "#CharList", "#String", "#Sort", "#SortList", - "#Symbol", "#SymbolList", "#Variable", "#VariableList", "#Pattern", "#PatternList") + val metalevelSorts = Seq( + "#Char", + "#CharList", + "#String", + "#Sort", + "#SortList", + "#Symbol", + "#SymbolList", + "#Variable", + "#VariableList", + "#Pattern", + "#PatternList" + ) if (metalevelSorts.contains(name)) { consumeWithLeadingWhitespaces("}") // no params b.CompoundSort(name, Seq.empty[Sort]) - } - else { + } else { throw error("", name) // not a valid meta-level sort } - } - else { // name is an object-level id + } else { // name is an object-level id val params = parseList(() => parseSort(objt), ',', '}') // params should be object-level consumeWithLeadingWhitespaces("}") b.CompoundSort(name, params) @@ -701,14 +713,14 @@ class TextToKore(b: Builders = DefaultBuilders) { } private def parseId(parsingLevel: ParsingLevel = both): String = { - def loop(s: StringBuilder): String = { + def loop(s: StringBuilder): String = scanner.next() match { case c if isObjectIdChar(c) => s += c; loop(s) - case c => scanner.putback(c) + case c => + scanner.putback(c) s.toString() } - } scanner.nextWithSkippingWhitespaces() match { case '#' => // going to parse a meta-level id: either #ID or #`ID @@ -732,8 +744,7 @@ class TextToKore(b: Builders = DefaultBuilders) { "#" + loop(new StringBuilder(c.toString())) case err => throw error("", err) } - } - else { + } else { // expect only object-level throw error("", '#') } @@ -741,14 +752,13 @@ class TextToKore(b: Builders = DefaultBuilders) { previousParsingLevel = objt // if parse succeeds, the level is object if (parsingLevel == both || parsingLevel == objt) { // expect both levels or only object-level - val id = loop(new StringBuilder(c.toString)) + val id = loop(new StringBuilder(c.toString)) val kwds = Seq("module", "endmodule", "sort", "symbol", "alias", "axiom") if (kwds.contains(id)) { throw error(" should not be keywords", id) } id - } - else { + } else { // expect only meta-level throw error("", c) } @@ -756,7 +766,8 @@ class TextToKore(b: Builders = DefaultBuilders) { } } - private def isObjectIdChar(c: Char): Boolean = TextToKore.isObjectIdChar(c) // TODO(Daejun): more efficient way? + private def isObjectIdChar(c: Char): Boolean = + TextToKore.isObjectIdChar(c) // TODO(Daejun): more efficient way? private def isLetter(c: Char): Boolean = TextToKore.isLetter(c) @@ -787,21 +798,23 @@ class TextToKore(b: Builders = DefaultBuilders) { private def parseList[T](parseElem: () => T, sep: Char, endsWith: Char): Seq[T] = { assert(sep != endsWith) - def parseList2(lst: Seq[T]): Seq[T] = { + def parseList2(lst: Seq[T]): Seq[T] = scanner.nextWithSkippingWhitespaces() match { - case c if c == endsWith => scanner.putback(c) + case c if c == endsWith => + scanner.putback(c) lst case c if c == sep => val elem = parseElem() parseList2(lst :+ elem) case err => throw error("'" + endsWith + "' or '" + sep + "'", err) } - } scanner.nextWithSkippingWhitespaces() match { - case c if c == endsWith => scanner.putback(c) + case c if c == endsWith => + scanner.putback(c) Seq() - case c => scanner.putback(c) + case c => + scanner.putback(c) val elem = parseElem() parseList2(Seq(elem)) } @@ -812,36 +825,32 @@ class TextToKore(b: Builders = DefaultBuilders) { consume(str) } - private def consume(str: String): Unit = { + private def consume(str: String): Unit = for (c <- str) { val n = scanner.next() if (n == c) () else throw error(c, n) } - } ////////////////////////////////////////////////////////// - private def error(expected: String, actual: String): ParseError = { + private def error(expected: String, actual: String): ParseError = ParseError( "ERROR: " + "Line " + scanner.lineNum + ": Column " + scanner.columnNum + ": " + "Expected " + expected + ", but " + actual + System.lineSeparator() + scanner.line + System.lineSeparator() + List.fill(scanner.columnNum - 1)(' ').mkString + "^" ) - } - private def error(expected: String, actual: Char): ParseError = { + private def error(expected: String, actual: Char): ParseError = error(expected, "'" + actual + "'") - } // private def error(expected: Char, actual: String): ParseError = { // error("'" + expected + "'", actual) // } - private def error(expected: Char, actual: Char): ParseError = { + private def error(expected: Char, actual: Char): ParseError = error("'" + expected + "'", "'" + actual + "'") - } } /** Collection of static methods. */ @@ -850,16 +859,13 @@ object TextToKore { // Lexicon checkers - def isLetter(c: Char): Boolean = { + def isLetter(c: Char): Boolean = ('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z') - } - def isDigit(c: Char): Boolean = { + def isDigit(c: Char): Boolean = '0' <= c && c <= '9' - } - def isObjectIdChar(c: Char): Boolean = { + def isObjectIdChar(c: Char): Boolean = isLetter(c) || isDigit(c) || c == '\'' || c == '-' - } } diff --git a/kore/src/main/scala/org/kframework/parser/treeNodes.scala b/kore/src/main/scala/org/kframework/parser/treeNodes.scala index 84a4fb343da..3f82737f287 100644 --- a/kore/src/main/scala/org/kframework/parser/treeNodes.scala +++ b/kore/src/main/scala/org/kframework/parser/treeNodes.scala @@ -2,19 +2,21 @@ package org.kframework.parser -import org.kframework.attributes.{HasLocation, Location, Source} +import java.util._ +import org.kframework.attributes.HasLocation +import org.kframework.attributes.Location +import org.kframework.attributes.Source import org.kframework.definition.Production import org.kframework.kore.KORE.Sort import org.kframework.utils.StringUtil -import org.pcollections.{ConsPStack, PStack} - -import java.util._ -import scala.collection.JavaConverters._ +import org.pcollections.ConsPStack +import org.pcollections.PStack import scala.collection.mutable +import scala.collection.JavaConverters._ trait Term extends HasLocation { var location: Optional[Location] = Optional.empty() - var source: Optional[Source] = Optional.empty() + var source: Optional[Source] = Optional.empty() } trait ProductionReference extends Term { @@ -55,7 +57,7 @@ case class Ambiguity(items: java.util.Set[Term]) extends Term with HasChildren { def replaceChildren(newChildren: java.util.Collection[Term]): Ambiguity = Ambiguity(new java.util.HashSet[Term](newChildren), location, source) - override def toString: String = "amb(" + (items.asScala mkString ",") + ")" + override def toString: String = "amb(" + (items.asScala.mkString(",")) + ")" override lazy val hashCode: Int = scala.runtime.ScalaRunTime._hashCode(Ambiguity.this) } diff --git a/kore/src/main/scala/org/kframework/rewriter/Rewriter.scala b/kore/src/main/scala/org/kframework/rewriter/Rewriter.scala index fb88f24833f..4aa4e4bfd74 100644 --- a/kore/src/main/scala/org/kframework/rewriter/Rewriter.scala +++ b/kore/src/main/scala/org/kframework/rewriter/Rewriter.scala @@ -2,9 +2,10 @@ package org.kframework.rewriter import java.util.Optional - -import org.kframework.definition.{Module, Rule} -import org.kframework.{RewriterResult, kore} +import org.kframework.definition.Module +import org.kframework.definition.Rule +import org.kframework.kore +import org.kframework.RewriterResult trait RewriterConstructor extends (Module => Rewriter) @@ -16,30 +17,50 @@ trait Rewriter { /** * (disregard this javadoc comment for now) + * * Takes one rewriting step. - * - for regular execution, it returns the next K or False (i.e. an empty Or) - * - for symbolic execution, it can return any formula with symbolic constraints - * - for search, it returns an Or with multiple ground terms as children + * - for regular execution, it returns the next K or False (i.e. an empty Or) + * - for symbolic execution, it can return any formula with symbolic constraints + * - for search, it returns an Or with multiple ground terms as children */ def execute(k: kore.K, depth: Optional[Integer]): RewriterResult - def `match`(k: kore.K, rule: Rule): kore.K - /** * Execute a search of the Transition System. - * @param initialConfiguration The configuration to begin searching from. - * @param depth No. of transitions to consider before termination (Depth of Tree to traverse). Empty represents unbounded. - * @param bound No. of states to consider as final results. Empty represents unbounded. - * @param pattern The rule (pattern + side condition) that we're trying to find a substitution for. - * @return A list of substitutions, denoting all the configurations matching the given rule. + * @param initialConfiguration + * The configuration to begin searching from. + * @param depth + * No. of transitions to consider before termination (Depth of Tree to traverse). Empty + * represents unbounded. + * @param bound + * No. of states to consider as final results. Empty represents unbounded. + * @param pattern + * The rule (pattern + side condition) that we're trying to find a substitution for. + * @return + * A list of substitutions, denoting all the configurations matching the given rule. */ - def search(initialConfiguration: kore.K, depth: Optional[Integer], bound: Optional[Integer], pattern: Rule, searchType: SearchType): kore.K + def search( + initialConfiguration: kore.K, + depth: Optional[Integer], + bound: Optional[Integer], + pattern: Rule, + searchType: SearchType + ): kore.K - def executeAndMatch(k: kore.K, depth: Optional[Integer], rule: Rule): Tuple2[RewriterResult, kore.K] + def executeAndMatch( + k: kore.K, + depth: Optional[Integer], + rule: Rule + ): Tuple2[RewriterResult, kore.K] - def prove(rules: Module, reuseDef:java.lang.Boolean): RewriterResult + def prove(rules: Module, reuseDef: java.lang.Boolean): RewriterResult - def equivalence(firstDef: Rewriter, secondDef: Rewriter, firstSpec: Module, secondSpec: Module): Boolean + def equivalence( + firstDef: Rewriter, + secondDef: Rewriter, + firstSpec: Module, + secondSpec: Module + ): Boolean } diff --git a/kore/src/main/scala/org/kframework/unparser/KOREToTreeNodes.scala b/kore/src/main/scala/org/kframework/unparser/KOREToTreeNodes.scala index b29972344d0..48bc9f6deee 100644 --- a/kore/src/main/scala/org/kframework/unparser/KOREToTreeNodes.scala +++ b/kore/src/main/scala/org/kframework/unparser/KOREToTreeNodes.scala @@ -1,39 +1,60 @@ // Copyright (c) K Team. All Rights Reserved. package org.kframework.unparser +import collection._ import java.util - -import org.kframework.POSet -import org.kframework.attributes.{Att, Location, Source} +import org.kframework.attributes.Att +import org.kframework.attributes.Location +import org.kframework.attributes.Source import org.kframework.builtin.Sorts import org.kframework.definition._ -import org.kframework.kore.{KApply, KToken, KVariable, _} +import org.kframework.kore._ +import org.kframework.kore.KApply +import org.kframework.kore.KToken +import org.kframework.kore.KVariable import org.kframework.parser._ import org.kframework.utils.StringUtil +import org.kframework.POSet import org.pcollections.ConsPStack - -import collection._ import JavaConverters._ object KOREToTreeNodes { - import org.kframework.kore.KORE.{Att => _, _} + import org.kframework.kore.KORE.{ Att => _, _ } - def wellTyped(args: Seq[Sort], p: Production, children: Iterable[Term], subsorts: POSet[Sort]): Boolean = { + def wellTyped( + args: Seq[Sort], + p: Production, + children: Iterable[Term], + subsorts: POSet[Sort] + ): Boolean = { val origP = p.att.getOptional(Att.ORIGINAL_PRD, classOf[Production]).orElse(p) val subst = origP.substitute(args) - val rightPoly = (args.isEmpty && origP.params.nonEmpty) || (p.sort == subst.sort && p.items == subst.items) - return rightPoly && p.nonterminals.zip(children).forall(p => !p._2.isInstanceOf[ProductionReference] || subsorts.lessThanEq(p._2.asInstanceOf[ProductionReference].production.sort, p._1.sort)) + val rightPoly = + (args.isEmpty && origP.params.nonEmpty) || (p.sort == subst.sort && p.items == subst.items) + return rightPoly && p.nonterminals + .zip(children) + .forall(p => + !p._2.isInstanceOf[ProductionReference] || subsorts + .lessThanEq(p._2.asInstanceOf[ProductionReference].production.sort, p._1.sort) + ) } def apply(t: K, mod: Module): Term = t match { - case t: KToken => Constant(t.s, mod.tokenProductionFor(t.sort), t.att.getOptional(classOf[Location]), t.att.getOptional(classOf[Source])) + case t: KToken => + Constant( + t.s, + mod.tokenProductionFor(t.sort), + t.att.getOptional(classOf[Location]), + t.att.getOptional(classOf[Source]) + ) case a: KApply => - val scalaChildren = a.klist.items.asScala map { i: K => apply(i, mod).asInstanceOf[Term] } - val children = ConsPStack.from(scalaChildren.reverse asJava) - val loc = t.att.getOptional(classOf[Location]) - val source = t.att.getOptional(classOf[Source]) - val p = mod.productionsFor(KLabel(a.klabel.name)).filter(!_.att.contains(Att.UNPARSE_AVOID)).head + val scalaChildren = a.klist.items.asScala.map { i: K => apply(i, mod).asInstanceOf[Term] } + val children = ConsPStack.from(scalaChildren.reverse asJava) + val loc = t.att.getOptional(classOf[Location]) + val source = t.att.getOptional(classOf[Source]) + val p = + mod.productionsFor(KLabel(a.klabel.name)).filter(!_.att.contains(Att.UNPARSE_AVOID)).head val subst = if (a.klabel.params.nonEmpty) { val origP = p.att.getOptional(Att.ORIGINAL_PRD, classOf[Production]).orElse(p) origP.substitute(a.klabel.params) @@ -46,19 +67,23 @@ object KOREToTreeNodes { def up(mod: Module)(t: K): K = t match { case v: KVariable => if (v.att.contains(Att.PRETTY_PRINT_WITH_SORT_ANNOTATION)) - KORE.KApply(KORE.KLabel("#SemanticCastTo" + v.att.get(classOf[org.kframework.kore.Sort])), KToken(v.name, Sorts.KVariable, v.att)) + KORE.KApply( + KORE.KLabel("#SemanticCastTo" + v.att.get(classOf[org.kframework.kore.Sort])), + KToken(v.name, Sorts.KVariable, v.att) + ) else KToken(v.name, Sorts.KVariable, v.att) case t: KToken => - val sort = Sort(t.sort.name, t.sort.params:_*) + val sort = Sort(t.sort.name, t.sort.params: _*) KToken(t.s, sort, t.att) case s: KSequence => - upList(mod)(s.items.asScala).foldRight(KApply(KLabel("#EmptyK"), KList(), s.att))((k1, k2) => KApply(KLabel("#KSequence"), KList(k1, k2), s.att)) + upList(mod)(s.items.asScala).foldRight(KApply(KLabel("#EmptyK"), KList(), s.att))((k1, k2) => + KApply(KLabel("#KSequence"), KList(k1, k2), s.att) + ) case r: KRewrite => KApply(KLabel("#KRewrite"), KList(up(mod)(r.left), up(mod)(r.right)), r.att) - case t: KApply => KApply(t.klabel, upList(mod)(t.klist.items.asScala), t.att) + case t: KApply => KApply(t.klabel, upList(mod)(t.klist.items.asScala), t.att) } - def upList(mod: Module)(items: Seq[K]): Seq[K] = { - items map up(mod) _ - } + def upList(mod: Module)(items: Seq[K]): Seq[K] = + items.map(up(mod) _) } diff --git a/kore/src/main/scala/org/kframework/unparser/Unparse.scala b/kore/src/main/scala/org/kframework/unparser/Unparse.scala index e2a925ab964..77ff0cda114 100644 --- a/kore/src/main/scala/org/kframework/unparser/Unparse.scala +++ b/kore/src/main/scala/org/kframework/unparser/Unparse.scala @@ -2,11 +2,10 @@ package org.kframework.unparser import java.io.PrintStream - +import org.kframework.kore.K +import org.kframework.kore.KLabel import org.kframework.kore.Unapply._ -import org.kframework.kore.{KLabel, InjectedKLabel, K, KApply} import org.kframework.utils.StringUtil - import scala.collection.JavaConverters._ /** @@ -18,64 +17,67 @@ object ToKast { unparse(s => b ++= s, false, 0, k) b.toString() } - def apply(k: K, out: PrintStream): Unit = { + def apply(k: K, out: PrintStream): Unit = unparse(out.print, false, 0, k) - } def apply(l: KLabel): String = unparse(false, l) def escape(s: String): String = StringUtil.enquoteKString(s) - def unparse(inParen: Boolean, l: KLabel) : String = { + def unparse(inParen: Boolean, l: KLabel): String = { var name: String = "" - if (l.name.matches("[#a-z][a-zA-Z0-9]*") - && l.name != "#token" && l.name != "#klabel") { + if ( + l.name.matches("[#a-z][a-zA-Z0-9]*") + && l.name != "#token" && l.name != "#klabel" + ) { name = l.name } else if (inParen) { - name = " `"+ escapeBackTicksAndSlashes(l.name) +'`' + name = " `" + escapeBackTicksAndSlashes(l.name) + '`' } else { name = '`' + escapeBackTicksAndSlashes(l.name) + '`' } if (l.params.isEmpty) { name } else { - name + "{"+ l.params.map(_.name).reduce((s1,s2) => s1 + "," + s2) + "}" + name + "{" + l.params.map(_.name).reduce((s1, s2) => s1 + "," + s2) + "}" } } - def escapeBackTicksAndSlashes(str: String) : String = + def escapeBackTicksAndSlashes(str: String): String = str.replaceAll("\\\\", "\\\\\\\\").replaceAll("`", "\\\\`"); /** - * Recursive worker function for printing KAST terms. - * The extra arguments are needed to respect precedence and the lexical syntax. + * Recursive worker function for printing KAST terms. The extra arguments are needed to respect + * precedence and the lexical syntax. + * + * - Precedence level 0 is for the top of a term or within an argument list. + * - Precedence level 1 is for arguments of a KRewrite. + * - Precedence level 2 is for entries in a KSequence, * - *
    - *
  • Precedence level 0 is for the top of a term or within an argument list. - *
  • Precedence level 1 is for arguments of a KRewrite. - *
  • Precedence level 2 is for entries in a KSequence, - *
- * The only case where braces may be needed is around a KSequence which is - * an argument of a KRewrite. + * The only case where braces may be needed is around a KSequence which is an argument of a + * KRewrite. * - * When a label that requires quotes is the first item inside a backquote bracket - * whitespace is required, as in {@code `` `_+_`(...} , to prevent the - * label quote from combining with the bracket, - * as in the incorrect {@code ```_+_`(...} + * When a label that requires quotes is the first item inside a backquote bracket whitespace is + * required, as in {@code `` `_+_`(...} , to prevent the label quote from combining with the + * bracket, as in the incorrect {@code ```_+_`(...} * - * @param accumulator The function that accumulates the string to date. ie, either a StringBuilder or - * an output stream of some kind. - * @param inParen True if this term is the leftmost within a set of brackets - * @param prec The current precedence level - * @param k The term to print + * @param accumulator + * The function that accumulates the string to date. ie, either a StringBuilder or an output + * stream of some kind. + * @param inParen + * True if this term is the leftmost within a set of brackets + * @param prec + * The current precedence level + * @param k + * The term to print */ - def unparse(accumulator:String=>Unit, inParen: Boolean, prec: Int, k: K): Unit = k match { - case KToken(s, sort) => accumulator("#token(" + escape(s) + "," + escape(sort.toString) + ")") - case InjectedKLabel(l) => accumulator("#klabel("+apply(l)+")") - case KVariable(v) => accumulator(v.toString) - case KApply(l, List()) => accumulator(unparse(inParen,l)+"(.KList)") + def unparse(accumulator: String => Unit, inParen: Boolean, prec: Int, k: K): Unit = k match { + case KToken(s, sort) => accumulator("#token(" + escape(s) + "," + escape(sort.toString) + ")") + case InjectedKLabel(l) => accumulator("#klabel(" + apply(l) + ")") + case KVariable(v) => accumulator(v.toString) + case KApply(l, List()) => accumulator(unparse(inParen, l) + "(.KList)") case KApply(l, args) => - accumulator(unparse(inParen,l)) + accumulator(unparse(inParen, l)) accumulator("(") var first = true for (a <- args) { @@ -94,19 +96,19 @@ object ToKast { accumulator("~>") unparse(accumulator, false, 2, i) } - case KRewrite(l,r) => + case KRewrite(l, r) => val needParen = prec > 1 if (needParen) accumulator("``") - unparse(accumulator,needParen || inParen,1,l) + unparse(accumulator, needParen || inParen, 1, l) accumulator("=>") - unparse(accumulator,false,1,r) + unparse(accumulator, false, 1, r) if (needParen) accumulator("``") - case KAs(l,r) => + case KAs(l, r) => val needParen = prec > 1 if (needParen) accumulator("``") - unparse(accumulator,needParen || inParen,1,l) + unparse(accumulator, needParen || inParen, 1, l) accumulator(" #as ") - unparse(accumulator,false,1,r) + unparse(accumulator, false, 1, r) if (needParen) accumulator("``") } } diff --git a/kore/src/test/scala/org/kframework/POSetTest.scala b/kore/src/test/scala/org/kframework/POSetTest.scala index cf6f909585b..693b11f96a7 100644 --- a/kore/src/test/scala/org/kframework/POSetTest.scala +++ b/kore/src/test/scala/org/kframework/POSetTest.scala @@ -1,10 +1,9 @@ // Copyright (c) K Team. All Rights Reserved. package org.kframework -import org.kframework.utils.errorsystem.KEMException - -import org.junit.Test import org.junit.Assert._ +import org.junit.Test +import org.kframework.utils.errorsystem.KEMException class POSetTest { case class Bar(x: Int) diff --git a/kore/src/test/scala/org/kframework/definition/OuterTest.scala b/kore/src/test/scala/org/kframework/definition/OuterTest.scala index 54e9beb0399..ffb36d75a93 100644 --- a/kore/src/test/scala/org/kframework/definition/OuterTest.scala +++ b/kore/src/test/scala/org/kframework/definition/OuterTest.scala @@ -2,17 +2,19 @@ package org.kframework.definition -import org.junit.{Assert, Test} +import org.junit.Assert +import org.junit.Test import org.kframework.attributes.Att import org.kframework.kore.ADT.KToken -import org.kframework.kore.KORE.Sort import org.kframework.kore.KORE.KLabel +import org.kframework.kore.KORE.Sort class OuterTest { @Test def isPrefixTest(): Unit = { val sort = Sort("foo") - val nt = NonTerminal(sort, None) - val prod1 = Production(Seq(), sort, Seq(Terminal("foo"), Terminal("("), nt, Terminal(")")), Att.empty) + val nt = NonTerminal(sort, None) + val prod1 = + Production(Seq(), sort, Seq(Terminal("foo"), Terminal("("), nt, Terminal(")")), Att.empty) Assert.assertTrue(prod1.isPrefixProduction) val prod2 = Production(Seq(), sort, Seq(Terminal("foo")), Att.empty) Assert.assertFalse(prod2.isPrefixProduction) @@ -20,89 +22,187 @@ class OuterTest { Assert.assertFalse(prod3.isPrefixProduction) val prod4 = Production(Seq(), sort, Seq(Terminal("foo"), Terminal("("), nt), Att.empty) Assert.assertFalse(prod4.isPrefixProduction) - val prod5 = Production(Seq(), sort, Seq(Terminal("foo"), Terminal("("), nt, Terminal(",")), Att.empty) + val prod5 = + Production(Seq(), sort, Seq(Terminal("foo"), Terminal("("), nt, Terminal(",")), Att.empty) Assert.assertFalse(prod5.isPrefixProduction) - val prod6 = Production(Seq(), sort, Seq(Terminal("foo"), Terminal("("), nt, Terminal(","), nt), Att.empty) + val prod6 = + Production(Seq(), sort, Seq(Terminal("foo"), Terminal("("), nt, Terminal(","), nt), Att.empty) Assert.assertFalse(prod6.isPrefixProduction) - val prod7 = Production(Seq(), sort, Seq(Terminal("foo"), Terminal("("), nt, Terminal(","), Terminal(")")), Att.empty) + val prod7 = Production( + Seq(), + sort, + Seq(Terminal("foo"), Terminal("("), nt, Terminal(","), Terminal(")")), + Att.empty + ) Assert.assertFalse(prod7.isPrefixProduction) - val prod8 = Production(Seq(), sort, Seq(Terminal("foo"), Terminal("("), Terminal(")")), Att.empty) + val prod8 = + Production(Seq(), sort, Seq(Terminal("foo"), Terminal("("), Terminal(")")), Att.empty) Assert.assertTrue(prod8.isPrefixProduction) val prod9 = Production(Seq(), sort, Seq(Terminal("("), Terminal(")")), Att.empty) Assert.assertTrue(prod9.isPrefixProduction) - val prod10 = Production(Seq(), sort, Seq(Terminal("("), nt, Terminal(","), nt, Terminal(")")), Att.empty) + val prod10 = + Production(Seq(), sort, Seq(Terminal("("), nt, Terminal(","), nt, Terminal(")")), Att.empty) Assert.assertTrue(prod10.isPrefixProduction) } @Test def recordProductions1(): Unit = { - val uid = UidProvider("") + val uid = UidProvider("") val sort1 = Sort("foo1") val sort2 = Sort("foo2") - val nt1 = NonTerminal(sort1, Some("bar")) - val nt2 = NonTerminal(sort2, Some("baz")) - val prod = Production(Seq(), sort1, Seq(Terminal("foo"), Terminal("("), nt1, Terminal(","), nt2, Terminal(")")), Att.empty) - val newAtt = Att.empty.add(Att.RECORD_PRD, classOf[Production], prod) + val nt1 = NonTerminal(sort1, Some("bar")) + val nt2 = NonTerminal(sort2, Some("baz")) + val prod = Production( + Seq(), + sort1, + Seq(Terminal("foo"), Terminal("("), nt1, Terminal(","), nt2, Terminal(")")), + Att.empty + ) + val newAtt = Att.empty.add(Att.RECORD_PRD, classOf[Production], prod) val records = prod.recordProductions(uid) Assert.assertEquals(7, records.size) - Assert.assertEquals(Set( - Production(Seq(), sort1, Seq(Terminal("foo"), Terminal("("), Terminal("..."), NonTerminal(Sort("foo-+1"), None), Terminal(")")), newAtt), // main - Production(Seq(), Sort("foo-+1"), Seq(Terminal("")), newAtt), // empty - Production(Seq(), Sort("foo-+1"), Seq(NonTerminal(Sort("foo-+1Ne"), None)), newAtt), // subsort - Production(Seq(), Sort("foo-+1Ne"), Seq(NonTerminal(Sort("foo-+1Ne"), None), Terminal(","), NonTerminal(Sort("foo-+1Item"), None)), newAtt), // repeat - Production(Seq(), Sort("foo-+1Ne"), Seq(NonTerminal(Sort("foo-+1Item"), None)), newAtt), // subsort2 - Production(Seq(), Sort("foo-+1Item"), Seq(Terminal("bar"), Terminal(":"), NonTerminal(sort1, None)), newAtt), // item - Production(Seq(), Sort("foo-+1Item"), Seq(Terminal("baz"), Terminal(":"), NonTerminal(sort2, None)), newAtt), // item - ), records) + Assert.assertEquals( + Set( + Production( + Seq(), + sort1, + Seq( + Terminal("foo"), + Terminal("("), + Terminal("..."), + NonTerminal(Sort("foo-+1"), None), + Terminal(")") + ), + newAtt + ), // main + Production(Seq(), Sort("foo-+1"), Seq(Terminal("")), newAtt), // empty + Production( + Seq(), + Sort("foo-+1"), + Seq(NonTerminal(Sort("foo-+1Ne"), None)), + newAtt + ), // subsort + Production( + Seq(), + Sort("foo-+1Ne"), + Seq( + NonTerminal(Sort("foo-+1Ne"), None), + Terminal(","), + NonTerminal(Sort("foo-+1Item"), None) + ), + newAtt + ), // repeat + Production( + Seq(), + Sort("foo-+1Ne"), + Seq(NonTerminal(Sort("foo-+1Item"), None)), + newAtt + ), // subsort2 + Production( + Seq(), + Sort("foo-+1Item"), + Seq(Terminal("bar"), Terminal(":"), NonTerminal(sort1, None)), + newAtt + ), // item + Production( + Seq(), + Sort("foo-+1Item"), + Seq(Terminal("baz"), Terminal(":"), NonTerminal(sort2, None)), + newAtt + ) // item + ), + records + ) } @Test def recordProductions2(): Unit = { - val uid = UidProvider("") + val uid = UidProvider("") val sort1 = Sort("foo1") val sort2 = Sort("foo2") - val nt1 = NonTerminal(sort1, None) - val nt2 = NonTerminal(sort2, Some("baz")) - val prod = Production(Seq(), sort1, Seq(Terminal("foo"), Terminal("("), nt1, Terminal(","), nt2, Terminal(")")), Att.empty) - val newAtt = Att.empty.add(Att.RECORD_PRD, classOf[Production], prod) + val nt1 = NonTerminal(sort1, None) + val nt2 = NonTerminal(sort2, Some("baz")) + val prod = Production( + Seq(), + sort1, + Seq(Terminal("foo"), Terminal("("), nt1, Terminal(","), nt2, Terminal(")")), + Att.empty + ) + val newAtt = Att.empty.add(Att.RECORD_PRD, classOf[Production], prod) val records = prod.recordProductions(uid) Assert.assertEquals(2, records.size) - Assert.assertEquals(Set( - Production(Seq(), sort1, Seq(Terminal("foo"), Terminal("("), Terminal("..."), Terminal(")")), newAtt), - Production(Seq(), sort1, Seq(Terminal("foo"), Terminal("("), Terminal("..."), Terminal("baz"), Terminal(":"), nt2, Terminal(")")), newAtt), - ), records) + Assert.assertEquals( + Set( + Production( + Seq(), + sort1, + Seq(Terminal("foo"), Terminal("("), Terminal("..."), Terminal(")")), + newAtt + ), + Production( + Seq(), + sort1, + Seq( + Terminal("foo"), + Terminal("("), + Terminal("..."), + Terminal("baz"), + Terminal(":"), + nt2, + Terminal(")") + ), + newAtt + ) + ), + records + ) } @Test def recordProductions3(): Unit = { - val uid = UidProvider("") + val uid = UidProvider("") val sort1 = Sort("foo1") val sort2 = Sort("foo2") - val nt1 = NonTerminal(sort1, None) - val nt2 = NonTerminal(sort2, None) - val prod = Production(Seq(), sort1, Seq(Terminal("foo"), Terminal("("), nt1, Terminal(","), nt2, Terminal(")")), Att.empty) - val newAtt = Att.empty.add(Att.RECORD_PRD, classOf[Production], prod) + val nt1 = NonTerminal(sort1, None) + val nt2 = NonTerminal(sort2, None) + val prod = Production( + Seq(), + sort1, + Seq(Terminal("foo"), Terminal("("), nt1, Terminal(","), nt2, Terminal(")")), + Att.empty + ) + val newAtt = Att.empty.add(Att.RECORD_PRD, classOf[Production], prod) val records = prod.recordProductions(uid) Assert.assertEquals(1, records.size) - Assert.assertEquals(Set( - Production(Seq(), sort1, Seq(Terminal("foo"), Terminal("("), Terminal("..."), Terminal(")")), newAtt) - ), records) + Assert.assertEquals( + Set( + Production( + Seq(), + sort1, + Seq(Terminal("foo"), Terminal("("), Terminal("..."), Terminal(")")), + newAtt + ) + ), + records + ) } @Test def klabelAttEquality(): Unit = { - val prod1 = Production(Some(KLabel("foo")), Seq(), Sort("Foo"), Seq(), Att.empty.add(Att.KLABEL, "foo")) - val prod2 = Production(Some(KLabel("foo")), Seq(), Sort("Foo"), Seq(), Att.empty.add(Att.KLABEL, "bar")) + val prod1 = + Production(Some(KLabel("foo")), Seq(), Sort("Foo"), Seq(), Att.empty.add(Att.KLABEL, "foo")) + val prod2 = + Production(Some(KLabel("foo")), Seq(), Sort("Foo"), Seq(), Att.empty.add(Att.KLABEL, "bar")) Assert.assertNotEquals(prod1, prod2) } // Create multiple versions of this sentence with attributes added def toSentenceAttList(sentence: Sentence): List[Sentence] = { - val att1 = Att.empty.add(Att.ASSOC).add(Att.BAG) - val att2 = Att.empty.add(Att.ASSOC).add(Att.CELL) - val att3 = Att.empty.add(Att.BAG).add(Att.CELL) - val att4 = Att.empty.add(Att.BAG).add(Att.HOOK, "A") - val att5 = Att.empty.add(Att.BAG).add(Att.HOOK, "B") - val att6 = Att.empty.add(Att.BAG).add(Att.LABEL, "A") - val att7 = Att.empty.add(Att.BAG).add(Att.LABEL, "B") - val att8 = Att.empty.add(Att.HOOK, "A").add(Att.LABEL, "B") - val att9 = Att.empty.add(Att.HOOK, "B").add(Att.LABEL, "A") + val att1 = Att.empty.add(Att.ASSOC).add(Att.BAG) + val att2 = Att.empty.add(Att.ASSOC).add(Att.CELL) + val att3 = Att.empty.add(Att.BAG).add(Att.CELL) + val att4 = Att.empty.add(Att.BAG).add(Att.HOOK, "A") + val att5 = Att.empty.add(Att.BAG).add(Att.HOOK, "B") + val att6 = Att.empty.add(Att.BAG).add(Att.LABEL, "A") + val att7 = Att.empty.add(Att.BAG).add(Att.LABEL, "B") + val att8 = Att.empty.add(Att.HOOK, "A").add(Att.LABEL, "B") + val att9 = Att.empty.add(Att.HOOK, "B").add(Att.LABEL, "A") val sentenceWithAtt1 = sentence.withAtt(att1) val sentenceWithAtt2 = sentence.withAtt(att2) val sentenceWithAtt3 = sentence.withAtt(att3) @@ -113,15 +213,17 @@ class OuterTest { val sentenceWithAtt8 = sentence.withAtt(att8) val sentenceWithAtt9 = sentence.withAtt(att9) - List(sentenceWithAtt1, - sentenceWithAtt2, - sentenceWithAtt3, - sentenceWithAtt4, - sentenceWithAtt5, - sentenceWithAtt6, - sentenceWithAtt7, - sentenceWithAtt8, - sentenceWithAtt9) + List( + sentenceWithAtt1, + sentenceWithAtt2, + sentenceWithAtt3, + sentenceWithAtt4, + sentenceWithAtt5, + sentenceWithAtt6, + sentenceWithAtt7, + sentenceWithAtt8, + sentenceWithAtt9 + ) } // Asserts that S1 < S2 < ... < Sn @@ -234,7 +336,8 @@ class OuterTest { claim2, claim3, claim4, - claim5) + claim5 + ) val sentenceListWithAtts = sentenceList.flatMap(toSentenceAttList(_)) diff --git a/kore/src/test/scala/org/kframework/definition/VisitorTest.scala b/kore/src/test/scala/org/kframework/definition/VisitorTest.scala index eee09c806e5..41d020a7b46 100644 --- a/kore/src/test/scala/org/kframework/definition/VisitorTest.scala +++ b/kore/src/test/scala/org/kframework/definition/VisitorTest.scala @@ -2,7 +2,8 @@ package org.kframework.definition -import org.junit.{Assert, Test} +import org.junit.Assert +import org.junit.Test trait Foo { def accept(x: DoubleDispatchVisitor) @@ -30,8 +31,4 @@ class FooDoubleDispatchVisitor extends DoubleDispatchVisitor { def visitBuz(x: Buz.type) {} } - - -class VisitorTest { - -} +class VisitorTest {} diff --git a/kore/src/test/scala/org/kframework/parser/kore/InterfaceTest.scala b/kore/src/test/scala/org/kframework/parser/kore/InterfaceTest.scala index c1d17a14072..9fb8660792e 100644 --- a/kore/src/test/scala/org/kframework/parser/kore/InterfaceTest.scala +++ b/kore/src/test/scala/org/kframework/parser/kore/InterfaceTest.scala @@ -2,8 +2,9 @@ package org.kframework.parser.kore -import org.junit.{Assert, Test} -import org.kframework.parser.kore.implementation.{DefaultBuilders => b} +import org.junit.Assert +import org.junit.Test +import org.kframework.parser.kore.implementation.{ DefaultBuilders => b } class InterfaceTest { @@ -171,4 +172,3 @@ class InterfaceTest { } } } - diff --git a/kore/src/test/scala/org/kframework/parser/kore/parser/TextToKoreTest.scala b/kore/src/test/scala/org/kframework/parser/kore/parser/TextToKoreTest.scala index 48eebe0788a..6022c45d69d 100644 --- a/kore/src/test/scala/org/kframework/parser/kore/parser/TextToKoreTest.scala +++ b/kore/src/test/scala/org/kframework/parser/kore/parser/TextToKoreTest.scala @@ -2,38 +2,60 @@ package org.kframework.parser.kore.parser -import org.junit.{Assert, Test} - -import org.kframework.parser.kore.implementation.{DefaultBuilders => b} +import org.junit.Assert +import org.junit.Test +import org.kframework.parser.kore.implementation.{ DefaultBuilders => b } class TextToKoreTest { @Test def testMultiOr(): Unit = { - val kore1 = "\\or{SortInt{}}(\\dv{SortInt{}}(\"1\"), \\dv{SortInt{}}(\"2\"), \\dv{SortInt{}}(\"3\"))" + val kore1 = + "\\or{SortInt{}}(\\dv{SortInt{}}(\"1\"), \\dv{SortInt{}}(\"2\"), \\dv{SortInt{}}(\"3\"))" val parser = new TextToKore() - val ast1 = parser.parsePattern(kore1) - val int = b.CompoundSort("SortInt", Seq()) - Assert.assertEquals(b.Or(int, Seq(b.DomainValue(int, "1"), b.DomainValue(int, "2"), b.DomainValue(int, "3"))), ast1) + val ast1 = parser.parsePattern(kore1) + val int = b.CompoundSort("SortInt", Seq()) + Assert.assertEquals( + b.Or(int, Seq(b.DomainValue(int, "1"), b.DomainValue(int, "2"), b.DomainValue(int, "3"))), + ast1 + ) } @Test def testMultiAnd(): Unit = { - val kore1 = "\\and{SortInt{}}(\\dv{SortInt{}}(\"1\"), \\dv{SortInt{}}(\"2\"), \\dv{SortInt{}}(\"3\"))" + val kore1 = + "\\and{SortInt{}}(\\dv{SortInt{}}(\"1\"), \\dv{SortInt{}}(\"2\"), \\dv{SortInt{}}(\"3\"))" val parser = new TextToKore() - val ast1 = parser.parsePattern(kore1) - val int = b.CompoundSort("SortInt", Seq()) - Assert.assertEquals(b.And(int, Seq(b.DomainValue(int, "1"), b.DomainValue(int, "2"), b.DomainValue(int, "3"))), ast1) + val ast1 = parser.parsePattern(kore1) + val int = b.CompoundSort("SortInt", Seq()) + Assert.assertEquals( + b.And(int, Seq(b.DomainValue(int, "1"), b.DomainValue(int, "2"), b.DomainValue(int, "3"))), + ast1 + ) } @Test def testAssocApplication(): Unit = { val parser = new TextToKore() - val int = b.CompoundSort("SortInt", Seq()) + val int = b.CompoundSort("SortInt", Seq()) - val koreLeft = "\\left-assoc{}(Lbl'Unds'Map'Unds{}(\\dv{SortInt{}}(\"1\"), \\dv{SortInt{}}(\"1\")))" + val koreLeft = + "\\left-assoc{}(Lbl'Unds'Map'Unds{}(\\dv{SortInt{}}(\"1\"), \\dv{SortInt{}}(\"1\")))" val astLeft = parser.parsePattern(koreLeft) - Assert.assertEquals(b.Application(b.SymbolOrAlias("Lbl'Unds'Map'Unds", Seq()), Seq(b.DomainValue(int, "1"), b.DomainValue(int, "1"))), astLeft) - - val koreRight = "\\right-assoc{}(Lbl'Unds'Map'Unds{}(\\dv{SortInt{}}(\"1\"), \\dv{SortInt{}}(\"1\")))" + Assert.assertEquals( + b.Application( + b.SymbolOrAlias("Lbl'Unds'Map'Unds", Seq()), + Seq(b.DomainValue(int, "1"), b.DomainValue(int, "1")) + ), + astLeft + ) + + val koreRight = + "\\right-assoc{}(Lbl'Unds'Map'Unds{}(\\dv{SortInt{}}(\"1\"), \\dv{SortInt{}}(\"1\")))" val astRight = parser.parsePattern(koreRight) - Assert.assertEquals(b.Application(b.SymbolOrAlias("Lbl'Unds'Map'Unds", Seq()), Seq(b.DomainValue(int, "1"), b.DomainValue(int, "1"))), astRight) + Assert.assertEquals( + b.Application( + b.SymbolOrAlias("Lbl'Unds'Map'Unds", Seq()), + Seq(b.DomainValue(int, "1"), b.DomainValue(int, "1")) + ), + astRight + ) } } diff --git a/kore/src/test/scala/org/kframework/unparser/UnparseTest.scala b/kore/src/test/scala/org/kframework/unparser/UnparseTest.scala index de6175d6ef0..905efa82b2b 100644 --- a/kore/src/test/scala/org/kframework/unparser/UnparseTest.scala +++ b/kore/src/test/scala/org/kframework/unparser/UnparseTest.scala @@ -1,68 +1,82 @@ // Copyright (c) K Team. All Rights Reserved. package org.kframework.unparser -import org.junit.{Assert, Test} +import org.junit.Assert +import org.junit.Test import org.kframework.attributes.Att import org.kframework.kore.ADT import org.kframework.kore.KORE._ class UnparseTest { @Test def Token() { - Assert.assertEquals("""#token("12","Int")""",ToKast(KToken("12", Sort("Int")))) + Assert.assertEquals("""#token("12","Int")""", ToKast(KToken("12", Sort("Int")))) } @Test def EscapeLabel() { - Assert.assertEquals("`_+_`",ToKast(KLabel("_+_"))) + Assert.assertEquals("`_+_`", ToKast(KLabel("_+_"))) } @Test def WrappedKLabel() { - Assert.assertEquals("#klabel(foo)",ToKast(InjectedKLabel('foo, Att.empty))) + Assert.assertEquals("#klabel(foo)", ToKast(InjectedKLabel('foo, Att.empty))) } @Test def EmptyApp() { - Assert.assertEquals("foo(.KList)",ToKast('foo())) + Assert.assertEquals("foo(.KList)", ToKast('foo())) } @Test def NestedApp() { - Assert.assertEquals("foo(a(.KList),b(.KList))",ToKast('foo('a(), 'b()))) + Assert.assertEquals("foo(a(.KList),b(.KList))", ToKast('foo('a(), 'b()))) } @Test def SequenceEmpty() { - Assert.assertEquals(".K",ToKast(ADT.KSequence(List(),Att.empty))) + Assert.assertEquals(".K", ToKast(ADT.KSequence(List(), Att.empty))) } @Test def Sequence() { - Assert.assertEquals("a(.KList)~>b(.KList)~>c(.KList)",ToKast('a()~>'b()~>'c())) + Assert.assertEquals("a(.KList)~>b(.KList)~>c(.KList)", ToKast('a() ~> 'b() ~> 'c())) } @Test def Rewrite() { - Assert.assertEquals("a(.KList)=>b(.KList)",ToKast(KRewrite('a(),'b()))) + Assert.assertEquals("a(.KList)=>b(.KList)", ToKast(KRewrite('a(), 'b()))) } @Test def Tokens() { - Assert.assertEquals("""#token("9","Int")~>#token("Test","String")""",ToKast(intToToken(9)~>"Test")) + Assert.assertEquals( + """#token("9","Int")~>#token("Test","String")""", + ToKast(intToToken(9) ~> "Test") + ) } @Test def Variables() { - Assert.assertEquals("A=>B",ToKast(KRewrite(KVariable("A"),KVariable("B")))) + Assert.assertEquals("A=>B", ToKast(KRewrite(KVariable("A"), KVariable("B")))) } @Test def Precedence1() { - Assert.assertEquals("``a(.KList)=>b(.KList)``~>c(.KList)",ToKast(KRewrite('a(),'b())~>'c())) + Assert.assertEquals("``a(.KList)=>b(.KList)``~>c(.KList)", ToKast(KRewrite('a(), 'b()) ~> 'c())) } @Test def Precedence2() { - Assert.assertEquals("a(.KList)=>b(.KList)~>c(.KList)",ToKast(KRewrite('a(),'b()~>'c()))) + Assert.assertEquals("a(.KList)=>b(.KList)~>c(.KList)", ToKast(KRewrite('a(), 'b() ~> 'c()))) } @Test def TickSpace() { - Assert.assertEquals("`` `_+_`(.KList)=>b(.KList)``~>c(.KList)",ToKast(KRewrite(KLabel("_+_")(),'b())~>'c())) + Assert.assertEquals( + "`` `_+_`(.KList)=>b(.KList)``~>c(.KList)", + ToKast(KRewrite(KLabel("_+_")(), 'b()) ~> 'c()) + ) } - @Test def testKeywords(): Unit = { - Assert.assertEquals("#a(.KList)~>`#klabel`(.KList)~>#klabel(test)~>`#token`(.KList)~>#token(\"1\",\"Int\")", - ToKast(KSequence(KLabel("#a")(), - KLabel("#klabel")(), InjectedKLabel(KLabel("test"),Att.empty), - KLabel("#token")(), KToken("1", Sort("Int"))))) - } + @Test def testKeywords(): Unit = + Assert.assertEquals( + "#a(.KList)~>`#klabel`(.KList)~>#klabel(test)~>`#token`(.KList)~>#token(\"1\",\"Int\")", + ToKast( + KSequence( + KLabel("#a")(), + KLabel("#klabel")(), + InjectedKLabel(KLabel("test"), Att.empty), + KLabel("#token")(), + KToken("1", Sort("Int")) + ) + ) + ) } diff --git a/pom.xml b/pom.xml index e96702e3d84..53c53a3862a 100644 --- a/pom.xml +++ b/pom.xml @@ -74,8 +74,13 @@ master true UTF-8 - 2.12.18 FastBuild + 2.12 + 18 + ${scala.majorVersion}.${scala.minorVersion} + 2.41.1 + 1.18.1 + 3.7.17 @@ -85,9 +90,9 @@ ${scala.version} - org.scala-lang - scala-reflect - ${scala.version} + org.scala-lang + scala-reflect + ${scala.version} junit @@ -101,6 +106,21 @@ 2.23.4 test + + com.diffplug.spotless + spotless-maven-plugin + ${spotless.version} + + + com.google.googlejavaformat + google-java-format + ${googleJavaFormat.version} + + + org.scalameta + scalafmt-core_${scala.majorVersion} + ${scalafmt.version} + @@ -203,7 +223,7 @@ ${project.basedir} - **/*.xml,**/*.xsd,**/*.md,**/*.k,**/*.kore,**/*.java,**/*.scala,**/*.jj,**/*.jjt,**/*.str,**/*.css,**/*.sty,**/*.tex,**/*.cls + **/*.xml,**/*.xsd,**/*.md,**/*.k,**/*.kore,**/*.java,**/*.scala,**/*.jj,**/*.jjt,**/*.str,**/*.css,**/*.sty,**/*.tex,**/*.cls src/main/config/checkstyle-copyright.xml true true @@ -276,16 +296,37 @@ - com.spotify.fmt - fmt-maven-plugin - 2.21.1 + com.diffplug.spotless + spotless-maven-plugin + ${spotless.version} + false - format + apply + process-sources + + + **/*.java + hs-backend-booster/src/main/native/**,haskell-backend/src/main/native/**,llvm-backend/src/main/native/** + + ${googleJavaFormat.version} + + + + + **/*.scala,**/*.sbt + hs-backend-booster/src/main/native/**,haskell-backend/src/main/native/**,llvm-backend/src/main/native/** + + ${scalafmt.version} + src/main/config/.scalafmt.conf + ${scala.majorVersion} + + + diff --git a/src/main/config/.scalafmt.conf b/src/main/config/.scalafmt.conf new file mode 100644 index 00000000000..5e1b1068972 --- /dev/null +++ b/src/main/config/.scalafmt.conf @@ -0,0 +1,27 @@ +version = 3.7.17 +runner.dialect = scala212 +maxColumn = 100 +align.preset = more +docstrings.style = Asterisk +comments { + wrap = trailing + wrapStandaloneSlcAsSlc = true +} +assumeStandardLibraryStripMargin = true +spaces.inImportCurlyBraces = true +rewrite { + rules = [ + AvoidInfix, + RedundantBraces, + RedundantParens, + SortModifiers, + PreferCurlyFors, + Imports + ] + sortModifiers.order = ["private", "protected", "final", "sealed", "abstract", "implicit", "override", "lazy"] + imports { + expand = true + sort = original + } + trailingCommas.style = never +} From ec06cd8308e777c4dcd8c21643e21f8274874431 Mon Sep 17 00:00:00 2001 From: Anton Savienko Date: Thu, 7 Dec 2023 22:25:29 -0700 Subject: [PATCH 3/5] hot fix (#3860) --- web/pages/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web/pages/index.md b/web/pages/index.md index 1d767391f62..a7497298a11 100644 --- a/web/pages/index.md +++ b/web/pages/index.md @@ -40,7 +40,7 @@ call/cc. ## Resources -- K Approach and Vision: [slide presentation](https://drive.google.com/file/d/1iXda2NyGzKVWxkd02IlXj5Tq5cOM_gNd/view) +- K Approach and Vision (2020): [slide presentation](https://drive.google.com/file/d/1iXda2NyGzKVWxkd02IlXj5Tq5cOM_gNd/view) - A set of reference implementations and tutorials for common programming language features and paradigms is available, although parts of these implementations may not be fully up to date with modern K features. - Read some papers about K on the [Formal Systems Laboratory (FSL)](https://fsl.cs.illinois.edu/publications/). - [Matching logic](http://matching-logic.org/) webpage at UIUC (USA). From 85a2aa8f1330c7b0cec56094d92750568e4462b0 Mon Sep 17 00:00:00 2001 From: Scott Guest Date: Fri, 8 Dec 2023 01:29:45 -0500 Subject: [PATCH 4/5] Clean up `{...}<:S` strict cast syntax (#3853) This PR cleans up a few issues related to the `{...}<:S` syntax for strict casts. Specifically, - Add a section to Lesson 1.11 explaining the need for the braced strict cast syntax - Change the klabel from `#InnerCast` to `#SyntacticCastBraced` - `#InnerCast` was a holdover from prior to #2352 - Opinionatedly, change the syntax from `{...}<:S` to `{...}::S` - Makes it more obvious this is just an alternative syntax for strict casts `::S` - To me, the syntax `<:S` is misleading in that it reads as "subsort of `S`", but the actual meaning is "exactly the sort `S` and not a proper subsort". - Minimal fallout - there is only one rule in `rv-match` and two tests in `pyk` where this needs to be changed (https://github.com/search?q=org%3Aruntimeverification+%7D%3C%3A&type=code) The commit history is clean and I can just drop the last commit if we don't want to change the syntax. --------- Co-authored-by: rv-jenkins --- .../include/kframework/builtin/domains.md | 2 +- .../include/kframework/builtin/kast.md | 2 +- .../k-tutorial/1_basic/11_casts/README.md | 50 +++++++++++++++---- .../1_basic/13_rewrite_rules/README.md | 2 +- k-distribution/k-tutorial/1_basic/commands.sh | 1 + .../parser/inner/RuleGrammarGenerator.java | 12 ++--- .../inner/disambiguation/AddEmptyLists.java | 2 +- .../disambiguation/RemoveBracketVisitor.java | 2 +- .../disambiguation/TypeInferenceVisitor.java | 2 +- .../inner/disambiguation/TypeInferencer.java | 6 +-- .../inference/SortInferencer.java | 2 +- 11 files changed, 58 insertions(+), 25 deletions(-) diff --git a/k-distribution/include/kframework/builtin/domains.md b/k-distribution/include/kframework/builtin/domains.md index 72df2bc186c..c2b669330e9 100644 --- a/k-distribution/include/kframework/builtin/domains.md +++ b/k-distribution/include/kframework/builtin/domains.md @@ -1932,7 +1932,7 @@ module STRING-BUFFER-IN-K [symbolic] syntax StringBuffer ::= String syntax String ::= StringBuffer2String ( StringBuffer ) [function, total] - rule {SB:String +String S:String}<:StringBuffer => (SB +String S)::String + rule {SB:String +String S:String}::StringBuffer => (SB +String S)::String rule .StringBuffer => "" rule StringBuffer2String(S:String) => S endmodule diff --git a/k-distribution/include/kframework/builtin/kast.md b/k-distribution/include/kframework/builtin/kast.md index 9a02996946c..da392abe46a 100644 --- a/k-distribution/include/kframework/builtin/kast.md +++ b/k-distribution/include/kframework/builtin/kast.md @@ -387,7 +387,7 @@ module AUTO-CASTS // generates, for all sorts, productions of the form: // Sort ::= Sort ":Sort" // semantic cast - force the inner term to be `Sort` or a subsort // Sort ::= Sort "::Sort" // strict cast - force the inner term to be exactly `Sort`. Useful for disambiguation - // Sort ::= "{" Sort "}" "<:Sort" // synonym for strict cast + // Sort ::= "{" Sort "}" "::Sort" // synonym for strict cast // Sort ::= "{" K "}" ":>Sort" // projection cast. Allows any term to be placed in a context that expects `Sort` // this is part of the mechanism that allows concrete user syntax in K endmodule diff --git a/k-distribution/k-tutorial/1_basic/11_casts/README.md b/k-distribution/k-tutorial/1_basic/11_casts/README.md index a3270999c72..6480a37a990 100644 --- a/k-distribution/k-tutorial/1_basic/11_casts/README.md +++ b/k-distribution/k-tutorial/1_basic/11_casts/README.md @@ -94,16 +94,18 @@ example, consider the following definition: module LESSON-11-C imports INT - syntax Exp ::= Int | Exp "+" Exp [group(exp)] - syntax Exp2 ::= Exp | Exp2 "+" Exp2 [group(exp2)] + syntax Exp ::= Int + | "add[" Exp "," Exp "]" [group(exp)] + syntax Exp2 ::= Exp + | "add[" Exp2 "," Exp2 "]" [group(exp2)] endmodule ``` This grammar is a little ambiguous and contrived, but it serves to demonstrate how a semantic cast might be insufficient to disambiguate a term. If we were -to write the term `(I1:Int + I2:Int):Exp2`, the term would be ambiguous, +to write the term `add[ I1:Int , I2:Int ]:Exp2`, the term would be ambiguous, because the cast is not sufficiently strict to determine whether you mean -to derive the "+" production in the group `exp` or the one in the group `exp2`. +to derive the "add" production defined in group `exp` or the one in group `exp2`. In this situation, there is a solution: the **strict cast**. For every sort `S` in your grammar, K also defines the following production: @@ -120,9 +122,39 @@ in the **type system** of K: namely, the term inside the cast cannot be a `syntax S ::= S2` exists. As a result, if we were to write in the above grammar the term -`(I1:Int + I2:Int)::Exp2`, then we would know that the second derivation above +`add[ I1:Int , I2:Int ]::Exp2`, then we would know that the second derivation above should be chosen, whereas if we want the first derivation, we could write -`(I1:Int + I2:Int)::Exp`. +`add[ I1:Int , I2:Int ]::Exp`. + +Care must be taken when using a strict cast with brackets. For example, consider a +similar grammar but using an infix "+": + +```k +module LESSON-11-D + imports INT + + syntax Exp ::= Int + | Exp "+" Exp [group(exp)] + syntax Exp2 ::= Exp + | Exp2 "+" Exp2 [group(exp2)] + | "(" Exp2 ")" [bracket] +endmodule +``` + +The term `I1:Int + I2:Int` is ambiguous and could refer to either the production +in group `exp` or the one in group `exp2`. To differentiate, you might try to write +`(I1:Int + I2:Int)::Exp2` similarly to the previous example. + +Unfortunately though, this is still ambiguous. Here, the strict cast `::Exp2` applies +directly to the brackets themselves rather than the underlying term within those brackets. +As a result, it enforces that `(I1:Int + I2:Int)` cannot be a strict subsort of `Exp2`, but +it has no effect on the sort of the subterm `I1:Int + I2:Int`. + +For cases like this, K provides an alternative syntax for strict casts: +``` + syntax S ::= "{" S "}::S" +``` +The ambiguity can then be resolved with `{I1:Int + I2:Int}::Exp` or `{I1:Int + I2:Int}::Exp2`. ### Projection casts @@ -162,7 +194,7 @@ inserted into the code that runs when the rule applies. For example, here is a module that makes use of projection casts: ```k -module LESSON-11-D +module LESSON-11-E imports INT imports BOOL @@ -186,12 +218,12 @@ the projection cast will fail. ## Exercises -1. Extend the `eval` function in `LESSON-11-D` to include Strings and add a `.` +1. Extend the `eval` function in `LESSON-11-E` to include Strings and add a `.` operator which concatenates them. 2. Modify your solution from Lesson 1.9, Exercise 2 by using an `Exp` sort to express the integer and Boolean expressions that it supports, in the same style -as `LESSON-11-D`. Then write an `eval` function that evaluates all terms of +as `LESSON-11-E`. Then write an `eval` function that evaluates all terms of sort `Exp` to either a `Bool` or an `Int`. ## Next lesson diff --git a/k-distribution/k-tutorial/1_basic/13_rewrite_rules/README.md b/k-distribution/k-tutorial/1_basic/13_rewrite_rules/README.md index c7385ab24ca..0694980e6a1 100644 --- a/k-distribution/k-tutorial/1_basic/13_rewrite_rules/README.md +++ b/k-distribution/k-tutorial/1_basic/13_rewrite_rules/README.md @@ -117,7 +117,7 @@ Haskell Backend which performs **symbolic execution**. ### Exercise Pass a program containing no functions to `krun`. You can use a term of sort -`Exp` from `LESSON-11-D`. Observe the output and try to understand why you get +`Exp` from `LESSON-11-E`. Observe the output and try to understand why you get the output you do. Then write two rules that rewrite that program to another. Run `krun --search` on that program and observe both results. Then add a third rule that rewrites one of those results again. Test that that rule applies as diff --git a/k-distribution/k-tutorial/1_basic/commands.sh b/k-distribution/k-tutorial/1_basic/commands.sh index 66ca5cf6aae..f15ab6e30fa 100644 --- a/k-distribution/k-tutorial/1_basic/commands.sh +++ b/k-distribution/k-tutorial/1_basic/commands.sh @@ -32,6 +32,7 @@ kompile 11_casts/README.md --md-selector "k & ! exclude" --main-module LESSON-11 kompile 11_casts/README.md --md-selector "k & ! exclude" --main-module LESSON-11-B --syntax-module LESSON-11-B --output-definition build/11b kompile 11_casts/README.md --md-selector "k & ! exclude" --main-module LESSON-11-C --syntax-module LESSON-11-C --output-definition build/11c kompile 11_casts/README.md --md-selector "k & ! exclude" --main-module LESSON-11-D --syntax-module LESSON-11-D --output-definition build/11d +kompile 11_casts/README.md --md-selector "k & ! exclude" --main-module LESSON-11-E --syntax-module LESSON-11-E --output-definition build/11e kompile 12_syntactic_lists/README.md --md-selector "k & ! exclude" --main-module LESSON-12-A --output-definition build/12a kompile 12_syntactic_lists/README.md --md-selector "k & ! exclude" --main-module LESSON-12-B --output-definition build/12b kompile 12_syntactic_lists/README.md --md-selector "k & ! exclude" --main-module LESSON-12-C --syntax-module LESSON-12-C --output-definition build/12c diff --git a/kernel/src/main/java/org/kframework/parser/inner/RuleGrammarGenerator.java b/kernel/src/main/java/org/kframework/parser/inner/RuleGrammarGenerator.java index 130ed27f176..35f20d563f7 100644 --- a/kernel/src/main/java/org/kframework/parser/inner/RuleGrammarGenerator.java +++ b/kernel/src/main/java/org/kframework/parser/inner/RuleGrammarGenerator.java @@ -783,18 +783,18 @@ private static Set makeCasts( castSort, Seq(NonTerminal(labelSort), Terminal("::" + castSort.toString())), attrs1.add(Att.FORMAT(), "%1%2"))); + prods.add( + Production( + KLabel("#SyntacticCastBraced"), + castSort, + Seq(Terminal("{"), NonTerminal(labelSort), Terminal("}"), Terminal("::" + castSort)), + attrs1.add(Att.FORMAT(), "%1 %2 %3%4"))); prods.add( Production( KLabel("#SemanticCastTo" + labelSort.toString()), labelSort, Seq(NonTerminal(labelSort), Terminal(":" + castSort)), attrs1.add(Att.FORMAT(), "%1%2"))); - prods.add( - Production( - KLabel("#InnerCast"), - castSort, - Seq(Terminal("{"), NonTerminal(labelSort), Terminal("}"), Terminal("<:" + castSort)), - attrs1.add(Att.FORMAT(), "%1 %2 %3%4"))); prods.add( Production( KLabel("#OuterCast"), diff --git a/kernel/src/main/java/org/kframework/parser/inner/disambiguation/AddEmptyLists.java b/kernel/src/main/java/org/kframework/parser/inner/disambiguation/AddEmptyLists.java index 885565d9c97..b4d4589e62d 100644 --- a/kernel/src/main/java/org/kframework/parser/inner/disambiguation/AddEmptyLists.java +++ b/kernel/src/main/java/org/kframework/parser/inner/disambiguation/AddEmptyLists.java @@ -112,7 +112,7 @@ public Tuple2, Term>, Set> apply(TermCons // Never add a list wrapper between a sort annotation and the annotated term if (tcLabelName.equals("#SyntacticCast") || tcLabelName.startsWith("#SemanticCastTo") - || tcLabelName.equals("#InnerCast")) { + || tcLabelName.equals("#SyntacticCastBraced")) { return superApply(tc); } } diff --git a/kernel/src/main/java/org/kframework/parser/inner/disambiguation/RemoveBracketVisitor.java b/kernel/src/main/java/org/kframework/parser/inner/disambiguation/RemoveBracketVisitor.java index 1d914cb360c..3dcf0aace10 100644 --- a/kernel/src/main/java/org/kframework/parser/inner/disambiguation/RemoveBracketVisitor.java +++ b/kernel/src/main/java/org/kframework/parser/inner/disambiguation/RemoveBracketVisitor.java @@ -11,7 +11,7 @@ public class RemoveBracketVisitor extends SafeTransformer { public Term apply(TermCons tc) { if (tc.production().att().contains(Att.BRACKET()) || tc.production().klabel().get().name().equals("#SyntacticCast") - || tc.production().klabel().get().name().equals("#InnerCast")) { + || tc.production().klabel().get().name().equals("#SyntacticCastBraced")) { return apply(tc.get(0)); } return super.apply(tc); diff --git a/kernel/src/main/java/org/kframework/parser/inner/disambiguation/TypeInferenceVisitor.java b/kernel/src/main/java/org/kframework/parser/inner/disambiguation/TypeInferenceVisitor.java index 2a4cf418f1e..f4972b8b99d 100644 --- a/kernel/src/main/java/org/kframework/parser/inner/disambiguation/TypeInferenceVisitor.java +++ b/kernel/src/main/java/org/kframework/parser/inner/disambiguation/TypeInferenceVisitor.java @@ -260,7 +260,7 @@ public Either, Term> apply(Term term) { castContext = CastContext.SEMANTIC; } else if (substituted.klabel().isDefined() && (substituted.klabel().get().name().equals("#SyntacticCast") - || substituted.klabel().get().name().equals("#InnerCast"))) { + || substituted.klabel().get().name().equals("#SyntacticCastBraced"))) { castContext = CastContext.STRICT; } else { castContext = CastContext.NONE; diff --git a/kernel/src/main/java/org/kframework/parser/inner/disambiguation/TypeInferencer.java b/kernel/src/main/java/org/kframework/parser/inner/disambiguation/TypeInferencer.java index 8798ac1151d..71e01fe0099 100644 --- a/kernel/src/main/java/org/kframework/parser/inner/disambiguation/TypeInferencer.java +++ b/kernel/src/main/java/org/kframework/parser/inner/disambiguation/TypeInferencer.java @@ -443,7 +443,7 @@ private static Sort getSortOfCast(TermCons tc) { case "#SyntacticCast": case "#OuterCast": return tc.production().sort(); - case "#InnerCast": + case "#SyntacticCastBraced": return ((NonTerminal) tc.production().items().apply(1)).sort(); default: if (tc.production().klabel().get().name().startsWith("#SemanticCastTo")) { @@ -628,11 +628,11 @@ public String apply(Term t) { if (tc.production().klabel().isDefined() && (tc.production().klabel().get().name().equals("#SyntacticCast") || tc.production().klabel().get().name().startsWith("#SemanticCastTo") - || tc.production().klabel().get().name().equals("#InnerCast"))) { + || tc.production().klabel().get().name().equals("#SyntacticCastBraced"))) { expectedSort = getSortOfCast(tc); isStrictEquality = tc.production().klabel().get().name().equals("#SyntacticCast") - || tc.production().klabel().get().name().equals("#InnerCast"); + || tc.production().klabel().get().name().equals("#SyntacticCastBraced"); if (tc.get(0) instanceof Constant child) { if (child.production().sort().equals(Sorts.KVariable()) || child.production().sort().equals(Sorts.KConfigVar())) { diff --git a/kernel/src/main/java/org/kframework/parser/inner/disambiguation/inference/SortInferencer.java b/kernel/src/main/java/org/kframework/parser/inner/disambiguation/inference/SortInferencer.java index 2de3668a55a..7c88927d511 100644 --- a/kernel/src/main/java/org/kframework/parser/inner/disambiguation/inference/SortInferencer.java +++ b/kernel/src/main/java/org/kframework/parser/inner/disambiguation/inference/SortInferencer.java @@ -112,7 +112,7 @@ private static boolean hasStrictCast(Term t) { if (pr.production().klabel().isDefined()) { KLabel klabel = pr.production().klabel().get(); String label = klabel.name(); - if (label.equals("#SyntacticCast") || label.equals("#InnerCast")) { + if (label.equals("#SyntacticCast") || label.equals("#SyntacticCastBraced")) { return true; } } From f80eee2d4202407bcaac74de64853d5e47af64c8 Mon Sep 17 00:00:00 2001 From: Radu Mereuta Date: Fri, 8 Dec 2023 14:48:20 +0200 Subject: [PATCH 5/5] Enable new TI in kprove (#3855) Move the option to enable new type inference to InnerParsingOptions so it's available in kprove as well. --- k-distribution/include/kframework/ktest.mak | 2 +- .../kframework/kompile/DefinitionParsing.java | 12 +++--- .../kframework/kompile/KompileOptions.java | 18 -------- .../parser/inner/ParseInModule.java | 28 ++++++------- .../parser/inner/RuleGrammarGenerator.java | 41 ++++++++++++++----- .../utils/options/InnerParsingOptions.java | 18 ++++++++ 6 files changed, 70 insertions(+), 49 deletions(-) diff --git a/k-distribution/include/kframework/ktest.mak b/k-distribution/include/kframework/ktest.mak index d76f3f03a9f..39b371b6ca3 100644 --- a/k-distribution/include/kframework/ktest.mak +++ b/k-distribution/include/kframework/ktest.mak @@ -53,7 +53,7 @@ ifeq ($(UNAME), Darwin) endif KOMPILE_FLAGS+=--no-exc-wrap --type-inference-mode checked -KPROVE_FLAGS+=--no-exc-wrap +KPROVE_FLAGS+=--no-exc-wrap --type-inference-mode checked KRUN_FLAGS+=--no-exc-wrap KRUN_OR_LEGACY=$(KRUN) diff --git a/kernel/src/main/java/org/kframework/kompile/DefinitionParsing.java b/kernel/src/main/java/org/kframework/kompile/DefinitionParsing.java index ba8136a20e6..5b227b566dc 100644 --- a/kernel/src/main/java/org/kframework/kompile/DefinitionParsing.java +++ b/kernel/src/main/java/org/kframework/kompile/DefinitionParsing.java @@ -445,7 +445,7 @@ private Definition resolveConfigBubbles(Definition def) { profileRules, files, options.debugTypeInference, - options.typeInferenceMode)) { + innerParsingOptions.typeInferenceMode)) { // each parser gets its own scanner because config labels can conflict with user // tokens parser.getScanner(globalOptions); @@ -514,7 +514,7 @@ private Definition resolveConfigBubbles(Definition def) { profileRules, files, options.debugTypeInference, - options.typeInferenceMode) + innerParsingOptions.typeInferenceMode) .getExtensionModule(); Set configDeclProductions = stream(module.localSentences()) @@ -561,7 +561,7 @@ private Definition resolveNonConfigBubbles( true, files, options.debugTypeInference, - options.typeInferenceMode, + innerParsingOptions.typeInferenceMode, false)) { Scanner scanner; if (deserializeScanner) { @@ -598,7 +598,7 @@ private Module resolveNonConfigBubbles(Module module, Scanner scanner, RuleGramm profileRules, files, options.debugTypeInference, - options.typeInferenceMode) + innerParsingOptions.typeInferenceMode) : RuleGrammarGenerator.getCombinedGrammar( cache.module(), scanner, @@ -606,7 +606,7 @@ private Module resolveNonConfigBubbles(Module module, Scanner scanner, RuleGramm false, files, options.debugTypeInference, - options.typeInferenceMode, + innerParsingOptions.typeInferenceMode, false)) { if (needNewScanner) parser.getScanner(globalOptions); parser.initialize(); @@ -806,7 +806,7 @@ public Rule parseRule(CompiledDefinition compiledDef, String contents, Source so true, files, options.debugTypeInference, - options.typeInferenceMode, + innerParsingOptions.typeInferenceMode, false)) { parser.setScanner(new Scanner(parser, globalOptions, files.resolveKompiled("scanner"))); java.util.Set res = diff --git a/kernel/src/main/java/org/kframework/kompile/KompileOptions.java b/kernel/src/main/java/org/kframework/kompile/KompileOptions.java index 23aaf4be5e3..3f865669673 100644 --- a/kernel/src/main/java/org/kframework/kompile/KompileOptions.java +++ b/kernel/src/main/java/org/kframework/kompile/KompileOptions.java @@ -244,22 +244,4 @@ public String syntaxModule(FileUtil files) { description = "Enable generation of legacy antileft priority predicates.", hidden = true) public boolean enableKoreAntileft; - - public enum TypeInferenceMode { - Z3, - SIMPLESUB, - CHECKED, - // We use an explicit DEFAULT option here so that ParseInModule can set a default which - // applies even for those codepaths that don't rely on KompileOptions - DEFAULT, - } - - @Parameter( - names = "--type-inference-mode", - description = - "Choose between the Z3-based and SimpleSub-based type inference algorithms, or run both" - + " and check that their results are equal. Must be one of " - + "[z3|simplesub|checked|default].", - hidden = true) - public TypeInferenceMode typeInferenceMode = TypeInferenceMode.DEFAULT; } diff --git a/kernel/src/main/java/org/kframework/parser/inner/ParseInModule.java b/kernel/src/main/java/org/kframework/parser/inner/ParseInModule.java index cab42970e4b..f1dea8b64de 100644 --- a/kernel/src/main/java/org/kframework/parser/inner/ParseInModule.java +++ b/kernel/src/main/java/org/kframework/parser/inner/ParseInModule.java @@ -15,7 +15,6 @@ import org.kframework.definition.Module; import org.kframework.definition.Terminal; import org.kframework.definition.TerminalLike; -import org.kframework.kompile.KompileOptions; import org.kframework.kore.K; import org.kframework.kore.Sort; import org.kframework.main.GlobalOptions; @@ -29,6 +28,7 @@ import org.kframework.utils.StringUtil; import org.kframework.utils.errorsystem.KEMException; import org.kframework.utils.file.FileUtil; +import org.kframework.utils.options.InnerParsingOptions; import scala.Tuple2; import scala.Tuple3; import scala.util.Either; @@ -65,7 +65,7 @@ public class ParseInModule implements Serializable, AutoCloseable { private final boolean forGlobalScanner; private final FileUtil files; private final String typeInferenceDebug; - private final KompileOptions.TypeInferenceMode typeInferenceMode; + private final InnerParsingOptions.TypeInferenceMode typeInferenceMode; private final boolean partialParseDebug; ParseInModule( @@ -75,7 +75,7 @@ public class ParseInModule implements Serializable, AutoCloseable { boolean forGlobalScanner, FileUtil files, String typeInferenceDebug, - KompileOptions.TypeInferenceMode typeInferenceMode, + InnerParsingOptions.TypeInferenceMode typeInferenceMode, boolean partialParseDebug) { this( seedModule, @@ -100,7 +100,7 @@ public class ParseInModule implements Serializable, AutoCloseable { boolean forGlobalScanner, FileUtil files, String typeInferenceDebug, - KompileOptions.TypeInferenceMode typeInferenceMode, + InnerParsingOptions.TypeInferenceMode typeInferenceMode, boolean partialParseDebug) { this( seedModule, @@ -128,7 +128,7 @@ private ParseInModule( boolean forGlobalScanner, FileUtil files, String typeInferenceDebug, - KompileOptions.TypeInferenceMode typeInferenceMode, + InnerParsingOptions.TypeInferenceMode typeInferenceMode, boolean partialParseDebug) { this.seedModule = seedModule; this.extensionModule = extensionModule; @@ -141,8 +141,8 @@ private ParseInModule( this.files = files; this.typeInferenceDebug = typeInferenceDebug; this.typeInferenceMode = - typeInferenceMode == KompileOptions.TypeInferenceMode.DEFAULT - ? KompileOptions.TypeInferenceMode.Z3 + typeInferenceMode == InnerParsingOptions.TypeInferenceMode.DEFAULT + ? InnerParsingOptions.TypeInferenceMode.Z3 : typeInferenceMode; this.partialParseDebug = partialParseDebug; } @@ -414,17 +414,17 @@ private Tuple2, Term>, Set> parseStringTe rez3 = new PushTopAmbiguityUp().apply(rez3); startTypeInf = profileRules ? System.currentTimeMillis() : 0; - KompileOptions.TypeInferenceMode infModeForTerm = + InnerParsingOptions.TypeInferenceMode infModeForTerm = SortInferencer.isSupported(rez3) ? typeInferenceMode - : KompileOptions.TypeInferenceMode.Z3; + : InnerParsingOptions.TypeInferenceMode.Z3; - if (infModeForTerm == KompileOptions.TypeInferenceMode.SIMPLESUB - || infModeForTerm == KompileOptions.TypeInferenceMode.CHECKED) { + if (infModeForTerm == InnerParsingOptions.TypeInferenceMode.SIMPLESUB + || infModeForTerm == InnerParsingOptions.TypeInferenceMode.CHECKED) { rez = new SortInferencer(disambModule).apply(rez3, startSymbol, isAnywhere); } - if (infModeForTerm == KompileOptions.TypeInferenceMode.Z3 - || infModeForTerm == KompileOptions.TypeInferenceMode.CHECKED) { + if (infModeForTerm == InnerParsingOptions.TypeInferenceMode.Z3 + || infModeForTerm == InnerParsingOptions.TypeInferenceMode.CHECKED) { TypeInferencer currentInferencer; if (isDebug(source, startLine)) { @@ -440,7 +440,7 @@ private Tuple2, Term>, Set> parseStringTe } Either, Term> z3Rez = new TypeInferenceVisitor(currentInferencer, startSymbol, isAnywhere).apply(rez3); - if (infModeForTerm == KompileOptions.TypeInferenceMode.CHECKED) { + if (infModeForTerm == InnerParsingOptions.TypeInferenceMode.CHECKED) { boolean bothLeft = rez.isLeft() && z3Rez.isLeft(); boolean equalRight = rez.isRight() && z3Rez.isRight() && rez.right().get().equals(z3Rez.right().get()); diff --git a/kernel/src/main/java/org/kframework/parser/inner/RuleGrammarGenerator.java b/kernel/src/main/java/org/kframework/parser/inner/RuleGrammarGenerator.java index 35f20d563f7..51a5c14eb45 100644 --- a/kernel/src/main/java/org/kframework/parser/inner/RuleGrammarGenerator.java +++ b/kernel/src/main/java/org/kframework/parser/inner/RuleGrammarGenerator.java @@ -33,12 +33,12 @@ import org.kframework.definition.Terminal; import org.kframework.definition.UidProvider; import org.kframework.definition.UserList; -import org.kframework.kompile.KompileOptions; import org.kframework.kore.Sort; import org.kframework.kore.SortHead; import org.kframework.parser.inner.kernel.Scanner; import org.kframework.utils.errorsystem.KEMException; import org.kframework.utils.file.FileUtil; +import org.kframework.utils.options.InnerParsingOptions; import scala.Option; import scala.Tuple3; import scala.collection.Seq; @@ -203,7 +203,14 @@ public static boolean isParserSort(Sort s) { /* use this overload if you don't need to profile rule parse times. */ public static ParseInModule getCombinedGrammar(Module mod, FileUtil files) { return getCombinedGrammar( - mod, false, false, false, files, null, KompileOptions.TypeInferenceMode.DEFAULT, false); + mod, + false, + false, + false, + files, + null, + InnerParsingOptions.TypeInferenceMode.DEFAULT, + false); } public static ParseInModule getCombinedGrammar( @@ -215,13 +222,20 @@ public static ParseInModule getCombinedGrammar( false, files, null, - KompileOptions.TypeInferenceMode.DEFAULT, + InnerParsingOptions.TypeInferenceMode.DEFAULT, partialParseDebug); } public static ParseInModule getCombinedGrammar(Module mod, boolean timing, FileUtil files) { return getCombinedGrammar( - mod, timing, false, false, files, null, KompileOptions.TypeInferenceMode.DEFAULT, false); + mod, + timing, + false, + false, + files, + null, + InnerParsingOptions.TypeInferenceMode.DEFAULT, + false); } public static ParseInModule getCombinedGrammar( @@ -229,7 +243,7 @@ public static ParseInModule getCombinedGrammar( boolean timing, FileUtil files, String debugTypeInference, - KompileOptions.TypeInferenceMode typeInferenceMode) { + InnerParsingOptions.TypeInferenceMode typeInferenceMode) { return getCombinedGrammar( mod, timing, false, false, files, debugTypeInference, typeInferenceMode, false); } @@ -237,7 +251,14 @@ public static ParseInModule getCombinedGrammar( public static ParseInModule getCombinedGrammar( Module mod, boolean timing, boolean isBison, FileUtil files) { return getCombinedGrammar( - mod, timing, isBison, false, files, null, KompileOptions.TypeInferenceMode.DEFAULT, false); + mod, + timing, + isBison, + false, + files, + null, + InnerParsingOptions.TypeInferenceMode.DEFAULT, + false); } public static ParseInModule getCombinedGrammar( @@ -249,7 +270,7 @@ public static ParseInModule getCombinedGrammar( forGlobalScanner, files, null, - KompileOptions.TypeInferenceMode.DEFAULT, + InnerParsingOptions.TypeInferenceMode.DEFAULT, false); } @@ -262,7 +283,7 @@ public static ParseInModule getCombinedGrammar( isBison, files, null, - KompileOptions.TypeInferenceMode.DEFAULT, + InnerParsingOptions.TypeInferenceMode.DEFAULT, false); } @@ -291,7 +312,7 @@ public static ParseInModule getCombinedGrammar( boolean forGlobalScanner, FileUtil files, String debugTypeInference, - KompileOptions.TypeInferenceMode typeInferenceMode, + InnerParsingOptions.TypeInferenceMode typeInferenceMode, boolean partialParseDebug) { return new ParseInModule( mod, @@ -311,7 +332,7 @@ public static ParseInModule getCombinedGrammar( boolean isBison, FileUtil files, String debugTypeInference, - KompileOptions.TypeInferenceMode typeInferenceMode, + InnerParsingOptions.TypeInferenceMode typeInferenceMode, boolean partialParseDebug) { return new ParseInModule( mod, diff --git a/kernel/src/main/java/org/kframework/utils/options/InnerParsingOptions.java b/kernel/src/main/java/org/kframework/utils/options/InnerParsingOptions.java index 19dda052663..82cb5634f3b 100644 --- a/kernel/src/main/java/org/kframework/utils/options/InnerParsingOptions.java +++ b/kernel/src/main/java/org/kframework/utils/options/InnerParsingOptions.java @@ -23,4 +23,22 @@ public InnerParsingOptions(Void v) {} descriptionKey = "file", hidden = true) public String profileRules; + + public enum TypeInferenceMode { + Z3, + SIMPLESUB, + CHECKED, + // We use an explicit DEFAULT option here so that ParseInModule can set a default which + // applies even for those codepaths that don't rely on KompileOptions + DEFAULT, + } + + @Parameter( + names = "--type-inference-mode", + description = + "Choose between the Z3-based and SimpleSub-based type inference algorithms, or run both" + + " and check that their results are equal. Must be one of " + + "[z3|simplesub|checked|default].", + hidden = true) + public TypeInferenceMode typeInferenceMode = TypeInferenceMode.DEFAULT; }