70 lines
2.8 KiB
Kotlin
70 lines
2.8 KiB
Kotlin
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<List<Clause>>() {
|
|
// 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<Term> by (numberParser or variableParser or compoundTermParser or atomParser)
|
|
|
|
private val logicOperandParser: Parser<LogicOperand> by (termParser or compoundTermParser or atomParser) map {
|
|
it as LogicOperand
|
|
}
|
|
|
|
private val conjunctionParser: Parser<Conjunction> by (logicOperandParser and comma and logicOperandParser) use {
|
|
Conjunction(t1, t3)
|
|
}
|
|
private val disjunctionParser: Parser<Disjunction> by (logicOperandParser and semicolon and logicOperandParser) use {
|
|
Disjunction(t1, t3)
|
|
}
|
|
|
|
private val operatorParser: Parser<Operator> 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<Clause> by (factParser or ruleParser)
|
|
|
|
override val rootParser: Parser<List<Clause>> by zeroOrMore(clauseParser)
|
|
}
|