Import Upstream version 20180207
[hcoop/debian/mlton.git] / mlyacc / src / hdr.sml
CommitLineData
7f918cf1
CE
1(* Modified by Vesa Karvonen on 2007-12-18.
2 * Create line directives in output.
3 *)
4(* ML-Yacc Parser Generator (c) 1989 Andrew W. Appel, David R. Tarditi *)
5
6functor HeaderFun () : HEADER =
7 struct
8 val DEBUG = true
9
10 type pos = {line : int, col : int}
11 val pos = {line = ref 1, start = ref 0}
12 val text = ref (nil: string list)
13 type inputSource = {name : string,
14 errStream : TextIO.outstream,
15 inStream : TextIO.instream,
16 errorOccurred : bool ref}
17
18 val newSource =
19 fn (s : string,i : TextIO.instream ,errs : TextIO.outstream) =>
20 {name=s,errStream=errs,inStream=i,
21 errorOccurred = ref false}
22
23 val errorOccurred = fn (s : inputSource) =>fn () => !(#errorOccurred s)
24
25 val pr = fn out : TextIO.outstream => fn s : string => TextIO.output(out,s)
26
27 val error = fn {name,errStream, errorOccurred,...} : inputSource =>
28 let val pr = pr errStream
29 in fn l : pos => fn msg : string =>
30 (pr name; pr ", line "; pr (Int.toString (#line l)); pr ": Error: ";
31 pr msg; pr "\n"; errorOccurred := true)
32 end
33
34 val warn = fn {name,errStream, errorOccurred,...} : inputSource =>
35 let val pr = pr errStream
36 in fn l : pos => fn msg : string =>
37 (pr name; pr ", line "; pr (Int.toString (#line l)); pr ": Warning: ";
38 pr msg; pr "\n")
39 end
40
41 datatype prec = LEFT | RIGHT | NONASSOC
42
43 datatype symbol = SYMBOL of string * pos
44 val symbolName = fn SYMBOL(s,_) => s
45 val symbolPos = fn SYMBOL(_,p) => p
46 val symbolMake = fn sp => SYMBOL sp
47
48 type ty = string
49 val tyName = fn i => i
50 val tyMake = fn i => i
51
52 datatype control = NODEFAULT | VERBOSE | PARSER_NAME of symbol |
53 FUNCTOR of string | START_SYM of symbol |
54 NSHIFT of symbol list | POS of string | PURE |
55 PARSE_ARG of string * string |
56 TOKEN_SIG_INFO of string
57
58 datatype declData = DECL of
59 {eop : symbol list,
60 keyword : symbol list,
61 nonterm : (symbol*ty option) list option,
62 prec : (prec * (symbol list)) list,
63 change: (symbol list * symbol list) list,
64 term : (symbol* ty option) list option,
65 control : control list,
66 value : (symbol * string) list}
67
68 type rhsData = {rhs:symbol list,code:string, prec:symbol option} list
69 datatype rule = RULE of {lhs : symbol, rhs : symbol list,
70 code : {text : string, pos : pos},
71 prec : symbol option}
72
73 type parseResult = string * declData * rule list
74 val getResult = fn p => p
75
76 fun join_decls
77 (DECL {eop=e,control=c,keyword=k,nonterm=n,prec,
78 change=su,term=t,value=v}:declData,
79 DECL {eop=e',control=c',keyword=k',nonterm=n',prec=prec',
80 change=su',term=t',value=v'} : declData,
81 inputSource,pos) =
82 let val ignore = fn s =>
83 (warn inputSource pos ("ignoring duplicate " ^ s ^
84 " declaration"))
85 val join = fn (e,NONE,NONE) => NONE
86 | (e,NONE,a) => a
87 | (e,a,NONE) => a
88 | (e,a,b) => (ignore e; a)
89 fun mergeControl (nil,a) = [a]
90 | mergeControl (l as h::t,a) =
91 case (h,a)
92 of (PARSER_NAME _,PARSER_NAME n1) => (ignore "%name"; l)
93 | (FUNCTOR _,FUNCTOR _) => (ignore "%header"; l)
94 | (PARSE_ARG _,PARSE_ARG _) => (ignore "%arg"; l)
95 | (START_SYM _,START_SYM s) => (ignore "%start"; l)
96 | (POS _,POS _) => (ignore "%pos"; l)
97 | (TOKEN_SIG_INFO _, TOKEN_SIG_INFO _)
98 => (ignore "%token_sig_info"; l)
99 | (NSHIFT a,NSHIFT b) => (NSHIFT (a@b)::t)
100 | _ => h :: mergeControl(t,a)
101 fun loop (nil,r) = r
102 | loop (h::t,r) = loop(t,mergeControl(r,h))
103 in DECL {eop=e@e',control=loop(c',c),keyword=k'@k,
104 nonterm=join("%nonterm",n,n'), prec=prec@prec',
105 change=su@su', term=join("%term",t,t'),value=v@v'} :
106 declData
107 end
108end;
109
110structure Header = HeaderFun();