forked from mozart/mozart2-compiler
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathParseOz.oz
152 lines (146 loc) · 5.06 KB
/
ParseOz.oz
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
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
%%%
%%% Author:
%%% Leif Kornstaedt <[email protected]>
%%%
%%% Copyright:
%%% Leif Kornstaedt, 1997
%%%
%%% Last change:
%%% $Date$ by $Author$
%%% $Revision$
%%%
%%% This file is part of Mozart, an implementation of Oz 3:
%%% http://www.mozart-oz.org
%%%
%%% See the file "LICENSE" or
%%% http://www.mozart-oz.org/LICENSE.html
%%% for information on usage and redistribution
%%% of this file, and for a DISCLAIMER OF ALL
%%% WARRANTIES.
%%%
local
ParseFile = Parser.'file'
ParseVirtualString = Parser.'virtualString'
local
Prefixes = ["`T_SWITCHNAME'"#"switch name"
"`T_OZATOM'"#"atom"
"`T_ATOM_LABEL'"#"atom label"
"`T_OZFLOAT'"#"float"
"`T_OZINT'"#"integer"
"`T_STRING'"#"string"
"`T_AMPER'"#"`&'"
"`T_VARIABLE'"#"variable"
"`T_VARIABLE_LABEL'"#"variable label"
"`T_DEFAULT'"#"`<='"
"`T_CHOICE'"#"`[]'"
"`T_LDOTS'"#"`...'"
"`T_OOASSIGN'"#"`<-'"
"`T_COMPARE'"#"comparison operator"
"`T_FDCOMPARE'"#"finite domain comparison operator"
"`T_FDIN'"#"finite domain inclusion operator"
"`T_ADD'"#"`+' or `-'"
"`T_FDMUL'"#"`*' or `/'"
"`T_OTHERMUL'"#"`div' or `mod'"
"`T_FALSE_LABEL'"#"`false' as label"
"`T_TRUE_LABEL'"#"`true' as label"
"`T_UNIT_LABEL'"#"`unit' as label"
"`T_DOTINT'"#"`.' followed by an integer"
"`T_DEREFF'"#"`!!'"
"`T_ENDOFFILE'"#"end-of-file"
"`T_REGEX'"#"regular expression"
"`T_REDUCE'"#"`=>'"
"`T_SEP'"#"`//'"]
fun {DetachPrefix P S}
case P of C|Cr then
case S of !C|Sr then {DetachPrefix Cr Sr}
else false
end
[] nil then
S
end
end
fun {BeautifyPrefix Ps S}
case Ps of X|Pr then P#R = X in
case {DetachPrefix P S} of false then {BeautifyPrefix Pr S}
elseof Rest then {Append R {Beautify Rest}}
end
[] nil then {Raise noBeautification} unit
end
end
fun {Beautify S}
case S of nil then ""
[] C|Cr then
case C of &` then
try
{BeautifyPrefix Prefixes S}
catch noBeautification then
case Cr of &T|&_|Crr then KW Rest in % e.g., "`T_case'"
{List.takeDropWhile Crr fun {$ C} C \= &' end ?KW ?Rest}
case Rest of &'|NewRest then
&`|{Append KW &'|{Beautify NewRest}}
end
elseof &'|Crr then Op Rest in % e.g., "`'+''"
{List.takeDropWhile Crr fun {$ C} C \= &' end ?Op ?Rest}
case Rest of &'|&'|NewRest then
&`|{Append Op &'|{Beautify NewRest}}
else
C|{Beautify Cr}
end
else S
end
end
else C|{Beautify Cr}
end
end
end
in
proc {Output Messages Reporter ShowInsert}
{ForAll {Reverse Messages}
proc {$ M}
case {Label M} of error then
case {CondSelect M kind unit} of 'parse error' then
{Reporter {AdjoinAt M msg {Beautify {Atom.toString M.msg}}}}
else
{Reporter M}
end
[] warn then
{Reporter M}
[] logInsert then FileName Coord in
FileName = M.1
Coord = {CondSelect M 2 unit}
{Reporter tell(insert(FileName Coord))}
if ShowInsert then
{Reporter tell(info('%%% inserted file "'#
FileName#'"\n' Coord))}
end
end
end}
end
end
in
fun {ParseOzFile FileName Reporter GetSwitch Defines}
Res#Messages = {ParseFile FileName
options(gump: {GetSwitch gump}
allowdeprecated: {GetSwitch allowdeprecated}
defines: Defines)}
in
{Output Messages Reporter {GetSwitch showinsert}}
case Res of fileNotFound then
{Reporter error(kind: 'compiler directive error'
msg: ('could not open file "'#FileName#
'" for reading'))}
parseError
else
Res
end
end
fun {ParseOzVirtualString VS Reporter GetSwitch Defines}
Res#Messages = {ParseVirtualString VS
options(gump: {GetSwitch gump}
allowdeprecated: {GetSwitch allowdeprecated}
defines: Defines)}
in
{Output Messages Reporter {GetSwitch showinsert}}
Res
end
end