Commit | Line | Data |
---|---|---|
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 | ||
6 | functor 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 | |
108 | end; | |
109 | ||
110 | structure Header = HeaderFun(); |