feat(parser): Terms parsing

This commit is contained in:
Tibo De Peuter 2025-04-17 21:44:34 +02:00
parent 5d8f2b6f35
commit 69c156024a
Signed by: tdpeuter
GPG key ID: 38297DE43F75FFE2
2 changed files with 217 additions and 0 deletions

View file

@ -0,0 +1,61 @@
package better_parser
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.Token
import com.github.h0tk3y.betterParse.lexer.literalToken
import com.github.h0tk3y.betterParse.lexer.regexToken
import com.github.h0tk3y.betterParse.parser.Parser
import prolog.ast.arithmetic.Float
import prolog.ast.arithmetic.Integer
import prolog.ast.terms.Atom
import prolog.ast.terms.Structure
import prolog.ast.terms.Term
import prolog.ast.terms.Variable
open class SimplePrologParser : Grammar<Any>() {
// Prolog tokens
private val nameToken: Token by regexToken("[a-z][a-zA-Z0-9_]*")
private val variableToken: Token by regexToken("[A-Z][a-zA-Z0-9_]*")
// Arithmetic tokens
private val floatToken: Token by regexToken("-?[1-9][0-9]*\\.[0-9]+")
private val integerToken: Token by regexToken("-?([1-9][0-9]*|0)")
// Special tokens
private val comma: Token by literalToken(",")
private val leftParenthesis: Token by literalToken("(")
private val rightParenthesis: Token by literalToken(")")
// Ignored tokens
private val whitespace: Token by regexToken("\\s+", ignore = true)
private val singleLineComment: Token by regexToken("%[^\\n]*", ignore = true)
private val multiLineComment: Token by regexToken("/\\*.*?\\*/", ignore = true)
// Prolog parsers
private val atomParser: Parser<Atom> by nameToken use { Atom(text) }
private val variableParser: Parser<Variable> by variableToken use { Variable(text) }
private val structureParser: Parser<Structure> by (atomParser and skip(leftParenthesis) and separated(
parser(this::termParser),
comma,
acceptZero = true
) and skip(rightParenthesis)) use {
Structure(t1, t2.terms)
}
// Arithmetic parsers
private val integerParser: Parser<Integer> by integerToken use { Integer(text.toInt()) }
private val floatParser: Parser<Float> by floatToken use {
Float(text.toFloat())
}
private val termParser: Parser<Term> by (floatParser
or integerParser
or variableParser
or structureParser
or atomParser
) map { it }
override val rootParser: Parser<Any> = termParser
}