File: parser.sml

package info (click to toggle)
mlton 20210117%2Bdfsg-3
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 58,464 kB
  • sloc: ansic: 27,682; sh: 4,455; asm: 3,569; lisp: 2,879; makefile: 2,347; perl: 1,169; python: 191; pascal: 68; javascript: 7
file content (109 lines) | stat: -rw-r--r-- 3,620 bytes parent folder | download | duplicates (5)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
signature MDL_PARSER_DRIVER =
sig
   structure Ast : MDL_AST

   exception ParseError

   val parse        : string * TextIO.instream -> Ast.decl list
   val parse'       : bool -> string * TextIO.instream -> Ast.decl list
   val parseString  : string -> Ast.decl list
   val parseString' : bool -> string -> Ast.decl list 
   val load         : string -> Ast.decl list
   val load'        : bool -> string -> Ast.decl list

end

functor MDLParserDriver
    (structure AstPP : MDL_AST_PRETTY_PRINTER
     val MDLmode     : bool
     val extraCells  : AstPP.Ast.storagedecl list
    ) : MDL_PARSER_DRIVER =
struct

   val MAX_ERROR = 30

   structure Ast = AstPP.Ast
   structure Error = MDLError
   structure LrVals = MDLParser(structure Token = LrParser.Token
                                structure AstPP = AstPP
                               )
   structure Lex = MDLLexFun(LrVals.Tokens)
   structure Parser = JoinWithArg(structure ParserData = LrVals.ParserData
                                  structure Lex = Lex
                                  structure LrParser = LrParser
                                 )
   open PrecedenceParser


   val defaultPrec = 
       foldr (fn ((id,fixity),S) => declare(S,id,fixity)) empty
        [("+",INFIX 5),
         ("-",INFIX 5),
         ("*",INFIX 6),
         ("div",INFIX 6),
         ("mod",INFIX 6),
         ("=",INFIX 3),
         ("==",INFIX 3),
         (">",INFIX 3),
         ("<",INFIX 3),
         ("<=",INFIX 3),
         (">=",INFIX 3),
         ("<>",INFIX 3),
         ("<<",INFIX 4),
         (">>",INFIX 4),
         ("~>>",INFIX 4),
         ("&&",INFIX 5),
         ("^^",INFIX 5),
         ("^",INFIX 5),
         ("||",INFIX 4),
         (":=",INFIX 2),
         ("andalso",INFIX 1),
         ("orelse",INFIX 0),
         ("::",INFIXR 5),
         ("@",INFIXR 5)
        ]

   exception ParseError

   fun parseIt silent (filename,stream)=
   let val _      = Lex.UserDeclarations.init ()
       val srcMap = SourceMapping.newmap{srcFile=filename}
       val errCount = ref 0
       fun err(a,b,msg) = 
       if silent then raise ParseError 
       else
       let val loc = SourceMapping.location srcMap (a,b)
       in  Error.setLoc loc; 
           Error.error(msg);
           errCount := !errCount + 1;
           if !errCount > MAX_ERROR then raise ParseError else ()
       end
       fun input n = TextIO.inputN(stream,n)
       val lexArg = {srcMap=srcMap, err=err, MDLmode=MDLmode}
       val lexer = Parser.Stream.streamify(Lex.makeLexer input lexArg)
       fun parseError(msg,a,b) = err(a,b,msg)
       fun errPos msg = if silent then raise ParseError else Error.errorPos msg
       fun import (loc,filename) = (Error.setLoc loc; loadIt silent filename)
       val (result,lexer) = 
             Parser.parse(15,lexer,parseError,
               (srcMap,errPos,import,ref defaultPrec,extraCells))
   in  if !Error.errorCount > 0 then raise ParseError else result end

   and loadIt silent filename =
   let val stream = TextIO.openIn filename
   in  parseIt silent (filename,stream) before TextIO.closeIn stream 
          handle e => (TextIO.closeIn stream; raise e)
   end handle IO.Io{function,name,cause,...} => 
       (
        Error.error(function^" failed in \""^name^"\" ("^exnName cause^")");
        raise ParseError)


   fun parse' silent x = (Error.init(); parseIt silent x)
   fun load' silent x = (Error.init(); loadIt silent x)
   fun parseString' silent s = parse' silent ("???",TextIO.openString s)

   val parse       = parse' false
   val load        = load' false
   val parseString = parseString' false
end