Advertisement
Guest User

Untitled

a guest
Oct 6th, 2012
51
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Scala 8.24 KB | None | 0 0
  1. import util.parsing.combinator.RegexParsers
  2.  
  3. object FimppParser extends RegexParsers {
  4.  
  5.   var ERRORS:ErrorMessageProvider = Trollestia
  6.   val keywords =
  7.     Set("and","got","i","my","me","with","about","either","or","has","is","have","are","likes","did","only","like","when","had","was","were","in")                 //TODO
  8.   val numbers = List("zero","one","two","three","four","five","six","seven","eight","nine","ten","eleven","twelve")
  9.  
  10.   def fullStop: Parser[Unit] = "." ^^^ ()
  11.   def headerEnd: Parser[Unit] = ("."|":") ^^^ ()
  12.   def sentenceEnd: Parser[Unit] = ("."|"!") ^^^ ()
  13.   def comma: Parser[Unit] = "," ^^^ ()
  14.   def kw(strs: String*): Parser[Unit] = strs match{
  15.     case Seq() => failure(ERRORS.unknownError)
  16.     case Seq(str) =>
  17.       if (str.endsWith("?") && str.length()>1) opt(kw(str.stripSuffix("?"))) ^^^ ()
  18.       else if (str.endsWith("*") && str.length()>1) rep(kw(str.stripSuffix("*"))) ^^^ ()
  19.       else if (str.endsWith("+") && str.length()>1) rep1(kw(str.stripSuffix("+"))) ^^^ ()
  20.       else ("""\b"""+str+"""\b""").r  ^^^ ()
  21.     case _ => ("""\b"""+strs.head+"""\b""").r ~ kw(strs.tail:_*)   ^^^ ()
  22.   }
  23.   def altkw(strs: String*):Parser[Unit] = strs match{
  24.     case Seq() => failure(ERRORS.unknownError).asInstanceOf[Parser[Unit]]
  25.     case Seq(str) => ("""\b"""+str+"""\b""").r ^^^ ()
  26.     case _ => (("""\b"""+strs.head+"""\b""").r | altkw(strs.tail:_*)) ^^^ ()
  27.   }
  28.   def word: Parser[String] = ("""[A-Za-z]+('[a-z]+)?""".r) ^? ({
  29.     case word if !keywords.contains(word) =>
  30.       if(word=="friendship") "magic" else word
  31.   },{ case notAWord =>
  32.     ERRORS.invalidIdentifier(notAWord)
  33.   })
  34.  
  35.   def identifier: Parser[String] = rep1(word) ^^ {l=>l.mkString(" ")}  //TODO: the/a/an
  36.  
  37.   def listOfIdentifiers: Parser[List[String]] = (
  38.     identifier~opt(comma)~and~identifier ^^ {case a~_~_~b => List(a,b)}
  39.     | identifier~comma~listOfIdentifiers ^^ {case a~_~bs => a::bs}
  40.     | identifier ^^ {x:String=>List(x)}
  41.     )
  42.  
  43.   def and: Parser[Unit] = kw("and")
  44.  
  45.   def or: Parser[Unit] = kw("or")
  46.  
  47.   def number: Parser[Long] = (
  48.     (opt(opt(kw("the"))~kw("number"))~>"""[0-9]+""".r) ^^ {s=>s.toLong}
  49.     | word ^? {case word if numbers.contains(word) => numbers.indexOf(word).toLong}
  50.     ) //TODO
  51.  
  52.   def stringLiteral: Parser[Expr] = "\"[^\"]*\"".r ^^ {sl =>
  53.     StringInnardsParser.parseAll(StringInnardsParser.stringInnards,sl.stripPrefix("\"").stripSuffix("\"")).get
  54.   }
  55.  
  56.   def literal: Parser[Expr] = (
  57.     stringLiteral
  58.     | number ^^ {v=>NumberValue(v)}
  59.     )//TODO
  60.   def listExpression: Parser[ListExpression] = (
  61.       simpleExpression~opt(comma)~and~simpleExpression ^^ {case a~_~_~b => ListExpression(List(a,b))}
  62.       | simpleExpression~comma~listExpression ^^ {case a~_~ListExpression(bs) => ListExpression(a::bs)}
  63.       )
  64.   def expression: Parser[Expr] =
  65.     listExpression | kw("only")~>simpleExpression ^^ {e=>ListExpression(List(e))} | simpleExpression
  66.   def simpleExpression: Parser[Expr] = literal | identifier ^^{id=>VariableValue(id)} //TODO
  67.  
  68.   def condition:Parser[Condition] = andCondition | orCondition | simpleCondition
  69.   def simpleCondition:Parser[Condition] = relationalCondition //TODO
  70.   def andCondition:Parser[Conjunction] = (
  71.       simpleCondition~and~simpleCondition ^^ {case c1~_~c2 => Conjunction(List(c1,c2))}
  72.         | simpleCondition~comma~andCondition ^^ {case c1~_~Conjunction(cs) => Conjunction(c1::cs)}
  73.       )
  74.   def orCondition = kw("either?")~>eitherLessOrCondition
  75.   def eitherLessOrCondition:Parser[Alternative] = (
  76.     simpleCondition~or~simpleCondition ^^ {case c1~_~c2 => Alternative(List(c1,c2))}
  77.       | simpleCondition~comma~eitherLessOrCondition ^^ {case c1~_~Alternative(cs) => Alternative(c1::cs)}
  78.     )
  79.   def relationalCondition:Parser[Condition] = (
  80.     expression~condOperator~expression ^^ {case e1~op~e2 => Relational(e1,op,e2)}
  81.       | altkw("everything","everypony")~>kw("in")~>expression~condOperator~expression ^^ {case e1~op~e2 => Relational(e1,"all"+op,e2)}
  82.       | altkw("anything","anypony")~>kw("in")~>expression~condOperator~expression ^^ {case e1~op~e2 => Relational(e1,"all"+op,e2)}
  83.     )
  84.   def hasOrHave:Parser[Unit] = altkw("has","have","had")
  85.   def isOrAre:Parser[Unit] = altkw("is","are","was","were")
  86.   def condOperator:Parser[String] = (
  87.     hasOrHave~kw("less","than") ^^^ "<"
  88.     | hasOrHave~kw("more","than") ^^^ ">"
  89.     ) //TODO
  90.   def function: Parser[Function] = (
  91.     opt(kw("today"))~(kw("i","learned","about?")~>identifier~opt(kw("with")~>listOfIdentifiers)<~headerEnd)
  92.     ~rep(statement) ~
  93.     (kw("that's","about")~>identifier~opt(kw("with")~>listOfIdentifiers)<~sentenceEnd)) ^? ({
  94.     case today~(fName~args)~stats~(fName2~args2) if fName==fName2 =>
  95.       Function(today.isDefined, fName, args.getOrElse(Nil),stats)
  96.     }, {
  97.     case today~(fName~args)~stats~(fName2~args2) =>
  98.       ERRORS.mismatchedFunctionNameInFooter(fName,fName2)
  99.     case _ =>
  100.       ERRORS.unknownError
  101.     })
  102.  
  103.  
  104.   def increment: Parser[Increment] = (
  105.     identifier~(kw("got"))~number~(kw("less")^^^(-1) | kw("fewer")^^^ (-1) | kw("more")^^^1)<~sentenceEnd
  106.     ^^ {
  107.       case i~_~n~dir =>
  108.         Increment(i,n*dir)
  109.     }
  110.   )
  111.   def assignment: Parser[Assignment] = (
  112.     kw("did","you","know","that?")
  113.     ~> identifier
  114.     ~ altkw("likes","is","like","are")
  115.     ~expression<~ "?"
  116.     ^^ {
  117.       case i~_~e=> Assignment(i,e);
  118.     })
  119.   def ifStat: Parser[IfStat] = (
  120.     (kw("when") ~> condition <~ headerEnd)
  121.       ~  rep(statement)
  122.       ~ opt(kw("in","the","end")~comma~kw("i","did","this","instead")~headerEnd~>rep(statement))
  123.       <~ kw("that's","what","i","did")<~sentenceEnd
  124.       ^^ {
  125.       case cond~body1~body2 =>
  126.         IfStat(cond,body1,body2.getOrElse(Nil))
  127.     }
  128.     )
  129.   def whileStat: Parser[WhileStat] = (
  130.     (kw("i","did","this","while") ~> condition <~ headerEnd)
  131.       ~  rep(statement)
  132.       ~ opt(kw("in","the","end")~comma~kw("i","did","this","instead")~headerEnd~>rep(statement))
  133.       <~ kw("that's","what","i","did")<~sentenceEnd
  134.       ^^ {
  135.       case cond~body1~body2 =>
  136.         WhileStat(cond,body1,body2.getOrElse(Nil))
  137.     }
  138.     )
  139.   def printStat: Parser[PrintStat] = kw("i")~>altkw("sang","wrote","said")~>opt(kw("that")|comma|":")~>expression<~sentenceEnd ^^ {e=>PrintStat(e)}
  140.   def statement: Parser[Statement] = assignment | ifStat | whileStat | printStat | increment
  141.  
  142.   def module:Parser[Module] = (
  143.     (kw("dear","princess","celestia") ~> ":" ~> identifier <~ headerEnd)
  144.     ~ rep(function)
  145.     <~ (kw("your","faithful","student")~comma~identifier~opt(sentenceEnd))
  146.     ^^ {
  147.       case name~functions => Module(name,functions)
  148.     }
  149.     )
  150.   def parseFim(s:String):Option[Module] = {
  151.     parseAll(module,s) match {
  152.       case Success(fimModule,_) => Some(fimModule)
  153.       case Failure(errorMsg,_) =>
  154.         println(errorMsg)
  155.         None
  156.     }
  157.   }
  158. }
  159.  
  160. object StringInnardsParser extends RegexParsers {
  161.   override val whiteSpace = "".r
  162.   def expression: Parser[Expr] = """[^"']+""".r ^^ {e=> FimppParser.parseAll(FimppParser.expression,e).get}
  163.  def stringInnards: Parser[Concatenation] = rep(
  164.    ("""[^"']+""".r ^^ {s=>StringValue(s)})
  165.      | ("\'"~>expression<~"\'")
  166.  )^^(l=>Concatenation(l))
  167. }
  168.  
  169. case class Function(main:Boolean, name:String, argNames:List[String], body:List[Statement])
  170. sealed trait Expr
  171. case class NumberValue(value: Long)  extends Expr
  172. case class StringValue(value: String) extends Expr
  173. case class Concatenation(exprs: List[Expr]) extends Expr
  174. case class ListExpression(elems: List[Expr]) extends Expr
  175. case class VariableValue(ident: String) extends Expr
  176. sealed trait Condition
  177. case class Conjunction(conds: List[Condition])extends Condition
  178. case class Alternative(conds: List[Condition])extends Condition
  179. case class Relational(left: Expr, op: String, right: Expr)extends Condition
  180. case class TrivialCondition(value: Boolean) extends Condition
  181. sealed trait Statement
  182. case class Assignment(variable: String, value: Expr) extends Statement
  183. case class Increment(variable: String, value: Long) extends Statement
  184. case class IfStat(cond: Condition, body: List[Statement], body2: List[Statement]) extends Statement
  185. case class WhileStat(cond: Condition, body:List[Statement], body2:List[Statement]) extends Statement
  186. case class PrintStat(expr: Expr) extends Statement
  187. case class Module(name:String, functions:List[Function])
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement