package better_parser import com.github.h0tk3y.betterParse.combinators.* import com.github.h0tk3y.betterParse.grammar.Grammar import com.github.h0tk3y.betterParse.lexer.literalToken import com.github.h0tk3y.betterParse.lexer.regexToken import com.github.h0tk3y.betterParse.parser.Parser import prolog.ast.logic.Fact import prolog.ast.arithmetic.Integer import prolog.ast.arithmetic.Float import prolog.ast.logic.Clause import prolog.ast.logic.LogicOperand import prolog.ast.logic.Rule import prolog.ast.terms.* import prolog.builtins.Conjunction import prolog.builtins.Disjunction class PrologSourceParser : Grammar>() { // Define the tokens private val atom by regexToken("[a-z][a-zA-Z0-9_]*") private val variable by regexToken("[A-Z][a-zA-Z0-9_]*") private val number by regexToken("-?[0-9]+(\\.[0-9]+)?") private val whitespace by regexToken("\\s+", ignore = true) private val comma by literalToken(",") private val semicolon by literalToken(";") private val neck by literalToken(":-") private val lparen by literalToken("(") private val rparen by literalToken(")") private val dot by literalToken(".") private val atomParser by atom use { Atom(text) } private val variableParser by variable use { Variable(text) } private val intParser by number use { Integer(text.toInt()) } private val floatParser by number use { Float(text.toFloat()) } private val numberParser by (intParser or floatParser) private val compoundTermParser by (atomParser and skip(lparen) and separated( atomParser or variableParser, comma ) and skip(rparen)) use { CompoundTerm(t1, t2.terms) } private val termParser: Parser by (numberParser or variableParser or compoundTermParser or atomParser) private val logicOperandParser: Parser by (termParser or compoundTermParser or atomParser) map { it as LogicOperand } private val conjunctionParser: Parser by (logicOperandParser and comma and logicOperandParser) use { Conjunction(t1, t3) } private val disjunctionParser: Parser by (logicOperandParser and semicolon and logicOperandParser) use { Disjunction(t1, t3) } private val operatorParser: Parser by (conjunctionParser or disjunctionParser) private val headParser by (compoundTermParser or atomParser) private val bodyParser by (operatorParser or compoundTermParser or atomParser) private val factParser by (headParser and dot) use { Fact(t1 as Head) } private val ruleParser by (headParser and neck and bodyParser and dot) use { Rule(t1 as Head, t3 as Body) } private val clauseParser: Parser by (factParser or ruleParser) override val rootParser: Parser> by zeroOrMore(clauseParser) }