package wacc import parsley.Parsley import parsley.character import parsley.token.{Basic, Lexer} import parsley.token.descriptions.* import parsley.token.errors._ val errConfig = new ErrorConfig { override def labelSymbol = Map( "!=" -> Label("binary operator"), "%" -> Label("binary operator"), "&&" -> Label("binary operator"), "*" -> Label("binary operator"), "/" -> Label("binary operator"), "<" -> Label("binary operator"), "<=" -> Label("binary operator"), "==" -> Label("binary operator"), ">" -> Label("binary operator"), ">=" -> Label("binary operator"), "||" -> Label("binary operator"), "!" -> Label("unary operator"), "len" -> Label("unary operator"), "ord" -> Label("unary operator"), "chr" -> Label("unary operator"), "bool" -> Label("valid type"), "char" -> Label("valid type"), "int" -> Label("valid type"), "pair" -> Label("valid type"), "string" -> Label("valid type"), "fst" -> Label("pair extraction"), "snd" -> Label("pair extraction"), "false" -> Label("boolean literal"), "true" -> Label("boolean literal"), "=" -> Label("assignment"), "[" -> Label("array index") ) } object lexer { private val desc = LexicalDesc.plain.copy( 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, errConfig) val ident = lexer.lexeme.names.identifier val integer = lexer.lexeme.integer.decimal32[Int] val negateCheck = lexer.nonlexeme.symbol("-") ~> character.digit val charLit = lexer.lexeme.character.ascii val stringLit = lexer.lexeme.string.ascii val implicits = lexer.lexeme.symbol.implicits val errTokens = Seq( lexer.nonlexeme.names.identifier.map(v => s"identifier $v"), lexer.nonlexeme.integer.decimal32[Int].map(n => s"integer $n"), (lexer.nonlexeme.character.ascii).map(c => s"character literal \'$c\'"), lexer.nonlexeme.string.ascii.map(s => s"string literal \"$s\""), character.whitespace.map(_ => "") ) ++ desc.symbolDesc.hardKeywords.map { k => lexer.nonlexeme.symbol(k).as(s"keyword $k") } def fully[A](p: Parsley[A]): Parsley[A] = lexer.fully(p) }