Checkpoint

This commit is contained in:
Tibo De Peuter 2025-05-01 21:16:48 +02:00
parent 9db1c66781
commit 724e911a6f
Signed by: tdpeuter
GPG key ID: 38297DE43F75FFE2
17 changed files with 288 additions and 95 deletions

View file

@ -7,6 +7,32 @@ import prolog.ast.arithmetic.Float
import prolog.ast.arithmetic.Integer
import prolog.ast.terms.*
/**
* Precedence is based on the following table:
*
* | Precedence | Type | Operators |
* |------------|------|-----------------------------------------------------------------------------------------------|
* | 1200 | xfx | --\>, :-, =\>, ==\> |
* | 1200 | fx | :-, ?- |
* | 1105 | xfy | \| |
* | 1100 | xfy | ; |
* | 1050 | xfy | -\>, \*-\> |
* | 1000 | xfy | , |
* | 990 | xfx | := |
* | 900 | fy | \\+ |
* | 700 | xfx | \<, =, =.., =:=, =\<, ==, =\\=, \>, \>=, \\=, \\==, as, is, \>:\<, :\< |
* | 600 | xfy | : |
* | 500 | yfx | +, -, /\\, \\/, xor |
* | 500 | fx | ? |
* | 400 | yfx | \*, /, //, div, rdiv, \<\<, \>\>, mod, rem |
* | 200 | xfx | \*\* |
* | 200 | xfy | ^ |
* | 200 | fy | +, -, \\ |
* | 100 | yfx | . |
* | 1 | fx | $ |
*
* @see [SWI-Prolog Predicate op/3](https://www.swi-prolog.org/pldoc/man?predicate=op/3)
*/
open class TermsGrammar : Tokens() {
// Basic named terms
@ -19,7 +45,7 @@ open class TermsGrammar : Tokens() {
) use { Atom(text.substring(1, text.length - 1)) }
protected val atom: Parser<Atom> by (quotedAtom or simpleAtom)
protected val compound: Parser<Structure> by (atom * -leftParenthesis * separated(
parser(::term),
parser(::termNoConjunction),
comma,
acceptZero = true
) * -rightParenthesis) use {
@ -30,51 +56,57 @@ open class TermsGrammar : Tokens() {
protected val int: Parser<Integer> by integerToken use { Integer(text.toInt()) }
protected val float: Parser<Float> by floatToken use { Float(text.toFloat()) }
// Operators
protected val ops: Parser<String> by (dummy
// Logic
or comma
or semicolon
// Arithmetic
or plus
or equals
or notEquals
) use { this.text }
protected val simpleOperand: Parser<Operand> by (dummy
// Logic
// Base terms (atoms, compounds, variables, numbers)
protected val baseTerm: Parser<Term> by (dummy
or (-leftParenthesis * parser(::term) * -rightParenthesis)
or compound
or atom
or variable
// Arithmetic
or int
or float
or int
)
protected val operand: Parser<Operand> by (dummy
or parser(::operator)
or simpleOperand
)
protected val operator: Parser<CompoundTerm> by (simpleOperand * ops * operand) use {
CompoundTerm(Atom(t2), listOf(t1, t3))
// Level 200 - prefix operators (+, -, \)
protected val op200: Parser<CompoundTerm> by ((plus or minus) * parser(::term200)) use {
CompoundTerm(Atom(t1.text), listOf(t2))
}
protected val term200: Parser<Term> by (op200 or baseTerm)
// Level 400 - multiplication, division
protected val op400: Parser<String> by (multiply or divide) use { text }
protected val term400: Parser<Term> by (term200 * zeroOrMore(op400 * term200)) use {
t2.fold(t1) { acc, (op, term) -> CompoundTerm(Atom(op), listOf(acc, term)) }
}
// Parts
protected val head: Parser<Head> by (dummy
or compound
or atom
)
protected val body: Parser<Body> by (dummy
or operator
or head
or variable
) use { this as Body }
// Level 500 - addition, subtraction
protected val op500: Parser<String> by (plus or minus) use { text }
protected val term500: Parser<Term> by (term400 * zeroOrMore(op500 * term400)) use {
t2.fold(t1) { acc, (op, term) -> CompoundTerm(Atom(op), listOf(acc, term)) }
}
protected val term: Parser<Term> by (dummy
or float
or int
or variable
or compound
or atom
)
// Level 700 - comparison operators
protected val op700: Parser<String> by (equals or notEquals) use { text }
protected val term700: Parser<Term> by (term500 * optional(op700 * term500)) use {
if (t2 == null) t1 else CompoundTerm(Atom(t2!!.t1), listOf(t1, t2!!.t2))
}
// Level 1000 - conjunction (,)
protected val term1000: Parser<Term> by (term700 * zeroOrMore(comma * term700)) use {
t2.fold(t1) { acc, (_, term) -> CompoundTerm(Atom(","), listOf(acc, term)) }
}
// Level 1100 - disjunction (;)
protected val term1100: Parser<Term> by (term1000 * zeroOrMore(semicolon * term1000)) use {
t2.fold(t1) { acc, (_, term) -> CompoundTerm(Atom(";"), listOf(acc, term)) }
}
// Term - highest level expression
protected val term: Parser<Term> by term1100
protected val termNoConjunction: Parser<Term> by term700
// Parts for clauses
protected val head: Parser<Head> by (compound or atom)
protected val body: Parser<Body> by term use { this as Body }
override val rootParser: Parser<Any> by term
}
}

View file

@ -25,6 +25,9 @@ abstract class Tokens : Grammar<Any>() {
protected val equals: Token by literalToken("=")
protected val notEquals: Token by literalToken("\\=")
protected val plus: Token by literalToken("+")
protected val minus: Token by literalToken("-")
protected val multiply: Token by literalToken("*")
protected val divide: Token by literalToken("/")
protected val dot by literalToken(".")
// Ignored tokens