-
Notifications
You must be signed in to change notification settings - Fork 0
/
Parse.sml
62 lines (53 loc) · 1.89 KB
/
Parse.sml
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
structure PlcFrontEnd = struct
(* Create a structure for the PlcParser, by loading the lexer and parser definitions. *)
structure PlcFELrVals = PlcParserLrValsFun(structure Token = LrParser.Token)
structure PlcLexer = PlcLexerFun(structure Tokens = PlcFELrVals.Tokens);
structure PlcParser =
Join(structure LrParser = LrParser
structure ParserData = PlcFELrVals.ParserData
structure Lex = PlcLexer)
(* Start the parsing given a stream of tokens *)
val invoke = fn lexstream =>
let
fun printError (str, pos,_) =
(TextIO.output(TextIO.stdOut, "\n***PLC Parser Error at line " ^ PlcLexer.UserDeclarations.getLineAsString() ^ "***\n"); raise PlcParser.ParseError)
in
PlcParser.parse(0,lexstream, printError,())
end
(* Create a lexer given a function that reads an program input *)
fun newLexer fcn =
let
val lexer = PlcParser.makeLexer fcn
val _ = PlcLexer.UserDeclarations.init()
in
lexer
end
(* Create a lexer from a program input as string. *)
fun stringToLexer str =
let
val done = ref false
in
newLexer(fn n => if (!done) then "" else (done := true;str))
end
(* Create a lexer reading a program from a file. *)
fun fileToLexer filename =
let
val inStream = TextIO.openIn(filename)
in
newLexer(fn n => TextIO.inputAll(inStream))
end
(*Creates a parser from a lexer. *)
fun lexerToParser(lexer) : expr =
let
val dummyEOF = PlcFELrVals.Tokens.EOF(0,0)
val (result,lexer) = invoke lexer
val (nextToken, lexer) = PlcParser.Stream.get lexer
in
if PlcParser.sameToken(nextToken, dummyEOF) then
result
else
(TextIO.output(TextIO.stdOut, "*** PLC PARSER WARNING -- unconsumed input ***\n"); result)
end
val fromString = lexerToParser o stringToLexer
val fromFile = lexerToParser o fileToLexer
end