1 // A Small Compiler for a Simple Functional Language  | 
     1 // A parser for the Fun language  | 
     2 // (includes a lexer and a parser)  | 
     2 //================================  | 
         | 
     3 //  | 
         | 
     4 // call with   | 
         | 
     5 //  | 
         | 
     6 //     scala fun_parser.scala fact.tks  | 
         | 
     7 //  | 
         | 
     8 //     scala fun_parser.scala defs.tks  | 
         | 
     9 //  | 
         | 
    10 // this will generate a .prs file that can be deserialised back  | 
         | 
    11 // into a list of declarations  | 
     3   | 
    12   | 
     4 object Fun_Parser { | 
    13 object Fun_Parser { | 
     5   | 
    14   | 
     6 import scala.language.implicitConversions      | 
    15 import scala.language.implicitConversions      | 
     7 import scala.language.reflectiveCalls  | 
    16 import scala.language.reflectiveCalls  | 
         | 
    17 import scala.util._   | 
     8 import java.io._  | 
    18 import java.io._  | 
     9   | 
    19   | 
    10 abstract class Token extends Serializable   | 
    20 abstract class Token extends Serializable   | 
    11 case object T_SEMI extends Token  | 
    21 case object T_SEMI extends Token  | 
    12 case object T_COMMA extends Token  | 
    22 case object T_COMMA extends Token  | 
   160   | 
   170   | 
   161   | 
   171   | 
   162 // Reading tokens and Writing parse trees  | 
   172 // Reading tokens and Writing parse trees  | 
   163   | 
   173   | 
   164 def serialise[T](fname: String, data: T) = { | 
   174 def serialise[T](fname: String, data: T) = { | 
   165   val out = new ObjectOutputStream(new FileOutputStream(fname))  | 
   175   import scala.util.Using  | 
   166   out.writeObject(data)  | 
   176   Using(new ObjectOutputStream(new FileOutputStream(fname))) { | 
   167   out.close  | 
   177     out => out.writeObject(data)  | 
   168 }  | 
   178   }  | 
   169   | 
   179 }  | 
   170 def deserialise[T](fname: String) : T = { | 
   180   | 
   171   val in = new ObjectInputStream(new FileInputStream(fname))  | 
   181 def deserialise[T](fname: String) : Try[T] = { | 
   172   val data = in.readObject.asInstanceOf[T]  | 
   182   import scala.util.Using  | 
   173   in.close  | 
   183   Using(new ObjectInputStream(new FileInputStream(fname))) { | 
   174   data  | 
   184     in => in.readObject.asInstanceOf[T]  | 
   175 }  | 
   185   }  | 
   176   | 
   186 }  | 
   177   | 
   187   | 
   178 def main(args: Array[String]) = { | 
   188   | 
         | 
   189 def main(args: Array[String]) : Unit= { | 
   179   val fname = args(0)  | 
   190   val fname = args(0)  | 
   180   val pname = fname.stripSuffix(".tks") ++ ".prs" | 
   191   val pname = fname.stripSuffix(".tks") ++ ".prs" | 
   181   val tks = deserialise[List[Token]](fname)  | 
   192   val tks = deserialise[List[Token]](fname).getOrElse(Nil)  | 
   182   serialise(pname, Prog.parse_single(tks))  | 
   193   serialise(pname, Prog.parse_single(tks))  | 
   183   | 
   194   | 
   184   // testing whether read-back is working  | 
   195   // testing whether read-back is working  | 
   185   //val ptree = deserialise[List[Decl]](pname)  | 
   196   //val ptree = deserialise[List[Decl]](pname).get  | 
   186   //println(s"Reading back from ${pname}:\n${ptree.mkString("\n")}")   | 
   197   //println(s"Reading back from ${pname}:\n${ptree.mkString("\n")}")   | 
   187 }  | 
   198 }  | 
   188   | 
   199   | 
   189 }  | 
   200 }  |