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
|