feat: Atom parsing
This commit is contained in:
parent
bd5c825ca2
commit
e749f8c6cb
8 changed files with 212 additions and 11 deletions
116
src/parser/Parser.kt
Normal file
116
src/parser/Parser.kt
Normal file
|
@ -0,0 +1,116 @@
|
|||
package parser
|
||||
|
||||
import lexer.Token
|
||||
import lexer.TokenType
|
||||
import prolog.ast.terms.Atom
|
||||
import prolog.ast.terms.Term
|
||||
|
||||
class Parser(private val tokens: List<Token>) {
|
||||
private var position: Int = 0
|
||||
|
||||
fun parse(): List<Term> {
|
||||
val terms = mutableListOf<Term>()
|
||||
|
||||
// TODO
|
||||
while (hasNext()) {
|
||||
terms.add(parseTerm())
|
||||
}
|
||||
|
||||
return terms
|
||||
}
|
||||
|
||||
/**
|
||||
* Matches the current token with any of the expected types.
|
||||
*
|
||||
* @param types The list of expected token types.
|
||||
* @return True if the current token matches any of the expected types, false otherwise.
|
||||
*/
|
||||
private fun match(types: List<TokenType>): Boolean {
|
||||
for (type in types) {
|
||||
if (check(type)) {
|
||||
next()
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the current token matches the expected type.
|
||||
*/
|
||||
private fun check(type: TokenType): Boolean {
|
||||
return hasNext() && peek().type == type
|
||||
}
|
||||
|
||||
private fun hasNext(): Boolean {
|
||||
// Check if the position is within the tokens list
|
||||
// TODO Check for EOF instead?
|
||||
return position < tokens.size
|
||||
}
|
||||
|
||||
private fun peek(): Token {
|
||||
// Peek should only be called if there is a next token
|
||||
if (!hasNext()) {
|
||||
throw Error("Unexpected end of input")
|
||||
}
|
||||
|
||||
return tokens[position]
|
||||
}
|
||||
|
||||
private fun next(): Token {
|
||||
val token = peek()
|
||||
position++
|
||||
return token
|
||||
}
|
||||
|
||||
private fun previous(): Token {
|
||||
// Previous should only be called if there is a previous token
|
||||
if (position == 0) {
|
||||
throw Error("No previous token")
|
||||
}
|
||||
|
||||
return tokens[position - 1]
|
||||
}
|
||||
|
||||
/* * * * * *
|
||||
* Parsers *
|
||||
* * * * * */
|
||||
|
||||
private fun parseTerm(): Term {
|
||||
// TODO Variable
|
||||
// TODO braced term
|
||||
// TODO Integer Term
|
||||
// TODO Float term
|
||||
// TODO Compound term
|
||||
// TODO Binary operator
|
||||
// TODO Unary operator
|
||||
// TODO list term
|
||||
// TODO curly bracketed term
|
||||
return parseAtom()
|
||||
}
|
||||
|
||||
private fun parseAtom(): Atom {
|
||||
// TODO empty list
|
||||
// TODO empty braces
|
||||
|
||||
return Atom(parseLetterDigit())
|
||||
|
||||
// TODO graphic
|
||||
// TODO quoted
|
||||
// TODO double quoted
|
||||
// TODO back quoted
|
||||
// TODO semicolon
|
||||
// TODO cut
|
||||
}
|
||||
|
||||
private fun parseLetterDigit(): String {
|
||||
// Check if the first character is a lowercase letter
|
||||
if (match(listOf(TokenType.ALPHANUMERIC)) && previous().value[0].isLowerCase()) {
|
||||
return previous().value
|
||||
}
|
||||
|
||||
// TODO How to fix?
|
||||
return ""
|
||||
}
|
||||
}
|
Reference in a new issue