feat: implement lexer

Merge request lab2425_spring/WACC_37!5

Co-authored-by: Jonny <j.sinteix@gmail.com>
This commit is contained in:
Gleb Koval 2025-02-02 13:37:36 +00:00
commit 41d541050f
4 changed files with 47 additions and 18 deletions

View File

@ -1,4 +1,5 @@
version = 3.8.6 version = 3.8.6
runner.dialect = scala3 runner.dialect = scala3
binPack.literalsExclude = []
maxColumn = 100 maxColumn = 100

View File

@ -1,16 +1,53 @@
package wacc package wacc
import parsley.Parsley import parsley.Parsley
import parsley.token.Lexer import parsley.token.{Basic, Lexer}
import parsley.token.descriptions.* import parsley.token.descriptions.*
object lexer { object lexer {
private val desc = LexicalDesc.plain.copy( private val desc = LexicalDesc.plain.copy(
// your configuration goes here nameDesc = NameDesc.plain.copy(
identifierStart = Basic(c => c.isLetter || c == '_'),
identifierLetter = Basic(c => c.isLetterOrDigit || c == '_')
),
symbolDesc = SymbolDesc.plain.copy(
hardKeywords = Set(
"begin", "end", "is", "skip", "if", "then", "else", "fi", "while", "do", "done", "read",
"free", "return", "exit", "print", "println", "true", "false", "int", "bool", "char",
"string", "pair", "newpair", "fst", "snd", "call", "chr", "ord", "len", "null"
),
hardOperators = Set(
"+", "-", "*", "/", "%", ">", "<", ">=", "<=", "==", "!=", "&&", "||", "!"
)
),
spaceDesc = SpaceDesc.plain.copy(
lineCommentStart = "#"
),
textDesc = TextDesc.plain.copy(
graphicCharacter = Basic(c => c >= ' ' && c != '\\' && c != '\'' && c != '"'),
escapeSequences = EscapeDesc.plain.copy(
literals = Set('\\', '"', '\''),
mapping = Map(
"0" -> '\u0000',
"b" -> '\b',
"t" -> '\t',
"n" -> '\n',
"f" -> '\f',
"r" -> '\r'
)
)
),
numericDesc = NumericDesc.plain.copy(
decimalExponentDesc = ExponentDesc.NoExponents
)
) )
private val lexer = Lexer(desc)
val integer = lexer.lexeme.integer.decimal private val lexer = Lexer(desc)
val ident = lexer.lexeme.names.identifier
val integer = lexer.lexeme.integer.decimal32[Int]
val charLit = lexer.lexeme.character.ascii
val stringLit = lexer.lexeme.string.ascii
val implicits = lexer.lexeme.symbol.implicits val implicits = lexer.lexeme.symbol.implicits
def fully[A](p: Parsley[A]): Parsley[A] = lexer.fully(p) def fully[A](p: Parsley[A]): Parsley[A] = lexer.fully(p)
} }

View File

@ -1,20 +1,8 @@
package wacc package wacc
import parsley.{Parsley, Result} import parsley.Result
import parsley.expr.chain
import lexer.implicits.implicitSymbol
import lexer.{integer, fully}
object parser { object parser {
def parse(input: String): Result[String, BigInt] = parser.parse(input) def parse(input: String): Result[String, BigInt] = parser.parse(input)
private val parser = fully(expr) private val parser = lexer.fully(???)
private val add = (x: BigInt, y: BigInt) => x + y
private val sub = (x: BigInt, y: BigInt) => x - y
private lazy val expr: Parsley[BigInt] =
chain.left1(integer | "(" ~> expr <~ ")")(
("+" as add) | ("-" as sub)
)
} }

View File

@ -39,6 +39,8 @@ class ParallelExamplesSpec extends AnyFlatSpec with BeforeAndAfterAll with Paral
def fileIsDissallowed(filename: String): Boolean = def fileIsDissallowed(filename: String): Boolean =
Seq( Seq(
// format: off
// disable formatting to avoid binPack
"wacc-examples/valid/advanced", "wacc-examples/valid/advanced",
"wacc-examples/valid/array", "wacc-examples/valid/array",
"wacc-examples/valid/basic/exit", "wacc-examples/valid/basic/exit",
@ -85,5 +87,6 @@ class ParallelExamplesSpec extends AnyFlatSpec with BeforeAndAfterAll with Paral
"wacc-examples/invalid/semanticErr/while", "wacc-examples/invalid/semanticErr/while",
// invalid (whack) // invalid (whack)
"wacc-examples/invalid/whack" "wacc-examples/invalid/whack"
// format: on
).find(filename.contains).isDefined ).find(filename.contains).isDefined
} }