| author | Christian Urban <christian dot urban at kcl dot ac dot uk> | 
| Tue, 21 Jul 2020 00:12:34 +0100 | |
| changeset 737 | 826c2bec403b | 
| parent 93 | 4794759139ea | 
| permissions | -rw-r--r-- | 
| 64 
2d625418c011
added everything
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: diff
changeset | 1 | //:load matcher.scala | 
| 
2d625418c011
added everything
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: diff
changeset | 2 | //:load parser3.scala | 
| 
2d625418c011
added everything
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: diff
changeset | 3 | |
| 
2d625418c011
added everything
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: diff
changeset | 4 | // some regular expressions | 
| 
2d625418c011
added everything
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: diff
changeset | 5 | val LETTER = RANGE("abcdefghijklmnopqrstuvwxyz")
 | 
| 
2d625418c011
added everything
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: diff
changeset | 6 | val ID = PLUS(LETTER) | 
| 
2d625418c011
added everything
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: diff
changeset | 7 | |
| 
2d625418c011
added everything
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: diff
changeset | 8 | val DIGIT = RANGE("0123456789")
 | 
| 
2d625418c011
added everything
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: diff
changeset | 9 | val NONZERODIGIT = RANGE("123456789")
 | 
| 
2d625418c011
added everything
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: diff
changeset | 10 | val NUMBER = ALT(SEQ(NONZERODIGIT, STAR(DIGIT)), "0") | 
| 
2d625418c011
added everything
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: diff
changeset | 11 | |
| 
2d625418c011
added everything
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: diff
changeset | 12 | val LPAREN = CHAR('(')
 | 
| 
2d625418c011
added everything
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: diff
changeset | 13 | val RPAREN = CHAR(')')
 | 
| 
2d625418c011
added everything
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: diff
changeset | 14 | |
| 
2d625418c011
added everything
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: diff
changeset | 15 | val WHITESPACE = PLUS(RANGE(" \n"))
 | 
| 
2d625418c011
added everything
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: diff
changeset | 16 | val OPS = RANGE("+-*")
 | 
| 
2d625418c011
added everything
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: diff
changeset | 17 | |
| 
2d625418c011
added everything
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: diff
changeset | 18 | // for classifying the strings that have been lexed | 
| 
2d625418c011
added everything
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: diff
changeset | 19 | abstract class Token | 
| 
2d625418c011
added everything
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: diff
changeset | 20 | |
| 
2d625418c011
added everything
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: diff
changeset | 21 | case object T_WHITESPACE extends Token | 
| 
2d625418c011
added everything
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: diff
changeset | 22 | case class T_NUM(s: String) extends Token | 
| 
2d625418c011
added everything
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: diff
changeset | 23 | case class T_OP(s: String) extends Token | 
| 
2d625418c011
added everything
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: diff
changeset | 24 | case object T_LPAREN extends Token | 
| 
2d625418c011
added everything
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: diff
changeset | 25 | case object T_RPAREN extends Token | 
| 
2d625418c011
added everything
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: diff
changeset | 26 | |
| 
2d625418c011
added everything
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: diff
changeset | 27 | |
| 
2d625418c011
added everything
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: diff
changeset | 28 | // lexing rules for arithmetic expressions | 
| 
2d625418c011
added everything
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: diff
changeset | 29 | val lexing_rules: List[Rule[Token]]= | 
| 
2d625418c011
added everything
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: diff
changeset | 30 | List((NUMBER, (s) => T_NUM(s.mkString)), | 
| 
2d625418c011
added everything
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: diff
changeset | 31 | (WHITESPACE, (s) => T_WHITESPACE), | 
| 
2d625418c011
added everything
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: diff
changeset | 32 | (LPAREN, (s) => T_LPAREN), | 
| 
2d625418c011
added everything
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: diff
changeset | 33 | (RPAREN, (s) => T_RPAREN), | 
| 
2d625418c011
added everything
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: diff
changeset | 34 | (OPS, (s) => T_OP(s.mkString))) | 
| 
2d625418c011
added everything
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: diff
changeset | 35 | |
| 
2d625418c011
added everything
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: diff
changeset | 36 | val Tk = Tokenizer(lexing_rules, List(T_WHITESPACE)) | 
| 
2d625418c011
added everything
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: diff
changeset | 37 | |
| 
2d625418c011
added everything
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: diff
changeset | 38 | |
| 
2d625418c011
added everything
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: diff
changeset | 39 | case class TokParser(tok: Token) extends Parser[List[Token], Token] {
 | 
| 
2d625418c011
added everything
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: diff
changeset | 40 |   def parse(ts: List[Token]) = ts match {
 | 
| 
2d625418c011
added everything
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: diff
changeset | 41 | case t::ts if (t == tok) => Set((t, ts)) | 
| 
2d625418c011
added everything
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: diff
changeset | 42 | case _ => Set () | 
| 
2d625418c011
added everything
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: diff
changeset | 43 | } | 
| 
2d625418c011
added everything
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: diff
changeset | 44 | } | 
| 
2d625418c011
added everything
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: diff
changeset | 45 | implicit def token2tparser(t: Token) = TokParser(t) | 
| 
2d625418c011
added everything
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: diff
changeset | 46 | |
| 
2d625418c011
added everything
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: diff
changeset | 47 | case object NumParser extends Parser[List[Token], Int] {
 | 
| 
2d625418c011
added everything
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: diff
changeset | 48 |   def parse(ts: List[Token]) = ts match {
 | 
| 
2d625418c011
added everything
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: diff
changeset | 49 | case T_NUM(s)::ts => Set((s.toInt, ts)) | 
| 
2d625418c011
added everything
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: diff
changeset | 50 | case _ => Set () | 
| 
2d625418c011
added everything
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: diff
changeset | 51 | } | 
| 
2d625418c011
added everything
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: diff
changeset | 52 | } | 
| 
2d625418c011
added everything
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: diff
changeset | 53 | |
| 
2d625418c011
added everything
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: diff
changeset | 54 | lazy val E: Parser[List[Token], Int] = (T ~ T_OP("+") ~ E) ==> { case ((x, y), z) => x + z } || T  
 | 
| 
2d625418c011
added everything
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: diff
changeset | 55 | lazy val T: Parser[List[Token], Int] = (F ~ T_OP("*") ~ T) ==> { case ((x, y), z) => x * z } || F
 | 
| 
2d625418c011
added everything
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: diff
changeset | 56 | lazy val F: Parser[List[Token], Int] = (T_LPAREN ~> E <~ T_RPAREN) || NumParser | 
| 
2d625418c011
added everything
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: diff
changeset | 57 | |
| 
2d625418c011
added everything
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: diff
changeset | 58 | println(E.parse_all(Tk.fromString("1 + 2 + 3")))
 | 
| 
2d625418c011
added everything
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: diff
changeset | 59 | println(E.parse_all(Tk.fromString("1 + 2 * 3")))
 | 
| 
2d625418c011
added everything
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: diff
changeset | 60 | println(E.parse_all(Tk.fromString("(1 + 2) * 3")))
 | 
| 
2d625418c011
added everything
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: diff
changeset | 61 | println(E.parse_all(Tk.fromString("(14 + 2) * (3 + 2)")))
 | 
| 
2d625418c011
added everything
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: diff
changeset | 62 |