git @ Cat's Eye Technologies Sbeezg / 5c5b421
Initial import of Sbeezg version 1.0 revision 2002.0317 sources. Cat's Eye Technologies 12 years ago
9 changed file(s) with 708 addition(s) and 0 deletion(s). Raw diff Collapse all Expand all
0 The Sbeezg Programming Language v2002.0317
1 -------------------------------
2
3 Sbeezg is single-assignment programming taken to the extreme. Each variable
4 may only be assigned once. There is no scope. When a function is executed,
5 a new copy of it is made, with all bound variable names altered to fresh ones,
6 and this is executed instead. Execution is sequential in nature. Arguments
7 and return value are given explicitly. There are no global names; there are
8 only lambda function definitions available. There are five built-in operations.
9 For convenience, there are three data types: atoms, integers, and closures.
10
11 Here is a brief EBNF rundown of the syntax:
12
13 Appl ::= Name "=" Val "(" Val {"," Val} ")".
14 Val ::= Name | "*" Const | "{" Name {"," Name} "|" Appl {";" Appl} "|" Name "}".
15
16 A program is an application, which consists of an assignment to a new (never
17 before named in the program) variable, of a value or the result of a function
18 call. Note that the arguments of a function call may only be simple values;
19 further nested function calls are disallowed as their implicit 'piping' of
20 values from one function to the next without an intervening variable name is
21 counter to the intention of this purely single-assignment language.
22
23 This documentation isn't really complete.
24
25 Chris Pressey
26 March 17 2002
27 Winnipeg, Manitoba
0 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
1 <html>
2 <head>
3 <title>Module sbeezg</title>
4 </head>
5 <body bgcolor="white">
6 <h1>Module sbeezg</h1>
7 <ul><li>
8 <a href="#index">Function index</a></li><li>
9 <a href="#exported">Exported functions</a></li></ul>
10
11 <h2>Description</h2>
12
13
14 <h2><a name="index">Function Index</a></h2>
15
16 <table width="100%" border="1"><tr><th colspan="2" align="left">Exported Functions</th></tr>
17 <tr><td><a href="#run-1">run/1</a></td><td/></tr>
18 <tr><td><a href="#test-1">test/1</a></td><td/></tr>
19 </table>
20
21 <h2><a name="exported">Exported Functions</a></h2>
22
23 <h3><a name="run-1">run/1</a></h3>
24
25 <p><code>run(Arg1) -> term()</code></p>
26 <p> </p>
27
28 <h3><a name="test-1">test/1</a></h3>
29
30 <p><code>test(Arg1) -> term()</code></p>
31 <p> </p></body>
32 </html>
0 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
1 <html>
2 <head>
3 <title>Module sbeezg_parser</title>
4 </head>
5 <body bgcolor="white">
6 <h1>Module sbeezg_parser</h1>
7 <ul><li>
8 <a href="#index">Function index</a></li><li>
9 <a href="#exported">Exported functions</a></li></ul>
10
11 <h2>Description</h2>
12
13
14 <h2><a name="index">Function Index</a></h2>
15
16 <table width="100%" border="1"><tr><th colspan="2" align="left">Exported Functions</th></tr>
17 <tr><td><a href="#format_error-1">format_error/1</a></td><td/></tr>
18 <tr><td><a href="#parse-1">parse/1</a></td><td/></tr>
19 <tr><td><a href="#parse_and_scan-1">parse_and_scan/1</a></td><td/></tr>
20 </table>
21
22 <h2><a name="exported">Exported Functions</a></h2>
23
24 <h3><a name="format_error-1">format_error/1</a></h3>
25
26 <p><code>format_error(Arg1) -> term()</code></p>
27 <p> </p>
28
29 <h3><a name="parse-1">parse/1</a></h3>
30
31 <p><code>parse(Arg1) -> term()</code></p>
32 <p> </p>
33
34 <h3><a name="parse_and_scan-1">parse_and_scan/1</a></h3>
35
36 <p><code>parse_and_scan(Arg1) -> term()</code></p>
37 <p> </p></body>
38 </html>
0 {application,sbeezg,
1 [{description,"The Sbeezg Programming Language"},
2 {vsn,"2002.0317"},
3 {modules,[sbeezg, sbeezg_parser]},
4 {registered,[]},
5 {env,[]},
6 {applications,[kernel,stdlib]}]}.
7
Binary diff not shown
Binary diff not shown
0 -module(sbeezg).
1 -vsn('2002.0317').
2 -author('cpressey@catseye.mb.ca').
3 -copyright('Copyright (c)2002 Cat`s Eye Technologies. All rights reserved.').
4
5 %%% Redistribution and use in source and binary forms, with or without
6 %%% modification, are permitted provided that the following conditions
7 %%% are met:
8 %%%
9 %%% Redistributions of source code must retain the above copyright
10 %%% notice, this list of conditions and the following disclaimer.
11 %%%
12 %%% Redistributions in binary form must reproduce the above copyright
13 %%% notice, this list of conditions and the following disclaimer in
14 %%% the documentation and/or other materials provided with the
15 %%% distribution.
16 %%%
17 %%% Neither the name of Cat's Eye Technologies nor the names of its
18 %%% contributors may be used to endorse or promote products derived
19 %%% from this software without specific prior written permission.
20 %%%
21 %%% THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
22 %%% CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
23 %%% INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
24 %%% MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
25 %%% DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
26 %%% LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
27 %%% OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
28 %%% PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
29 %%% OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
30 %%% ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
31 %%% OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32 %%% OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
33 %%% POSSIBILITY OF SUCH DAMAGE.
34
35 -export([run/1, test/1]).
36
37 %%% BEGIN sbeezg.erl %%%
38
39 %%% A simple interpreter for the Sbeezg Programming Language.
40
41 %% Interpreter ---------------------------------------------------------
42 %% Call sbeezg:run("sbeezg-program") to interpret a Sbeezg program.
43 %% Empties the process dictionary as a side effect.
44
45 run(String) when list(String) ->
46 {ok, Toks, N} = erl_scan:string(String),
47 % io:fwrite("scan: ~s -> ~w~n", [String, Toks]),
48 erase(), % clear process dictionary for parser
49 case sbeezg_parser:parse(Toks ++ [{'$end',999}]) of
50 {ok, Prog} ->
51 % io:fwrite("parse: ~s -> ~w~n", [String, Prog]),
52 erase(), % destroy the garbage left in the process dictionary
53 run(Prog);
54 {error, {Line, Module, Message}}=Q ->
55 io:fwrite("Error: ~s~n", [Message]),
56 Q
57 end;
58 run({assign, L, F, A}=C) ->
59 % io:fwrite("~w~n", [C]),
60 L0 = get_name(L),
61 F0 = run(F),
62 A0 = run(A),
63 assign(L0, '$placeholder'),
64 R0 = execute(F0, A0),
65 assign(L0, R0);
66 run({assign, L, R}=C) ->
67 % io:fwrite("~w~n", [C]),
68 L0 = get_name(L),
69 R0 = run(R),
70 assign(L0, R0);
71 run({vlist, H, T}=C) ->
72 % io:fwrite("~w~n", [C]),
73 H0 = run(H),
74 T0 = run(T),
75 [H0 | T0];
76 run({lambda, N, A, R}=C) ->
77 % io:fwrite("~w~n", [C]),
78 {func, N, A, R};
79 run({alist, H, T}=C) ->
80 % io:fwrite("~w~n", [C]),
81 H0 = run(H),
82 T0 = run(T),
83 case T0 of
84 [] -> H0;
85 _ -> T0
86 end;
87 run({lit,{atom,Line,Atom}}) -> Atom;
88 run({lit,{integer,Line,Int}}) -> Int;
89 run({name, {atom,Line,Atom}}) ->
90 case get(Atom) of
91 undefined ->
92 io:fwrite("~w undefined!~n", [Atom]),
93 Atom;
94 N ->
95 N
96 end;
97 run(nil) ->
98 [];
99 run(Q) ->
100 io:fwrite("UNKNOWN ~w~n", [Q]),
101 unknown.
102
103 get_name({nlist, H, T}=C) ->
104 % io:fwrite("~w~n", [C]),
105 H0 = get_name(H),
106 T0 = get_name(T),
107 [H0 | T0];
108 get_name({name, {atom,Line,Atom}}) -> Atom;
109 get_name(nil) -> [].
110
111 %% Utility -------------------------------------------------------------
112
113 assign(Name, Value) ->
114 % io:fwrite("Assigning ~w to ~w~n", [Value, Name]),
115 case get(Name) of
116 NonExist when NonExist == undefined; NonExist == '$placeholder' ->
117 put(Name, Value);
118 Exist ->
119 io:fwrite("ERROR: Multiple Assignment to ~w=~w (~w)~n",
120 [Name, Exist, Value])
121 end,
122 Value.
123
124 execute(print, [H | T]) ->
125 io:fwrite("~w", [H]),
126 execute(print, T);
127 execute(print, []) -> ok;
128 execute(is, [A, B, T, F]) ->
129 % io:fwrite("~w", [C]),
130 case A of
131 B -> T;
132 _ -> F
133 end;
134 execute(pred, [X]) ->
135 % io:fwrite("pred ~w~n", [X]),
136 X - 1;
137 execute(succ, [X]) -> X + 1;
138 execute(Func, Args) when atom(Func) ->
139 io:fwrite("Unknown built-in '~w(~w)'~n", [Func, Args]),
140 unknown;
141 execute({func, P, B, R}, A) ->
142 P0 = fresh(P),
143 B0 = fresh(B),
144 P1 = get_name(P0),
145 bind(P1, A),
146 run(B0),
147 run(R).
148
149 fresh({assign, L, F, A}=C) -> {assign, fresh(L), fresh(F), fresh(A)};
150 fresh({assign, L, R}=C) -> {assign, fresh(L), fresh(R)};
151 fresh({vlist, H, T}=C) -> {vlist, fresh(H), fresh(T)};
152 fresh({lambda, X, A}=C) -> {lambda, fresh(X), fresh(A)};
153 fresh({nlist, H, T}=C) -> {nlist, fresh(H), fresh(T)};
154 fresh({alist, H, T}=C) -> {alist, fresh(H), fresh(T)};
155 fresh({lit,X}=C) -> C;
156 fresh({name,{atom,Line,Atom}}=C) ->
157 case get(Atom) of
158 undefined -> C;
159 _ ->
160 fresh({name, {atom, Line, list_to_atom([$_ | atom_to_list(Atom)])}})
161 end;
162 fresh(X) -> X.
163
164 bind([],[]) -> ok;
165 bind([HN|TN],[HV|TV]) ->
166 % io:fwrite("bind ~w to ~w~n", [HV,HN]),
167 assign(HN,HV),
168 bind(TN,TV).
169
170 %% User interface ------------------------------------------------------
171
172 test([N]) -> test(list_to_integer(N));
173 test(N) ->
174 R = run(prg(N)),
175 E = erase(),
176 {R, E}.
177
178 prg(1) -> "a={b|p=*print;c=p(b)|b};d=a(*foo);e=a(*bar);f=a(*baz)";
179 prg(2) -> "a={b|p=*print;c=p(b)|b};d={e,f|g=e(f)|g};h=d(a,*hello)";
180 prg(3) -> "p=*print;i=*is;r=i(*a,*b,*troo,*fall);q=p(r)";
181 prg(4) -> "f={a,b|p=*print;g=p(a);k=b(a,b)|a};l=f(*hello,f)";
182 prg(5) -> "f={a,b|i=*is;s=*pred;p=*print;g=p(*beer);h=s(a);"
183 "ln={x,m|z=x|x};lg={y,n|q=n(y,n)|y};j=i(h,0,ln,lg);"
184 "k=j(h,b)|a};l=f(99,f)";
185 prg(6) -> "f=*a;f=*b"; % intentionally erroneous
186 prg(_) -> unknown.
187
188 %%% END of sbeezg.erl %%%
0 -module(sbeezg_parser).
1 -define(THIS_MODULE, sbeezg_parser).
2 -export([parse/1, parse_and_scan/1, format_error/1]).
3
4 new_name({name,{atom,Line,Name}}=A) ->
5 case get(A) of
6 defn ->
7 return_error(0, io_lib:format("Name '~w' already defined", [Name]));
8 _ ->
9 put(A, defn)
10 end.
11
12 existing_name({name,{atom,Line,Name}}=A) ->
13 case get(A) of
14 undefined ->
15 return_error(0, io_lib:format("Name '~w' is not yet defined", [Name]));
16 _ ->
17 ok
18 end.
19
20 %%% END of sbeezg_parser.yrl %%%
21
22 %% ``The contents of this file are subject to the Erlang Public License,
23 %% Version 1.1, (the "License"); you may not use this file except in
24 %% compliance with the License. You should have received a copy of the
25 %% Erlang Public License along with this software. If not, it can be
26 %% retrieved via the world wide web at http://www.erlang.org/.
27 %%
28 %% Software distributed under the License is distributed on an "AS IS"
29 %% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
30 %% the License for the specific language governing rights and limitations
31 %% under the License.
32 %%
33 %% The Initial Developer of the Original Code is Ericsson Utvecklings AB.
34 %% Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
35 %% AB. All Rights Reserved.''
36 %%
37 %% $Id$
38 %%
39
40 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
41 % The parser generator will insert appropriate declarations before this line.%
42
43 parse(Tokens) ->
44 case catch yeccpars1(Tokens, false, 0, [], []) of
45 error ->
46 Errorline =
47 if Tokens == [] -> 0; true -> element(2, hd(Tokens)) end,
48 {error,
49 {Errorline, ?THIS_MODULE, "syntax error at or after this line."}};
50 Other ->
51 Other
52 end.
53
54 parse_and_scan({Mod, Fun, Args}) ->
55 case apply(Mod, Fun, Args) of
56 {eof, _} ->
57 {ok, eof};
58 {error, Descriptor, _} ->
59 {error, Descriptor};
60 {ok, Tokens, _} ->
61 yeccpars1(Tokens, {Mod, Fun, Args}, 0, [], [])
62 end.
63
64 format_error(Message) ->
65 case io_lib:deep_char_list(Message) of
66 true ->
67 Message;
68 _ ->
69 io_lib:write(Message)
70 end.
71
72 % To be used in grammar files to throw an error message to the parser toplevel.
73 % Doesn't have to be exported!
74 return_error(Line, Message) ->
75 throw({error, {Line, ?THIS_MODULE, Message}}).
76
77
78 % Don't change yeccpars1/6 too much, it is called recursively by yeccpars2/8!
79 yeccpars1([Token | Tokens], Tokenizer, State, States, Vstack) ->
80 yeccpars2(State, element(1, Token), States, Vstack, Token, Tokens,
81 Tokenizer);
82 yeccpars1([], {M, F, A}, State, States, Vstack) ->
83 case catch apply(M, F, A) of
84 {eof, Endline} ->
85 {error, {Endline, ?THIS_MODULE, "end_of_file"}};
86 {error, Descriptor, Endline} ->
87 {error, Descriptor};
88 {'EXIT', Reason} ->
89 {error, {0, ?THIS_MODULE, Reason}};
90 {ok, Tokens, Endline} ->
91 case catch yeccpars1(Tokens, {M, F, A}, State, States, Vstack) of
92 error ->
93 Errorline = element(2, hd(Tokens)),
94 {error, {Errorline, ?THIS_MODULE,
95 "syntax error at or after this line."}};
96 Other ->
97 Other
98 end
99 end;
100 yeccpars1([], false, State, States, Vstack) ->
101 yeccpars2(State, '$end', States, Vstack, {'$end', 999999}, [], false).
102
103 % For internal use only.
104 yeccerror(Token) ->
105 {error,
106 {element(2, Token), ?THIS_MODULE,
107 ["syntax error before: ", yecctoken2string(Token)]}}.
108
109 yecctoken2string({atom, _, A}) -> io_lib:write(A);
110 yecctoken2string({integer,_,N}) -> io_lib:write(N);
111 yecctoken2string({float,_,F}) -> io_lib:write(F);
112 yecctoken2string({char,_,C}) -> io_lib:write_char(C);
113 yecctoken2string({var,_,V}) -> io_lib:format('~s', [V]);
114 yecctoken2string({string,_,S}) -> io_lib:write_string(S);
115 yecctoken2string({reserved_symbol, _, A}) -> io_lib:format('~w', [A]);
116 yecctoken2string({Cat, _, Val}) -> io_lib:format('~w', [Val]);
117
118 yecctoken2string({'dot', _}) -> io_lib:format('~w', ['.']);
119 yecctoken2string({'$end', _}) ->
120 [];
121 yecctoken2string({Other, _}) when atom(Other) ->
122 io_lib:format('~w', [Other]);
123 yecctoken2string(Other) ->
124 io_lib:write(Other).
125
126 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
127
128
129 yeccpars2(0, atom, __Ss, __Stack, __T, __Ts, __Tzr) ->
130 yeccpars1(__Ts, __Tzr, 3, [0 | __Ss], [__T | __Stack]);
131 yeccpars2(0, _, _, _, __T, _, _) ->
132 yeccerror(__T);
133 yeccpars2(1, '$end', _, __Stack, _, _, _) ->
134 {ok, hd(__Stack)};
135 yeccpars2(1, _, _, _, __T, _, _) ->
136 yeccerror(__T);
137 yeccpars2(2, ';', __Ss, __Stack, __T, __Ts, __Tzr) ->
138 yeccpars1(__Ts, __Tzr, 27, [2 | __Ss], [__T | __Stack]);
139 yeccpars2(2, __Cat, __Ss, [__1|__Stack], __T, __Ts, __Tzr) ->
140 __Val = {alist,__1,nil},
141 yeccpars2(yeccgoto(alist, hd(__Ss)), __Cat, __Ss, [__Val | __Stack], __T, __Ts, __Tzr);
142 yeccpars2(3, __Cat, __Ss, [__1|__Stack], __T, __Ts, __Tzr) ->
143 __Val = {name,__1},
144 yeccpars2(yeccgoto(name, hd(__Ss)), __Cat, __Ss, [__Val | __Stack], __T, __Ts, __Tzr);
145 yeccpars2(4, '=', __Ss, __Stack, __T, __Ts, __Tzr) ->
146 yeccpars1(__Ts, __Tzr, 5, [4 | __Ss], [__T | __Stack]);
147 yeccpars2(4, _, _, _, __T, _, _) ->
148 yeccerror(__T);
149 yeccpars2(5, atom, __Ss, __Stack, __T, __Ts, __Tzr) ->
150 yeccpars1(__Ts, __Tzr, 3, [5 | __Ss], [__T | __Stack]);
151 yeccpars2(5, integer, __Ss, __Stack, __T, __Ts, __Tzr) ->
152 yeccpars1(__Ts, __Tzr, 7, [5 | __Ss], [__T | __Stack]);
153 yeccpars2(5, '*', __Ss, __Stack, __T, __Ts, __Tzr) ->
154 yeccpars1(__Ts, __Tzr, 6, [5 | __Ss], [__T | __Stack]);
155 yeccpars2(5, '{', __Ss, __Stack, __T, __Ts, __Tzr) ->
156 yeccpars1(__Ts, __Tzr, 10, [5 | __Ss], [__T | __Stack]);
157 yeccpars2(5, _, _, _, __T, _, _) ->
158 yeccerror(__T);
159 yeccpars2(6, atom, __Ss, __Stack, __T, __Ts, __Tzr) ->
160 yeccpars1(__Ts, __Tzr, 26, [6 | __Ss], [__T | __Stack]);
161 yeccpars2(6, _, _, _, __T, _, _) ->
162 yeccerror(__T);
163 yeccpars2(7, __Cat, __Ss, [__1|__Stack], __T, __Ts, __Tzr) ->
164 __Val = {lit,__1},
165 yeccpars2(yeccgoto(val, hd(__Ss)), __Cat, __Ss, [__Val | __Stack], __T, __Ts, __Tzr);
166 yeccpars2(8, __Cat, __Ss, [__1|__Stack], __T, __Ts, __Tzr) ->
167 __Val = begin
168 existing_name(__1), __1
169 end,
170 yeccpars2(yeccgoto(val, hd(__Ss)), __Cat, __Ss, [__Val | __Stack], __T, __Ts, __Tzr);
171 yeccpars2(9, '(', __Ss, __Stack, __T, __Ts, __Tzr) ->
172 yeccpars1(__Ts, __Tzr, 20, [9 | __Ss], [__T | __Stack]);
173 yeccpars2(9, __Cat, __Ss, [__3,__2,__1|__Stack], __T, __Ts, __Tzr) ->
174 __Val = begin
175 new_name(__1), {assign,__1,__3}
176 end,
177 __Nss = lists:nthtail(2, __Ss),
178 yeccpars2(yeccgoto(appl, hd(__Nss)), __Cat, __Nss, [__Val | __Stack], __T, __Ts, __Tzr);
179 yeccpars2(10, atom, __Ss, __Stack, __T, __Ts, __Tzr) ->
180 yeccpars1(__Ts, __Tzr, 3, [10 | __Ss], [__T | __Stack]);
181 yeccpars2(10, _, _, _, __T, _, _) ->
182 yeccerror(__T);
183 yeccpars2(11, ',', __Ss, __Stack, __T, __Ts, __Tzr) ->
184 yeccpars1(__Ts, __Tzr, 18, [11 | __Ss], [__T | __Stack]);
185 yeccpars2(11, __Cat, __Ss, [__1|__Stack], __T, __Ts, __Tzr) ->
186 __Val = begin
187 new_name(__1), {nlist,__1,nil}
188 end,
189 yeccpars2(yeccgoto(nlist, hd(__Ss)), __Cat, __Ss, [__Val | __Stack], __T, __Ts, __Tzr);
190 yeccpars2(12, '|', __Ss, __Stack, __T, __Ts, __Tzr) ->
191 yeccpars1(__Ts, __Tzr, 13, [12 | __Ss], [__T | __Stack]);
192 yeccpars2(12, _, _, _, __T, _, _) ->
193 yeccerror(__T);
194 yeccpars2(13, atom, __Ss, __Stack, __T, __Ts, __Tzr) ->
195 yeccpars1(__Ts, __Tzr, 3, [13 | __Ss], [__T | __Stack]);
196 yeccpars2(13, _, _, _, __T, _, _) ->
197 yeccerror(__T);
198 yeccpars2(14, '|', __Ss, __Stack, __T, __Ts, __Tzr) ->
199 yeccpars1(__Ts, __Tzr, 15, [14 | __Ss], [__T | __Stack]);
200 yeccpars2(14, _, _, _, __T, _, _) ->
201 yeccerror(__T);
202 yeccpars2(15, atom, __Ss, __Stack, __T, __Ts, __Tzr) ->
203 yeccpars1(__Ts, __Tzr, 3, [15 | __Ss], [__T | __Stack]);
204 yeccpars2(15, _, _, _, __T, _, _) ->
205 yeccerror(__T);
206 yeccpars2(16, '}', __Ss, __Stack, __T, __Ts, __Tzr) ->
207 yeccpars1(__Ts, __Tzr, 17, [16 | __Ss], [__T | __Stack]);
208 yeccpars2(16, _, _, _, __T, _, _) ->
209 yeccerror(__T);
210 yeccpars2(17, __Cat, __Ss, [__7,__6,__5,__4,__3,__2,__1|__Stack], __T, __Ts, __Tzr) ->
211 __Val = {lambda,__2,__4,__6},
212 __Nss = lists:nthtail(6, __Ss),
213 yeccpars2(yeccgoto(val, hd(__Nss)), __Cat, __Nss, [__Val | __Stack], __T, __Ts, __Tzr);
214 yeccpars2(18, atom, __Ss, __Stack, __T, __Ts, __Tzr) ->
215 yeccpars1(__Ts, __Tzr, 3, [18 | __Ss], [__T | __Stack]);
216 yeccpars2(18, _, _, _, __T, _, _) ->
217 yeccerror(__T);
218 yeccpars2(19, __Cat, __Ss, [__3,__2,__1|__Stack], __T, __Ts, __Tzr) ->
219 __Val = begin
220 new_name(__1), {nlist,__1,__3}
221 end,
222 __Nss = lists:nthtail(2, __Ss),
223 yeccpars2(yeccgoto(nlist, hd(__Nss)), __Cat, __Nss, [__Val | __Stack], __T, __Ts, __Tzr);
224 yeccpars2(20, atom, __Ss, __Stack, __T, __Ts, __Tzr) ->
225 yeccpars1(__Ts, __Tzr, 3, [20 | __Ss], [__T | __Stack]);
226 yeccpars2(20, integer, __Ss, __Stack, __T, __Ts, __Tzr) ->
227 yeccpars1(__Ts, __Tzr, 7, [20 | __Ss], [__T | __Stack]);
228 yeccpars2(20, '*', __Ss, __Stack, __T, __Ts, __Tzr) ->
229 yeccpars1(__Ts, __Tzr, 6, [20 | __Ss], [__T | __Stack]);
230 yeccpars2(20, '{', __Ss, __Stack, __T, __Ts, __Tzr) ->
231 yeccpars1(__Ts, __Tzr, 10, [20 | __Ss], [__T | __Stack]);
232 yeccpars2(20, _, _, _, __T, _, _) ->
233 yeccerror(__T);
234 yeccpars2(21, ',', __Ss, __Stack, __T, __Ts, __Tzr) ->
235 yeccpars1(__Ts, __Tzr, 24, [21 | __Ss], [__T | __Stack]);
236 yeccpars2(21, __Cat, __Ss, [__1|__Stack], __T, __Ts, __Tzr) ->
237 __Val = {vlist,__1,nil},
238 yeccpars2(yeccgoto(vlist, hd(__Ss)), __Cat, __Ss, [__Val | __Stack], __T, __Ts, __Tzr);
239 yeccpars2(22, ')', __Ss, __Stack, __T, __Ts, __Tzr) ->
240 yeccpars1(__Ts, __Tzr, 23, [22 | __Ss], [__T | __Stack]);
241 yeccpars2(22, _, _, _, __T, _, _) ->
242 yeccerror(__T);
243 yeccpars2(23, __Cat, __Ss, [__6,__5,__4,__3,__2,__1|__Stack], __T, __Ts, __Tzr) ->
244 __Val = begin
245 new_name(__1), {assign,__1,__3,__5}
246 end,
247 __Nss = lists:nthtail(5, __Ss),
248 yeccpars2(yeccgoto(appl, hd(__Nss)), __Cat, __Nss, [__Val | __Stack], __T, __Ts, __Tzr);
249 yeccpars2(24, atom, __Ss, __Stack, __T, __Ts, __Tzr) ->
250 yeccpars1(__Ts, __Tzr, 3, [24 | __Ss], [__T | __Stack]);
251 yeccpars2(24, integer, __Ss, __Stack, __T, __Ts, __Tzr) ->
252 yeccpars1(__Ts, __Tzr, 7, [24 | __Ss], [__T | __Stack]);
253 yeccpars2(24, '*', __Ss, __Stack, __T, __Ts, __Tzr) ->
254 yeccpars1(__Ts, __Tzr, 6, [24 | __Ss], [__T | __Stack]);
255 yeccpars2(24, '{', __Ss, __Stack, __T, __Ts, __Tzr) ->
256 yeccpars1(__Ts, __Tzr, 10, [24 | __Ss], [__T | __Stack]);
257 yeccpars2(24, _, _, _, __T, _, _) ->
258 yeccerror(__T);
259 yeccpars2(25, __Cat, __Ss, [__3,__2,__1|__Stack], __T, __Ts, __Tzr) ->
260 __Val = {vlist,__1,__3},
261 __Nss = lists:nthtail(2, __Ss),
262 yeccpars2(yeccgoto(vlist, hd(__Nss)), __Cat, __Nss, [__Val | __Stack], __T, __Ts, __Tzr);
263 yeccpars2(26, __Cat, __Ss, [__2,__1|__Stack], __T, __Ts, __Tzr) ->
264 __Val = {lit,__2},
265 __Nss = lists:nthtail(1, __Ss),
266 yeccpars2(yeccgoto(val, hd(__Nss)), __Cat, __Nss, [__Val | __Stack], __T, __Ts, __Tzr);
267 yeccpars2(27, atom, __Ss, __Stack, __T, __Ts, __Tzr) ->
268 yeccpars1(__Ts, __Tzr, 3, [27 | __Ss], [__T | __Stack]);
269 yeccpars2(27, _, _, _, __T, _, _) ->
270 yeccerror(__T);
271 yeccpars2(28, __Cat, __Ss, [__3,__2,__1|__Stack], __T, __Ts, __Tzr) ->
272 __Val = {alist,__1,__3},
273 __Nss = lists:nthtail(2, __Ss),
274 yeccpars2(yeccgoto(alist, hd(__Nss)), __Cat, __Nss, [__Val | __Stack], __T, __Ts, __Tzr);
275 yeccpars2(__Other, _, _, _, _, _, _) ->
276 exit({parser, __Other, missing_state_in_action_table}).
277
278 yeccgoto(alist, 0) ->
279 1;
280 yeccgoto(alist, 13) ->
281 14;
282 yeccgoto(alist, 27) ->
283 28;
284 yeccgoto(appl, 0) ->
285 2;
286 yeccgoto(appl, 13) ->
287 2;
288 yeccgoto(appl, 27) ->
289 2;
290 yeccgoto(name, 0) ->
291 4;
292 yeccgoto(name, 5) ->
293 8;
294 yeccgoto(name, 10) ->
295 11;
296 yeccgoto(name, 13) ->
297 4;
298 yeccgoto(name, 15) ->
299 16;
300 yeccgoto(name, 18) ->
301 11;
302 yeccgoto(name, 20) ->
303 8;
304 yeccgoto(name, 24) ->
305 8;
306 yeccgoto(name, 27) ->
307 4;
308 yeccgoto(nlist, 10) ->
309 12;
310 yeccgoto(nlist, 18) ->
311 19;
312 yeccgoto(val, 5) ->
313 9;
314 yeccgoto(val, 20) ->
315 21;
316 yeccgoto(val, 24) ->
317 21;
318 yeccgoto(vlist, 20) ->
319 22;
320 yeccgoto(vlist, 24) ->
321 25;
322 yeccgoto(__Symbol, __State) ->
323 exit({__Symbol, __State, missing_in_goto_table}).
324
325
0 %%% -grammar(sbeezg_parser).
1 %%% -vsn('2002.0317').
2 %%% -author('cpressey@catseye.mb.ca').
3 %%% -copyright('Copyright (c)2002 Cat`s Eye Technologies. All rights reserved.').
4
5 %%% Redistribution and use in source and binary forms, with or without
6 %%% modification, are permitted provided that the following conditions
7 %%% are met:
8 %%%
9 %%% Redistributions of source code must retain the above copyright
10 %%% notice, this list of conditions and the following disclaimer.
11 %%%
12 %%% Redistributions in binary form must reproduce the above copyright
13 %%% notice, this list of conditions and the following disclaimer in
14 %%% the documentation and/or other materials provided with the
15 %%% distribution.
16 %%%
17 %%% Neither the name of Cat's Eye Technologies nor the names of its
18 %%% contributors may be used to endorse or promote products derived
19 %%% from this software without specific prior written permission.
20 %%%
21 %%% THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
22 %%% CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
23 %%% INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
24 %%% MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
25 %%% DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
26 %%% LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
27 %%% OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
28 %%% PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
29 %%% OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
30 %%% ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
31 %%% OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32 %%% OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
33 %%% POSSIBILITY OF SUCH DAMAGE.
34
35 %%% BEGIN sbeezg_parser.yrl %%%
36
37 Nonterminals vlist val nlist name alist appl.
38 Terminals '=' '*' '(' ')' '{' '|' '}' ',' ';' atom integer.
39 Rootsymbol alist.
40
41 %%% EBNF:
42 %%% Appl ::= Name "=" Val "(" Val {"," Val} ")".
43 %%% Val ::= Name | "*" Const | "{" Name {"," Name} "|" Appl {";" Appl} "|" Name "}".
44
45 %%% Recursive Version (no {}'s):
46 %%% Appl ::= Name "=" Val ["(" Vlist ")"].
47 %%% Vlist ::= Val ["," Vlist].
48 %%% Val ::= Name | "*" Name | "{" Nlist "|" Alist "|" Name "}".
49 %%% Nlist ::= Name ["," Nlist].
50 %%% Alist ::= Appl [";" Alist].
51
52 appl -> name '=' val '(' vlist ')' : new_name('$1'), {assign, '$1', '$3', '$5'}.
53 appl -> name '=' val : new_name('$1'), {assign, '$1', '$3'}.
54 vlist -> val ',' vlist : {vlist, '$1', '$3'}.
55 vlist -> val : {vlist, '$1', nil}.
56 val -> '{' nlist '|' alist '|' name '}' : {lambda, '$2', '$4', '$6'}.
57 val -> '*' atom : {lit, '$2'}.
58 val -> integer : {lit, '$1'}.
59 val -> name : existing_name('$1'), '$1'.
60 nlist -> name ',' nlist : new_name('$1'), {nlist, '$1', '$3'}.
61 nlist -> name : new_name('$1'), {nlist, '$1', nil}.
62 alist -> appl ';' alist : {alist, '$1', '$3'}.
63 alist -> appl : {alist, '$1', nil}.
64 name -> atom : {name, '$1'}.
65
66 Erlang code.
67
68 new_name({name,{atom,Line,Name}}=A) ->
69 case get(A) of
70 defn ->
71 return_error(0, io_lib:format("Name '~w' already defined", [Name]));
72 _ ->
73 put(A, defn)
74 end.
75
76 existing_name({name,{atom,Line,Name}}=A) ->
77 case get(A) of
78 undefined ->
79 return_error(0, io_lib:format("Name '~w' is not yet defined", [Name]));
80 _ ->
81 ok
82 end.
83
84 %%% END of sbeezg_parser.yrl %%%