|
|
1.1 ! root 1: (* a simple parser. (R. Burstall) ! 2: The grammar is: ! 3: ! 4: var = x | y | z ! 5: const = 0 | 1 | 2 ! 6: aexpr = var | const | (expr) ! 7: expr = aexpr + expr | aexpr * expr | aexpr ! 8: stmt = var := expr ! 9: | if expr then stmt ! 10: | while expr do stmt ! 11: | begin stmts end ! 12: stmts = stmt ; stmts | stmt ! 13: decl = var : integer | var : boolean ! 14: decls = decl ; decls | decl ! 15: prog = var decls begin stmts end . ! 16: ! 17: If S is a set of string lists we say that a function f: string list -> string list ! 18: recognizes S if ! 19: ! 20: (1) if l does not begin with a list in S then f l fails ! 21: (2) if s is the longest list in S such that l = s@m for some list m, then ! 22: f l = m ! 23: ! 24: Each phrase name in the grammar above denotes a set of string lists. We write ML ! 25: functions called var, const, aexpr, ..., to recognized each of these phrases ! 26: (i.e. to recognize the associated set of string lists). ! 27: ! 28: If f1 recognizes P1 and f2 recognizes P2 then we can define a function g to ! 29: recognize P1 P2 by ! 30: ! 31: g = f1 & f2 where f & g = (fn s => g(f s)) ! 32: ! 33: We can define a function h to recognize P1 | P2 by ! 34: ! 35: h = f = f1 ||| f2 where f ||| g = (fn s => f1 s handle Fail => f2 s) ! 36: *) ! 37: ! 38: exception Fail ! 39: ! 40: infix 3 & ! 41: infix 2 ||| ! 42: ! 43: fun f1 & f2 = (fn s => f2(f1 s)) ! 44: fun f1 ||| f2 = (fn s => f1 s handle Fail => f2 s) ! 45: ! 46: fun quote (t: string) ([]: string list) = raise Fail ! 47: | quote t (t' :: rest) = if t = t' then rest else raise Fail ! 48: ! 49: val var = quote "x" ||| quote "y" ||| quote "z" ! 50: ! 51: val const = quote "0" ||| quote "1" ||| quote "2" ! 52: ! 53: fun aexpr s = (var ||| const ||| quote "(" & expr & quote ")") s ! 54: ! 55: and expr s = (aexpr & quote "+" & expr ||| ! 56: aexpr & quote "*" & expr ||| ! 57: aexpr) s ! 58: ! 59: and stmt s = (var & quote ":=" & expr ||| ! 60: quote "if" & expr & quote "then" & stmt ||| ! 61: quote "while" & expr & quote "do" & stmt ||| ! 62: quote "begin" & stmts & quote "end") s ! 63: ! 64: and stmts s = (stmt & quote ";" & stmts ||| stmt) s ! 65: ! 66: and decl s = (var & quote ":" & quote "integer" ||| ! 67: var & quote ":" & quote "boolean") s ! 68: ! 69: and decls s = (decl & quote ";" & decls ||| decl) s ! 70: ! 71: and prog s = (quote "var" & decls & quote "begin" & stmts & quote "end" & ! 72: quote ".") s ! 73: ! 74: fun parse s = (if prog s = [] then "YES" else "NO") handle Fail => "NO" ! 75: ! 76: (* examples *) ! 77: ! 78: expr ["x","+","1", "end", "."]; ! 79: ! 80: parse ["var","x",":","integer",";","y",":","boolean", ! 81: "begin","x",":=","0","end","."];
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.