Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Lexer Extensions #6

Draft
wants to merge 9 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
275 changes: 157 additions & 118 deletions .github/workflows/ci.yml

Large diffs are not rendered by default.

38 changes: 30 additions & 8 deletions build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,24 @@ import org.scalajs.linker.interface.ESVersion
import com.typesafe.tools.mima.core._

val projectName = "parsley-cats"
val Scala213 = "2.13.10"
val Scala212 = "2.12.17"
val Scala3 = "3.2.1"
val Scala213 = "2.13.12"
val Scala212 = "2.12.18"
val Scala3 = "3.3.0"
val Java8 = JavaSpec.temurin("8")
val JavaLTS = JavaSpec.temurin("11")
val JavaLatest = JavaSpec.temurin("17")

val mainBranch = "master"

Global / onChangedBuildSource := ReloadOnSourceChanges

val releaseFlags = Seq("-Xdisable-assertions", "-opt:l:method,inline", "-opt-inline-from", "parsley.**", "-opt-warnings:at-inline-failed")
val noReleaseFlagsScala3 = true // maybe some day this can be turned off...

inThisBuild(List(
tlBaseVersion := "1.2",
tlBaseVersion := "1.3",
organization := "com.github.j-mie6",
organizationName := "Parsley Contributors <https://github.com/j-mie6/Parsley/graphs/contributors>",
startYear := Some(2022),
homepage := Some(url("https://github.com/j-mie6/parsley-cats")),
licenses := List("BSD-3-Clause" -> url("https://opensource.org/licenses/BSD-3-Clause")),
Expand All @@ -30,9 +39,11 @@ inThisBuild(List(
ProblemFilters.exclude[MissingClassProblem]("parsley.MonoidKForParsley"),
),
// CI Configuration
tlCiReleaseBranches := Seq("master"),
tlCiReleaseBranches := Seq(mainBranch),
tlSonatypeUseLegacyHost := false,
githubWorkflowJavaVersions := Seq(JavaSpec.temurin("8"), JavaSpec.temurin("11"), JavaSpec.temurin("17")),
tlCiScalafmtCheck := false,
tlCiHeaderCheck := true,
githubWorkflowJavaVersions := Seq(Java8, JavaLTS, JavaLatest),
))

lazy val root = tlCrossRootProject.aggregate(`parsley-cats`)
Expand All @@ -43,13 +54,24 @@ lazy val `parsley-cats` = crossProject(JVMPlatform, JSPlatform, NativePlatform)
.in(file("parsley-cats"))
.settings(
name := projectName,

headerLicenseStyle := HeaderLicenseStyle.SpdxSyntax,
headerEmptyLine := false,

libraryDependencies ++= Seq(
"org.typelevel" %%% "cats-core" % "2.8.0",
"com.github.j-mie6" %%% "parsley" % "4.0.0",
"org.scalatest" %%% "scalatest" % "3.2.12" % Test,
"org.scalatest" %%% "scalatest" % "3.2.17" % Test,
"org.typelevel" %%% "cats-laws" % "2.8.0" % Test,
),

Test / testOptions += Tests.Argument(TestFrameworks.ScalaTest, "-oI"),

scalacOptions ++= {
if (!isSnapshot.value && !(noReleaseFlagsScala3 && scalaBinaryVersion.value == "3")) releaseFlags else Seq.empty
},
)
.jsSettings(
Test / scalaJSLinkerConfig := scalaJSLinkerConfig.value.withESFeatures(_.withESVersion(ESVersion.ES2018))
// this is required until we bump to a higher parsley major/minor (the regex is still in 4.0.0)
Test / scalaJSLinkerConfig := scalaJSLinkerConfig.value.withESFeatures(_.withESVersion(ESVersion.ES2018))
)
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
/* SPDX-FileCopyrightText: © 2022 Parsley Cats Contributors <https://github.com/j-mie6/parsley-cats/graphs/contributors>
/*
* Copyright 2022 Parsley Contributors <https://github.com/j-mie6/Parsley/graphs/contributors>
*
* SPDX-License-Identifier: BSD-3-Clause
*/
package parsley.cats
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
/* SPDX-FileCopyrightText: © 2022 Parsley Cats Contributors <https://github.com/j-mie6/parsley-cats/graphs/contributors>
/*
* Copyright 2022 Parsley Contributors <https://github.com/j-mie6/Parsley/graphs/contributors>
*
* SPDX-License-Identifier: BSD-3-Clause
*/
package parsley.cats
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
/* SPDX-FileCopyrightText: © 2022 Parsley Cats Contributors <https://github.com/j-mie6/parsley-cats/graphs/contributors>
/*
* Copyright 2022 Parsley Contributors <https://github.com/j-mie6/Parsley/graphs/contributors>
*
* SPDX-License-Identifier: BSD-3-Clause
*/
package parsley.cats
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
/* SPDX-FileCopyrightText: © 2022 Parsley Cats Contributors <https://github.com/j-mie6/parsley-cats/graphs/contributors>
/*
* Copyright 2022 Parsley Contributors <https://github.com/j-mie6/Parsley/graphs/contributors>
*
* SPDX-License-Identifier: BSD-3-Clause
*/
package parsley.cats
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
/* SPDX-FileCopyrightText: © 2022 Parsley Cats Contributors <https://github.com/j-mie6/parsley-cats/graphs/contributors>
/*
* Copyright 2022 Parsley Contributors <https://github.com/j-mie6/Parsley/graphs/contributors>
*
* SPDX-License-Identifier: BSD-3-Clause
*/
package parsley.cats
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
/* SPDX-FileCopyrightText: © 2022 Parsley Cats Contributors <https://github.com/j-mie6/parsley-cats/graphs/contributors>
/*
* Copyright 2022 Parsley Contributors <https://github.com/j-mie6/Parsley/graphs/contributors>
*
* SPDX-License-Identifier: BSD-3-Clause
*/
package parsley.cats
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
/* SPDX-FileCopyrightText: © 2022 Parsley Cats Contributors <https://github.com/j-mie6/parsley-cats/graphs/contributors>
/*
* Copyright 2022 Parsley Contributors <https://github.com/j-mie6/Parsley/graphs/contributors>
*
* SPDX-License-Identifier: BSD-3-Clause
*/
package parsley.cats
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
/* SPDX-FileCopyrightText: © 2023 Parsley Cats Contributors <https://github.com/j-mie6/parsley-cats/graphs/contributors>
/*
* Copyright 2022 Parsley Contributors <https://github.com/j-mie6/Parsley/graphs/contributors>
*
* SPDX-License-Identifier: BSD-3-Clause
*/
package parsley.cats
Expand Down Expand Up @@ -127,7 +129,7 @@ object combinator {
* @since 1.2.0
*/
def sepEndBy1[A](p: Parsley[A], sep: =>Parsley[_]): Parsley[NonEmptyList[A]] = parsley.combinator.sepEndBy1(p, sep).map { xxs =>
val (x::xs) = xxs
val (x::xs) = xxs: @unchecked
NonEmptyList(x, xs)
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
/* SPDX-FileCopyrightText: © 2023 Parsley Cats Contributors <https://github.com/j-mie6/parsley-cats/graphs/contributors>
/*
* Copyright 2022 Parsley Contributors <https://github.com/j-mie6/Parsley/graphs/contributors>
*
* SPDX-License-Identifier: BSD-3-Clause
*/
package parsley.cats
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
/* SPDX-FileCopyrightText: © 2022 Parsley Cats Contributors <https://github.com/j-mie6/parsley-cats/graphs/contributors>
/*
* Copyright 2022 Parsley Contributors <https://github.com/j-mie6/Parsley/graphs/contributors>
*
* SPDX-License-Identifier: BSD-3-Clause
*/
package parsley
Expand Down
72 changes: 72 additions & 0 deletions parsley-cats/shared/src/main/scala/parsley/token/cats.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
/*
* Copyright 2022 Parsley Contributors <https://github.com/j-mie6/Parsley/graphs/contributors>
*
* SPDX-License-Identifier: BSD-3-Clause
*/
package parsley.token

import parsley.Parsley
import parsley.cats.combinator.sepBy1

import _root_.cats.data.NonEmptyList
j-mie6 marked this conversation as resolved.
Show resolved Hide resolved

object cats {
implicit class LexerNonEmpty(val lexer: Lexer) {
object cats {
object lexeme {
object separators {
/** This combinator parses '''one''' or more occurrences of `p`, separated by semi-colons.
*
* First parses a `p`. Then parses a semi-colon followed by `p` until there are no more semi-colons.
* The results of the `p`'s, `x,,1,,` through `x,,n,,`, are returned as `NonEmptyList(x,,1,,, .., x,,n,,)`.
* If `p` fails having consumed input, the whole parser fails. Requires at least
* one `p` to have been parsed.
*
* @example {{{
* scala> ...
* scala> val stmts = lexer.lexeme.separators.semiSep1(int)
* scala> stmts.parse("7; 3;2")
* val res0 = Success(NonEmptyList(7; 3; 2))
* scala> stmts.parse("")
* val res1 = Failure(..)
* scala> stmts.parse("1")
* val res2 = Success(NonEmptyList(1))
* scala> stmts.parse("1; 2; ")
* val res3 = Failure(..) // no trailing semi-colon allowed
* }}}
*
* @param p the parser whose results are collected into a list.
* @return a parser that parses `p` delimited by semi-colons, returning the list of `p`'s results.
* @since 1.3.0
*/
def semiSep1[A](p: Parsley[A]): Parsley[NonEmptyList[A]] = sepBy1(p, lexer.lexeme.symbol.semi)
/** This combinator parses '''one''' or more occurrences of `p`, separated by commas.
*
* First parses a `p`. Then parses a comma followed by `p` until there are no more commas.
* The results of the `p`'s, `x,,1,,` through `x,,n,,`, are returned as `NonEmptyList(x,,1,,, .., x,,n,,)`.
* If `p` fails having consumed input, the whole parser fails. Requires at least
* one `p` to have been parsed.
*
* @example {{{
* scala> ...
* scala> val stmts = lexer.lexeme.separators.commaSep1(int)
* scala> stmts.parse("7, 3,2")
* val res0 = Success(NonEmptyList(7, 3, 2))
* scala> stmts.parse("")
* val res1 = Failure(..)
* scala> stmts.parse("1")
* val res2 = Success(NonEmptyList(1))
* scala> stmts.parse("1, 2, ")
* val res3 = Failure(..) // no trailing comma allowed
* }}}
*
* @param p the parser whose results are collected into a list.
* @return a parser that parses `p` delimited by commas, returning the list of `p`'s results.
* @since 1.3.0
*/
def commaSep1[A](p: Parsley[A]): Parsley[NonEmptyList[A]] = sepBy1(p, lexer.lexeme.symbol.comma)
}
}
}
}
}
5 changes: 3 additions & 2 deletions parsley-cats/shared/src/test/scala/parsley/ParsleyTest.scala
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
/* SPDX-FileCopyrightText: © 2023 Parsley Contributors <https://github.com/j-mie6/Parsley/graphs/contributors>
/*
* Copyright 2022 Parsley Contributors <https://github.com/j-mie6/Parsley/graphs/contributors>
*
* SPDX-License-Identifier: BSD-3-Clause
*/
package parsley
Expand All @@ -8,7 +10,6 @@ import org.scalatest.flatspec.AnyFlatSpec
import org.scalatest.matchers.should.Matchers

import parsley.combinator.eof
import parsley.Result
import parsley.errors.{ErrorBuilder, tokenextractors}
import org.scalatest.Inside
import org.scalactic.source.Position
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
/*
* Copyright 2022 Parsley Contributors <https://github.com/j-mie6/Parsley/graphs/contributors>
*
* SPDX-License-Identifier: BSD-3-Clause
*/
package parsley.cats

import org.scalatest.flatspec.AnyFlatSpec
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
/* SPDX-FileCopyrightText: © 2023 Parsley Contributors <https://github.com/j-mie6/Parsley/graphs/contributors>
/*
* Copyright 2022 Parsley Contributors <https://github.com/j-mie6/Parsley/graphs/contributors>
*
* SPDX-License-Identifier: BSD-3-Clause
*/
package parsley.cats
Expand Down
2 changes: 1 addition & 1 deletion project/build.properties
Original file line number Diff line number Diff line change
@@ -1 +1 @@
sbt.version=1.8.2
sbt.version=1.9.6
17 changes: 6 additions & 11 deletions project/plugins.sbt
Original file line number Diff line number Diff line change
@@ -1,23 +1,18 @@
val sbtTypelevelVersion = "0.4.19"
val sbtTypelevelVersion = "0.5.3"

libraryDependencySchemes ++= Seq(
"org.scala-native" % "sbt-scala-native" % VersionScheme.Always,
"org.scala-lang.modules" %% "scala-xml" % VersionScheme.Always,
)

//addSbtPlugin("org.typelevel" % "sbt-typelevel" % sbtTypelevelVersion) // disabled because I don't want headers and formatting checks
addSbtPlugin("org.typelevel" % "sbt-typelevel-settings" % sbtTypelevelVersion)
addSbtPlugin("org.typelevel" % "sbt-typelevel-ci-release" % sbtTypelevelVersion)
addSbtPlugin("org.typelevel" % "sbt-typelevel" % sbtTypelevelVersion)

// Cross Project Setup
addSbtPlugin("org.portable-scala" % "sbt-scalajs-crossproject" % "1.2.0")
addSbtPlugin("org.portable-scala" % "sbt-scala-native-crossproject" % "1.2.0")
addSbtPlugin("org.scala-js" % "sbt-scalajs" % "1.11.0")
addSbtPlugin("org.scala-native" % "sbt-scala-native" % "0.4.8")
addSbtPlugin("org.scala-js" % "sbt-scalajs" % "1.13.2")
addSbtPlugin("org.scala-native" % "sbt-scala-native" % "0.4.15")

// Other
// This is here purely to enable the niceness settings
addSbtPlugin("ch.epfl.scala" % "sbt-bloop" % "1.4.8")
addSbtPlugin("com.beautiful-scala" % "sbt-scalastyle" % "1.5.1")
addSbtPlugin("org.scoverage" % "sbt-scoverage" % "2.0.5")
addSbtPlugin("org.jmotor.sbt" % "sbt-dependency-updates" % "1.2.7")
addSbtPlugin("org.scoverage" % "sbt-scoverage" % "2.0.8")
addSbtPlugin("com.timushev.sbt" % "sbt-rewarn" % "0.1.3")