package org.example import com.github.h0tk3y.betterParse.combinators.* import com.github.h0tk3y.betterParse.grammar.Grammar import com.github.h0tk3y.betterParse.grammar.parser import com.github.h0tk3y.betterParse.lexer.literalToken import com.github.h0tk3y.betterParse.lexer.regexToken import com.github.h0tk3y.betterParse.parser.Parser class RegexParser : Grammar() { val postfixOperator by regexToken("[+*?]") val alternationSymbol by literalToken("|") val openParenSymbol by literalToken("(") val closeParenSymbol by literalToken(")") val dot by literalToken(".") val charToken by regexToken("[a-zA-Z0-9]") val char by charToken map { CharItem(it.text) } val item: Parser by char or (dot asJust DotItem()) or (skip(openParenSymbol) and (parser(::rootParser)) and skip(closeParenSymbol)) val term: Parser by (item and optional(postfixOperator)) map { result -> result.t1.let { first -> result.t2?.let { when (it.text) { "+" -> PlusItem(first) "*" -> StarItem(first) "?" -> QuestionItem(first) else -> first } } ?: first } } val andThen: Parser by oneOrMore(term) map { items -> items.reduce { left, right -> AndThenItem(left, right) } } val termWithAlternation: Parser by leftAssociative( andThen, alternationSymbol, ) { left, _, right -> AlternationItem(left, right) } override val rootParser: Parser by termWithAlternation }