This GitLab instance reached the end of its service life. It won't be possible to create new users or projects.

Please read the deprecation notice for more information concerning the deprecation timeline

Visit migration.git.tu-berlin.de (internal network only) to import your old projects to the new GitLab platform 📥

Parsing.scala 2.1 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61
package de.bbisping.coupledsim.util

trait Parsing {
  
  import Parsing._
  
  type Token
  
  def getTokenPosition(token: Token): Pos
  
  abstract sealed class Parsed[+A] {
    def map[B](f: A => B): Parsed[B]
    def flatMap[B](f: (A, List[Token]) => Parsed[B]): Parsed[B]
    def orElse[B >: A](f: List[Token] => Parsed[B]): Parsed[B]
  }
  
  case class ParseFail[+A](msg: String, remainder: List[Token]) extends Parsed[A] {
    override def map[B](f: A => B): Parsed[B] = ParseFail[B](msg, remainder)
    override def flatMap[B](f: (A, List[Token]) => Parsed[B]): Parsed[B] = ParseFail[B](msg, remainder)
    override def orElse[B >: A](f: List[Token] => Parsed[B]): Parsed[B] = {
      f(remainder) match {
        case ParseFail(msg2, remainder2) =>
          if (remainder2.size < remainder.size) {
            ParseFail(msg2, remainder2)
          } else if (remainder2.size > remainder.size) {
            ParseFail(msg, remainder)
          } else {
            ParseFail(msg + "\n" + msg2, remainder)
          }
        case o => o
      }
    }
    
    def position = remainder.headOption.map(getTokenPosition).getOrElse(Pos0)
  }
  
  case class ParseSuccess[+A](get: A, remainder: List[Token]) extends Parsed[A] {
    override def map[B](f: A => B): Parsed[B] = ParseSuccess[B](f(get), remainder)
    override def flatMap[B](f: (A, List[Token]) => Parsed[B]): Parsed[B] = f(get, remainder)
    override def orElse[B >: A](f: List[Token] => Parsed[B]): Parsed[B] = this
  }
}

object Parsing {
  
  trait AbstractExpression {
    def position: Pos
  }
  
  case class Pos(val line: Int, val col: Int, endLine: Int = -1, endCol: Int = -1) {
    def incLine(lineCount: Int = 1) = Pos(line + lineCount, 0, (if (endLine > -1) endLine + lineCount else endLine), endCol)
    def incCol(columnCount: Int = 1) = Pos(line, col + columnCount, endLine , (if (endCol > -1) endCol + columnCount else endCol))
    
    def getEndLine = (if (endLine > -1) endLine else line)
    def getEndCol = (if (endCol > -1) endCol else col)
    
    def merge(other: Pos) = Pos(line, col, other.getEndLine, other.getEndCol)
  }
  
  object Pos0 extends Pos(0,0)
}