feat: implemented lexer-backed error builder, error messages are now based on predefined tokens

Co-authored-by: gc1523
This commit is contained in:
Barf-Vader 2025-02-06 17:39:35 +00:00
parent e787d7168f
commit 19880321d7
2 changed files with 17 additions and 3 deletions

View File

@ -80,5 +80,15 @@ object lexer {
val stringLit = lexer.lexeme.string.ascii val stringLit = lexer.lexeme.string.ascii
val implicits = lexer.lexeme.symbol.implicits val implicits = lexer.lexeme.symbol.implicits
val errTokens = Seq(
lexer.nonlexeme.names.identifier.map(v => s"identifier $v"),
lexer.nonlexeme.integer.decimal32[Int].map(n => s"integer $n"),
lexer.nonlexeme.character.ascii.map(c => s"character literal $c"),
lexer.nonlexeme.string.ascii.map(s => s"string literal $s"),
character.whitespace.map(_ => "")
) ++ desc.symbolDesc.hardKeywords.map { k =>
lexer.nonlexeme.symbol(k).as(s"keyword $k")
}
def fully[A](p: Parsley[A]): Parsley[A] = lexer.fully(p) def fully[A](p: Parsley[A]): Parsley[A] = lexer.fully(p)
} }

View File

@ -9,16 +9,17 @@ import parsley.errors.combinator._
import parsley.syntax.zipped._ import parsley.syntax.zipped._
import parsley.cats.combinator.{some} import parsley.cats.combinator.{some}
import cats.data.NonEmptyList import cats.data.NonEmptyList
import parsley.errors.DefaultErrorBuilder
import parsley.errors.ErrorBuilder
import parsley.errors.tokenextractors.LexToken
object parser { object parser {
import lexer.implicits.implicitSymbol import lexer.implicits.implicitSymbol
import lexer.{ident, integer, charLit, stringLit, negateCheck} import lexer.{ident, integer, charLit, stringLit, negateCheck, errTokens}
import ast._ import ast._
//error extensions //error extensions
extension [A](p: Parsley[A]) { extension [A](p: Parsley[A]) {
//combines label and explain together into one function call //combines label and explain together into one function call
def labelAndExplain(label: String, explanation: String): Parsley[A] = { def labelAndExplain(label: String, explanation: String): Parsley[A] = {
p.label(label).explain(explanation) p.label(label).explain(explanation)
@ -46,6 +47,9 @@ object parser {
case Expr case Expr
case Pair case Pair
implicit val builder: ErrorBuilder[String] = new DefaultErrorBuilder with LexToken {
def tokens = errTokens
}
def parse(input: String): Result[String, Program] = parser.parse(input) def parse(input: String): Result[String, Program] = parser.parse(input)
private val parser = lexer.fully(`<program>`) private val parser = lexer.fully(`<program>`)