Import Upstream version 20180207
[hcoop/debian/mlton.git] / mlyacc / examples / calc / calc.sml
CommitLineData
7f918cf1
CE
1(* calc.sml *)
2
3(* This file provides glue code for building the calculator using the
4 * parser and lexer specified in calc.lex and calc.grm.
5*)
6
7structure Calc : sig
8 val parse : unit -> unit
9 end =
10struct
11
12(*
13 * We apply the functors generated from calc.lex and calc.grm to produce
14 * the CalcParser structure.
15 *)
16
17 structure CalcLrVals =
18 CalcLrValsFun(structure Token = LrParser.Token)
19
20 structure CalcLex =
21 CalcLexFun(structure Tokens = CalcLrVals.Tokens)
22
23 structure CalcParser =
24 Join(structure LrParser = LrParser
25 structure ParserData = CalcLrVals.ParserData
26 structure Lex = CalcLex)
27
28(*
29 * We need a function which given a lexer invokes the parser. The
30 * function invoke does this.
31 *)
32
33 fun invoke lexstream =
34 let fun print_error (s,i:int,_) =
35 TextIO.output(TextIO.stdOut,
36 "Error, line " ^ (Int.toString i) ^ ", " ^ s ^ "\n")
37 in CalcParser.parse(0,lexstream,print_error,())
38 end
39
40(*
41 * Finally, we need a driver function that reads one or more expressions
42 * from the standard input. The function parse, shown below, does
43 * this. It runs the calculator on the standard input and terminates when
44 * an end-of-file is encountered.
45 *)
46
47 fun parse () =
48 let val lexer = CalcParser.makeLexer (fn _ =>
49 (case TextIO.inputLine TextIO.stdIn
50 of SOME s => s
51 | _ => ""))
52 val dummyEOF = CalcLrVals.Tokens.EOF(0,0)
53 val dummySEMI = CalcLrVals.Tokens.SEMI(0,0)
54 fun loop lexer =
55 let val (result,lexer) = invoke lexer
56 val (nextToken,lexer) = CalcParser.Stream.get lexer
57 val _ = case result
58 of SOME r =>
59 TextIO.output(TextIO.stdOut,
60 "result = " ^ (Int.toString r) ^ "\n")
61 | NONE => ()
62 in if CalcParser.sameToken(nextToken,dummyEOF) then ()
63 else loop lexer
64 end
65 in loop lexer
66 end
67
68end (* structure Calc *)