Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- class Pos (val prog: String, val offs: Int, val line: Int, val col: Int){
- def this(prog: String) = this(prog, 0, 1, 1)
- def ch = if(offs == prog.length) -1 else prog(offs)
- def getCol = col
- def inc = ch match{
- case '\n' => new Pos(prog, offs + 1, line + 1, 1)
- case -1 => this
- case _ => new Pos(prog, offs + 1, line, col + 1)
- }
- override def toString = "(" + line + ", " + col + ")"
- }
- object DomainTags extends Enumeration{
- type Tag = Value
- val WHITESPACE, IDENT, NUMBER10, NUMBER16, STR, END_OF_PROGRAM, ERROR = Value
- }
- import DomainTags ._
- class Scanner {
- def scan(start: Pos ): (Tag, Pos) =
- sys.error("syntax error at " + start)
- }
- class Token(val start: Pos, scanner: Scanner){
- val (tag, follow) = start.ch match{
- case -1 => (END_OF_PROGRAM, start)
- case _ => scanner.scan(start)
- }
- def image = start.prog.substring(start.offs, follow.offs)
- def next = new Token(follow, scanner)
- }
- trait Whitespaces extends Scanner{
- private def missWhitespace (pos: Pos): Pos = pos.ch match {
- case ' ' => missWhitespace(pos.inc)
- case '\t' => missWhitespace(pos.inc)
- case '\n' => missWhitespace(pos.inc)
- case _ => pos
- }
- override def scan(start: Pos) = {
- val follow = missWhitespace(start)
- if(start != follow) (WHITESPACE, follow)
- else super.scan(start)
- }
- }
- trait Number10 extends Scanner {
- private def missNumber(pos: Pos): Pos = {
- if (pos.ch.toChar.isDigit) {missNumber(pos.inc)}
- else pos
- }
- override def scan(start: Pos) = {
- val follow = missNumber(start)
- if(start != follow) (NUMBER10, follow)
- else super.scan(start)
- }
- }
- trait Number16 extends Scanner {
- private def missNumber(pos: Pos): Pos = {
- if (pos.ch.toChar.isDigit || (pos.ch.toChar == 'A') || (pos.ch.toChar == 'B') || (pos.ch.toChar == 'C') || (pos.ch.toChar == 'D') || (pos.ch.toChar == 'E') || (pos.ch.toChar == 'F')) {missNumber(pos.inc)}
- else pos
- }
- override def scan(start: Pos) = {
- val pos = start.inc;
- val follow = if((start.ch.toChar == '$') && (pos.ch.toChar.isDigit || (pos.ch.toChar == 'A') || (pos.ch.toChar == 'B') || (pos.ch.toChar == 'C') || (pos.ch.toChar == 'D') || (pos.ch.toChar == 'E') || (pos.ch.toChar == 'F'))) missNumber(start.inc) else start
- if(start != follow) (NUMBER16, follow)
- else super.scan(start)
- }
- }
- trait Ident extends Scanner {
- private def missI(pos: Pos): Pos = {
- if (pos.ch.toChar.isLetter || pos.ch.toChar.isDigit || pos.ch.toChar == '$' ) missI(pos.inc)
- else pos
- }
- override def scan(start: Pos) = {
- val follow = if(start.ch.toChar.isLetter) missI(start) else start
- if(start != follow) (IDENT, follow)
- else super.scan(start)
- }
- }
- trait Error extends Scanner {
- private def missMiss(pos: Pos): Pos = {
- if (!pos.ch.toChar.isLetter && !pos.ch.toChar.isDigit
- && !(pos.ch.toChar == ' ') && !(pos.ch.toChar == '\"') && !(pos.ch.toChar =='\t') && !(pos.ch.toChar =='\n')) missMiss(pos.inc)
- else pos
- }
- override def scan(start: Pos) = {
- val follow = missMiss(start)
- if(start != follow) (ERROR, follow)
- else super.scan(start)
- }
- }
- trait Str extends Scanner {
- private def missK(pos: Pos, temp: Pos, flag:Int, temp2: Pos): (Pos, Pos) = {
- if (pos.inc.getCol == 1 && pos.ch.toChar != '\\') (pos, temp.inc) else {
- if (pos.ch.toChar == '\"' && pos.inc.ch.toChar == '\"' && pos.offs == temp.offs) missK(pos.inc.inc, pos.inc, flag, pos.inc)
- else {
- if (pos.ch.toChar == '\"' && pos.inc.ch.toChar == '\"' && pos.offs != temp.offs) (pos.inc, pos.inc)
- else {
- if (pos.ch.toChar == '\"' && flag == 0) missK(pos.inc, temp.inc, 1, temp2)
- else {
- if (pos.ch.toChar == '\"' && flag == 1) (pos.inc, pos.inc)
- else {
- if (pos.ch == -1) (temp2.inc, temp2.inc.inc)
- else missK(pos.inc, temp.inc, flag, temp2)
- }
- }
- }
- }
- }
- }
- override def scan(start: Pos) = {
- val (follow, temp) = if(start.ch.toChar == '\"') missK(start, start, 0, start) else (start, start)
- if (start != follow) {
- if (follow.offs == temp.offs) (STR, follow)
- else (ERROR, follow)
- }
- else super.scan(start)
- }
- }
- var t = new Token(
- new Pos("123 $123ABC 123$ \"abc\" \" \"\" \" i$1dsd ~~ lol12 \" abc \\n abc\" "), //"\" \"\"kcd124\"123 $12ABC \"\" \"\"\" 12$ABC\" "),
- new Scanner
- with Error
- with Ident
- with Str
- with Number16
- with Number10
- with Whitespaces
- )
- while (t.tag != END_OF_PROGRAM) {
- println(t.tag.toString + " " + t.start + "-" + t.follow + ": " + t.image)
- t = t.next
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement