1%% ``Licensed under the Apache License, Version 2.0 (the "License");
2%% you may not use this file except in compliance with the License.
3%% You may obtain a copy of the License at
4%%
5%%     http://www.apache.org/licenses/LICENSE-2.0
6%%
7%% Unless required by applicable law or agreed to in writing, software
8%% distributed under the License is distributed on an "AS IS" BASIS,
9%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10%% See the License for the specific language governing permissions and
11%% limitations under the License.
12%%
13%% The Initial Developer of the Original Code is Ericsson Utvecklings AB.
14%% Portions created by Ericsson are Copyright 2000, Ericsson Utvecklings
15%% AB. All Rights Reserved.''
16%%
17%%     $Id: asn1ct_parser2.erl,v 1.1 2008/12/17 09:53:30 mikpe Exp $
18-module(asn1ct_parser2).
19
20-export([parse/1]).
21-include("asn1_records.hrl").
22
23%% parse all types in module
24parse(Tokens) ->
25    case catch parse_ModuleDefinition(Tokens) of
26	{'EXIT',Reason} ->
27	    {error,{{undefined,get(asn1_module),
28		    [internal,error,'when',parsing,module,definition,Reason]},
29		    hd(Tokens)}};
30	{asn1_error,Reason} ->
31	    {error,{Reason,hd(Tokens)}};
32	{ModuleDefinition,Rest1} ->
33	    {Types,Rest2} = parse_AssignmentList(Rest1),
34	    case Rest2 of
35		[{'END',_}|_Rest3] ->
36		    {ok,ModuleDefinition#module{typeorval = Types}};
37		_  ->
38		    {error,{{get_line(hd(Rest2)),get(asn1_module),
39			     [got,get_token(hd(Rest2)),expected,'END']},
40			    hd(Rest2)}}
41	    end
42    end.
43
44parse_ModuleDefinition([{typereference,L1,ModuleIdentifier}|Rest0]) ->
45    put(asn1_module,ModuleIdentifier),
46    {_DefinitiveIdentifier,Rest02} =
47	case Rest0 of
48	    [{'{',_}|_Rest01] ->
49		parse_ObjectIdentifierValue(Rest0);
50	    _ ->
51		{[],Rest0}
52	end,
53    Rest = case Rest02 of
54	       [{'DEFINITIONS',_}|Rest03] ->
55		   Rest03;
56	       _ ->
57		   throw({asn1_error,{get_line(hd(Rest02)),get(asn1_module),
58				      [got,get_token(hd(Rest02)),
59				       expected,'DEFINITIONS']}})
60	   end,
61    {TagDefault,Rest2} =
62	case Rest of
63	    [{'EXPLICIT',_L3},{'TAGS',_L4}|Rest1] ->
64		put(tagdefault,'EXPLICIT'), {'EXPLICIT',Rest1};
65	    [{'IMPLICIT',_L3},{'TAGS',_L4}|Rest1] ->
66		put(tagdefault,'IMPLICIT'), {'IMPLICIT',Rest1};
67	    [{'AUTOMATIC',_L3},{'TAGS',_L4}|Rest1] ->
68		put(tagdefault,'AUTOMATIC'), {'AUTOMATIC',Rest1};
69	    Rest1 ->
70		put(tagdefault,'EXPLICIT'), {'EXPLICIT',Rest1} % The default
71	end,
72    {ExtensionDefault,Rest3} =
73	case Rest2 of
74	    [{'EXTENSIBILITY',_L5}, {'IMPLIED',_L6}|Rest21] ->
75		{'IMPLIED',Rest21};
76	    _  -> {false,Rest2}
77	end,
78    case Rest3 of
79	[{'::=',_L7}, {'BEGIN',_L8}|Rest4] ->
80	    {Exports, Rest5} = parse_Exports(Rest4),
81	    {Imports, Rest6} = parse_Imports(Rest5),
82	    {#module{ pos = L1,
83		     name = ModuleIdentifier,
84		     defid = [], % fix this
85		     tagdefault = TagDefault,
86		     extensiondefault = ExtensionDefault,
87		     exports = Exports,
88		     imports = Imports},Rest6};
89	_ -> throw({asn1_error,{get_line(hd(Rest3)),get(asn1_module),
90				[got,get_token(hd(Rest3)),expected,"::= BEGIN"]}})
91    end;
92parse_ModuleDefinition(Tokens) ->
93    throw({asn1_error,{get_line(hd(Tokens)),get(asn1_module),
94		       [got,get_token(hd(Tokens)),expected,typereference]}}).
95
96parse_Exports([{'EXPORTS',_L1},{';',_L2}|Rest]) ->
97    {{exports,[]},Rest};
98parse_Exports([{'EXPORTS',_L1}|Rest]) ->
99    {SymbolList,Rest2} = parse_SymbolList(Rest),
100    case Rest2 of
101	[{';',_}|Rest3] ->
102	    {{exports,SymbolList},Rest3};
103	_ ->
104	    throw({asn1_error,{get_line(hd(Rest2)),get(asn1_module),
105			       [got,get_token(hd(Rest2)),expected,';']}})
106    end;
107parse_Exports(Rest) ->
108    {{exports,all},Rest}.
109
110parse_SymbolList(Tokens) ->
111    parse_SymbolList(Tokens,[]).
112
113parse_SymbolList(Tokens,Acc) ->
114    {Symbol,Rest} = parse_Symbol(Tokens),
115    case Rest of
116	[{',',_L1}|Rest2] ->
117	    parse_SymbolList(Rest2,[Symbol|Acc]);
118	Rest2  ->
119	    {lists:reverse([Symbol|Acc]),Rest2}
120    end.
121
122parse_Symbol(Tokens) ->
123    parse_Reference(Tokens).
124
125parse_Reference([{typereference,L1,TrefName},{'{',_L2},{'}',_L3}|Rest]) ->
126%    {Tref,Rest};
127    {tref2Exttref(L1,TrefName),Rest};
128parse_Reference([Tref1 = {typereference,_,_},{'.',_},Tref2 = {typereference,_,_},
129		 {'{',_L2},{'}',_L3}|Rest]) ->
130%    {{Tref1,Tref2},Rest};
131    {{tref2Exttref(Tref1),tref2Exttref(Tref2)},Rest};
132parse_Reference([Tref = {typereference,_L1,_TrefName}|Rest]) ->
133    {tref2Exttref(Tref),Rest};
134parse_Reference([Vref = {identifier,_L1,_VName}|Rest]) ->
135    {identifier2Extvalueref(Vref),Rest};
136parse_Reference(Tokens) ->
137    throw({asn1_error,{get_line(hd(Tokens)),get(asn1_module),
138		       [got,get_token(hd(Tokens)),expected,
139			[typereference,identifier]]}}).
140
141parse_Imports([{'IMPORTS',_L1},{';',_L2}|Rest]) ->
142    {{imports,[]},Rest};
143parse_Imports([{'IMPORTS',_L1}|Rest]) ->
144    {SymbolsFromModuleList,Rest2} = parse_SymbolsFromModuleList(Rest),
145    case Rest2 of
146	[{';',_L2}|Rest3] ->
147	    {{imports,SymbolsFromModuleList},Rest3};
148	Rest3 ->
149	    throw({asn1_error,{get_line(hd(Rest3)),get(asn1_module),
150			       [got,get_token(hd(Rest3)),expected,';']}})
151    end;
152parse_Imports(Tokens) ->
153    {{imports,[]},Tokens}.
154
155parse_SymbolsFromModuleList(Tokens) ->
156    parse_SymbolsFromModuleList(Tokens,[]).
157
158parse_SymbolsFromModuleList(Tokens,Acc) ->
159    {SymbolsFromModule,Rest} = parse_SymbolsFromModule(Tokens),
160    case (catch parse_SymbolsFromModule(Rest)) of
161	{Sl,_Rest2} when record(Sl,'SymbolsFromModule') ->
162	    parse_SymbolsFromModuleList(Rest,[SymbolsFromModule|Acc]);
163	_  ->
164	    {lists:reverse([SymbolsFromModule|Acc]),Rest}
165    end.
166
167parse_SymbolsFromModule(Tokens) ->
168    SetRefModuleName =
169	fun(N) ->
170		fun(X) when record(X,'Externaltypereference')->
171			X#'Externaltypereference'{module=N};
172		   (X) when record(X,'Externalvaluereference')->
173			X#'Externalvaluereference'{module=N}
174		end
175	end,
176    {SymbolList,Rest} = parse_SymbolList(Tokens),
177    case Rest of
178	%%How does this case correspond to x.680 ?
179	[{'FROM',_L1},Tref = {typereference,_,_},Ref={identifier,_L2,_Id},C={',',_}|Rest2] ->
180	    {#'SymbolsFromModule'{symbols=SymbolList,
181				  module=tref2Exttref(Tref)},[Ref,C|Rest2]};
182	%%How does this case correspond to x.680 ?
183	[{'FROM',_L1},Tref = {typereference,_,_},{identifier,_L2,_Id}|Rest2] ->
184	    {#'SymbolsFromModule'{symbols=SymbolList,
185				  module=tref2Exttref(Tref)},Rest2};
186	[{'FROM',_L1},Tref = {typereference,_,Name},Brace = {'{',_}|Rest2] ->
187	    {_ObjIdVal,Rest3} = parse_ObjectIdentifierValue([Brace|Rest2]), % value not used yet, fix me
188	    NewSymbolList = lists:map(SetRefModuleName(Name),SymbolList),
189	    {#'SymbolsFromModule'{symbols=NewSymbolList,
190				  module=tref2Exttref(Tref)},Rest3};
191	[{'FROM',_L1},Tref = {typereference,_,Name}|Rest2] ->
192	    NewSymbolList = lists:map(SetRefModuleName(Name),SymbolList),
193	    {#'SymbolsFromModule'{symbols=NewSymbolList,
194				  module=tref2Exttref(Tref)},Rest2};
195	_ ->
196	    throw({asn1_error,{get_line(hd(Rest)),get(asn1_module),
197			       [got,get_token(hd(Rest)),expected,
198				['FROM typerefernece identifier ,',
199				 'FROM typereference identifier',
200				 'FROM typereference {',
201				 'FROM typereference']]}})
202    end.
203
204parse_ObjectIdentifierValue([{'{',_}|Rest]) ->
205    parse_ObjectIdentifierValue(Rest,[]).
206
207parse_ObjectIdentifierValue([{number,_,Num}|Rest],Acc) ->
208    parse_ObjectIdentifierValue(Rest,[Num|Acc]);
209parse_ObjectIdentifierValue([{identifier,_,Id},{'(',_}, {number,_,Num}, {')',_}|Rest],Acc) ->
210    parse_ObjectIdentifierValue(Rest,[{'NamedNumber',Id,Num}|Acc]);
211parse_ObjectIdentifierValue([{identifier,_,Id},{'(',_}, {identifier,_,Id2}, {')',_}|Rest],Acc) ->
212    parse_ObjectIdentifierValue(Rest,[{'NamedNumber',Id,Id2}|Acc]);
213parse_ObjectIdentifierValue([{identifier,_,Id},{'(',_}, {typereference,_,Tref},{'.',_},{identifier,_,Id2}, {')',_}|Rest],Acc) ->
214    parse_ObjectIdentifierValue(Rest,[{'NamedNumber',Id,{'ExternalValue',Tref,Id2}}|Acc]);
215parse_ObjectIdentifierValue([Id = {identifier,_,_}|Rest],Acc) ->
216    parse_ObjectIdentifierValue(Rest,[identifier2Extvalueref(Id)|Acc]);
217parse_ObjectIdentifierValue([{'}',_}|Rest],Acc) ->
218    {lists:reverse(Acc),Rest};
219parse_ObjectIdentifierValue([H|_T],_Acc) ->
220    throw({asn1_error,{get_line(H),get(asn1_module),
221		       [got,get_token(H),expected,
222			['{ some of the following }',number,'identifier ( number )',
223			 'identifier ( identifier )',
224			 'identifier ( typereference.identifier)',identifier]]}}).
225
226parse_AssignmentList(Tokens = [{'END',_}|_Rest]) ->
227    {[],Tokens};
228parse_AssignmentList(Tokens = [{'$end',_}|_Rest]) ->
229    {[],Tokens};
230parse_AssignmentList(Tokens) ->
231    parse_AssignmentList(Tokens,[]).
232
233parse_AssignmentList(Tokens= [{'END',_}|_Rest],Acc) ->
234    {lists:reverse(Acc),Tokens};
235parse_AssignmentList(Tokens= [{'$end',_}|_Rest],Acc) ->
236    {lists:reverse(Acc),Tokens};
237parse_AssignmentList(Tokens,Acc) ->
238    case (catch parse_Assignment(Tokens)) of
239	{'EXIT',Reason} ->
240	    exit(Reason);
241	{asn1_error,R} ->
242%	    [H|T] = Tokens,
243	    throw({error,{R,hd(Tokens)}});
244	{Assignment,Rest} ->
245	    parse_AssignmentList(Rest,[Assignment|Acc])
246    end.
247
248parse_Assignment(Tokens) ->
249    Flist = [fun parse_TypeAssignment/1,
250	     fun parse_ValueAssignment/1,
251	     fun parse_ObjectClassAssignment/1,
252	     fun parse_ObjectAssignment/1,
253	     fun parse_ObjectSetAssignment/1,
254	     fun parse_ParameterizedAssignment/1,
255	     fun parse_ValueSetTypeAssignment/1],
256    case (catch parse_or(Tokens,Flist)) of
257	{'EXIT',Reason} ->
258	    exit(Reason);
259	AsnErr = {asn1_error,_} ->
260	    throw(AsnErr);
261	{asn1_assignment_error,Reason} ->
262	    throw({asn1_error,Reason});
263	Result ->
264	    Result
265    end.
266
267
268parse_or(Tokens,Flist) ->
269	parse_or(Tokens,Flist,[]).
270
271parse_or(_Tokens,[],ErrList) ->
272    case ErrList of
273	[] ->
274	    throw({asn1_error,{parse_or,ErrList}});
275	L when list(L) ->
276%%%	    throw({asn1_error,{parse_or,hd(lists:reverse(ErrList))}});
277	    %% chose to throw 1) the error with the highest line no,
278	    %% 2) the last error which is not a asn1_assignment_error or
279	    %% 3) the last error.
280	    throw(prioritize_error(ErrList));
281	Other ->
282	    throw({asn1_error,{parse_or,Other}})
283    end;
284parse_or(Tokens,[Fun|Frest],ErrList) ->
285    case (catch Fun(Tokens)) of
286	Exit = {'EXIT',_Reason} ->
287	    parse_or(Tokens,Frest,[Exit|ErrList]);
288	AsnErr = {asn1_error,_} ->
289	    parse_or(Tokens,Frest,[AsnErr|ErrList]);
290	AsnAssErr = {asn1_assignment_error,_} ->
291	    parse_or(Tokens,Frest,[AsnAssErr|ErrList]);
292	Result = {_,L} when list(L) ->
293	    Result;
294%	Result ->
295%	    Result
296	Error  ->
297	    parse_or(Tokens,Frest,[Error|ErrList])
298    end.
299
300parse_TypeAssignment([{typereference,L1,Tref},{'::=',_}|Rest]) ->
301    {Type,Rest2} = parse_Type(Rest),
302    {#typedef{pos=L1,name=Tref,typespec=Type},Rest2};
303parse_TypeAssignment([H1,H2|_Rest]) ->
304    throw({asn1_assignment_error,{get_line(H1),get(asn1_module),
305				  [got,[get_token(H1),get_token(H2)], expected,
306				   typereference,'::=']}});
307parse_TypeAssignment([H|_T]) ->
308    throw({asn1_assignment_error,{get_line(H),get(asn1_module),
309				  [got,get_token(H),expected,
310				   typereference]}}).
311
312parse_Type(Tokens) ->
313    {Tag,Rest3} = case Tokens of
314		      [Lbr= {'[',_}|Rest] ->
315			  parse_Tag([Lbr|Rest]);
316		      Rest-> {[],Rest}
317		  end,
318    {Tag2,Rest4} = case Rest3 of
319		       [{'IMPLICIT',_}|Rest31] when record(Tag,tag)->
320			   {[Tag#tag{type='IMPLICIT'}],Rest31};
321		       [{'EXPLICIT',_}|Rest31] when record(Tag,tag)->
322			   {[Tag#tag{type='EXPLICIT'}],Rest31};
323		       Rest31 when record(Tag,tag) ->
324			   {[Tag#tag{type={default,get(tagdefault)}}],Rest31};
325		       Rest31 ->
326			   {Tag,Rest31}
327		   end,
328    Flist = [fun parse_BuiltinType/1,fun parse_ReferencedType/1,fun parse_TypeWithConstraint/1],
329    {Type,Rest5} = case (catch parse_or(Rest4,Flist)) of
330		      {'EXIT',Reason} ->
331			  exit(Reason);
332			AsnErr = {asn1_error,_Reason} ->
333			 throw(AsnErr);
334		      Result ->
335			  Result
336		  end,
337    case hd(Rest5) of
338	{'(',_} ->
339	    {Constraints,Rest6} = parse_Constraints(Rest5),
340	    if record(Type,type) ->
341		    {Type#type{constraint=merge_constraints(Constraints),
342			       tag=Tag2},Rest6};
343	       true ->
344		    {#type{def=Type,constraint=merge_constraints(Constraints),
345			   tag=Tag2},Rest6}
346	    end;
347	_ ->
348	    if record(Type,type) ->
349		    {Type#type{tag=Tag2},Rest5};
350	       true ->
351		    {#type{def=Type,tag=Tag2},Rest5}
352	    end
353    end.
354
355parse_BuiltinType([{'BIT',_},{'STRING',_}|Rest]) ->
356    case Rest of
357	[{'{',_}|Rest2] ->
358	    {NamedNumberList,Rest3} = parse_NamedNumberList(Rest2),
359	    case Rest3 of
360		[{'}',_}|Rest4] ->
361		    {#type{def={'BIT STRING',NamedNumberList}},Rest4};
362		_ ->
363		    throw({asn1_error,{get_line(hd(Rest3)),get(asn1_module),
364				       [got,get_token(hd(Rest3)),expected,'}']}})
365	    end;
366	 _ ->
367	    {{'BIT STRING',[]},Rest}
368    end;
369parse_BuiltinType([{'BOOLEAN',_}|Rest]) ->
370    {#type{def='BOOLEAN'},Rest};
371%% CharacterStringType ::= RestrictedCharacterStringType |
372%%                         UnrestrictedCharacterStringType
373parse_BuiltinType([{restrictedcharacterstringtype,_,StringName}|Rest]) ->
374    {#type{def=StringName},Rest};
375parse_BuiltinType([{'CHARACTER',_},{'STRING',_}|Rest]) ->
376    {#type{def='CHARACTER STRING'},Rest};
377
378parse_BuiltinType([{'CHOICE',_},{'{',_}|Rest]) ->
379    {AlternativeTypeLists,Rest2} = parse_AlternativeTypeLists(Rest),
380    case Rest2 of
381	[{'}',_}|Rest3] ->
382	    {#type{def={'CHOICE',AlternativeTypeLists}},Rest3};
383	_  ->
384	    throw({asn1_error,{get_line(hd(Rest2)),get(asn1_module),
385			       [got,get_token(hd(Rest2)),expected,'}']}})
386    end;
387parse_BuiltinType([{'EMBEDDED',_},{'PDV',_}|Rest]) ->
388    {#type{def='EMBEDDED PDV'},Rest};
389parse_BuiltinType([{'ENUMERATED',_},{'{',_}|Rest]) ->
390    {Enumerations,Rest2} = parse_Enumerations(Rest),
391    case Rest2 of
392	[{'}',_}|Rest3] ->
393	    {#type{def={'ENUMERATED',Enumerations}},Rest3};
394	_ ->
395	    throw({asn1_error,{get_line(hd(Rest2)),get(asn1_module),
396			       [got,get_token(hd(Rest2)),expected,'}']}})
397    end;
398parse_BuiltinType([{'EXTERNAL',_}|Rest]) ->
399    {#type{def='EXTERNAL'},Rest};
400
401% InstanceOfType
402parse_BuiltinType([{'INSTANCE',_},{'OF',_}|Rest]) ->
403    {DefinedObjectClass,Rest2} = parse_DefinedObjectClass(Rest),
404    case Rest2 of
405	[{'(',_}|_] ->
406	    {Constraint,Rest3} = parse_Constraint(Rest2),
407	    {#type{def={'INSTANCE OF',DefinedObjectClass,Constraint}},Rest3};
408	_ ->
409	    {#type{def={'INSTANCE OF',DefinedObjectClass,[]}},Rest2}
410    end;
411
412% parse_BuiltinType(Tokens) ->
413
414parse_BuiltinType([{'INTEGER',_}|Rest]) ->
415    case Rest of
416	[{'{',_}|Rest2] ->
417	    {NamedNumberList,Rest3} = parse_NamedNumberList(Rest2),
418	    case Rest3 of
419		[{'}',_}|Rest4] ->
420		    {#type{def={'INTEGER',NamedNumberList}},Rest4};
421		_ ->
422		    throw({asn1_error,{get_line(hd(Rest3)),get(asn1_module),
423				       [got,get_token(hd(Rest3)),expected,'}']}})
424	    end;
425	 _ ->
426	    {#type{def='INTEGER'},Rest}
427    end;
428parse_BuiltinType([{'NULL',_}|Rest]) ->
429    {#type{def='NULL'},Rest};
430
431% ObjectClassFieldType fix me later
432
433parse_BuiltinType([{'OBJECT',_},{'IDENTIFIER',_}|Rest]) ->
434    {#type{def='OBJECT IDENTIFIER'},Rest};
435parse_BuiltinType([{'OCTET',_},{'STRING',_}|Rest]) ->
436    {#type{def='OCTET STRING'},Rest};
437parse_BuiltinType([{'REAL',_}|Rest]) ->
438    {#type{def='REAL'},Rest};
439parse_BuiltinType([{'SEQUENCE',_},{'{',_},{'...',Line},{'}',_}|Rest]) ->
440    {#type{def=#'SEQUENCE'{components=[{'EXTENSIONMARK',Line,undefined}]}},
441     Rest};
442parse_BuiltinType([{'SEQUENCE',_},{'{',_},{'...',Line},{'!',_}|Rest]) ->
443    {ExceptionIdentification,Rest2} = parse_ExceptionIdentification(Rest),
444    case Rest2 of
445	[{'}',_}|Rest3] ->
446	    {#type{def=#'SEQUENCE'{components=[{'EXTENSIONMARK',
447						Line,
448						ExceptionIdentification}]}},
449	     Rest3};
450	_ ->
451	    throw({asn1_error,{get_line(hd(Rest2)),get(asn1_module),
452			       [got,get_token(hd(Rest2)),expected,'}']}})
453    end;
454parse_BuiltinType([{'SEQUENCE',_},{'{',_}|Rest]) ->
455    {ComponentTypeLists,Rest2} = parse_ComponentTypeLists(Rest),
456    case Rest2  of
457	[{'}',_}|Rest3] ->
458	    {#type{def=#'SEQUENCE'{components=ComponentTypeLists}},Rest3};
459	_ ->
460	    throw({asn1_error,{get_line(hd(Rest2)),get(asn1_module),
461			       [got,get_token(hd(Rest2)),expected,'}']}})
462    end;
463parse_BuiltinType([{'SEQUENCE',_},{'OF',_}|Rest]) ->
464    {Type,Rest2} = parse_Type(Rest),
465    {#type{def={'SEQUENCE OF',Type}},Rest2};
466
467
468parse_BuiltinType([{'SET',_},{'{',_},{'...',Line},{'}',_}|Rest]) ->
469    {#type{def=#'SET'{components=[{'EXTENSIONMARK',Line,undefined}]}},Rest};
470parse_BuiltinType([{'SET',_},{'{',_},{'...',Line},{'!',_}|Rest]) ->
471    {ExceptionIdentification,Rest2} = parse_ExceptionIdentification(Rest),
472    case Rest2 of
473	[{'}',_}|Rest3] ->
474	    {#type{def=#'SET'{components=
475			      [{'EXTENSIONMARK',Line,ExceptionIdentification}]}},
476	     Rest3};
477	_ ->
478	    throw({asn1_error,{get_line(hd(Rest2)),get(asn1_module),
479			       [got,get_token(hd(Rest2)),expected,'}']}})
480    end;
481parse_BuiltinType([{'SET',_},{'{',_}|Rest]) ->
482    {ComponentTypeLists,Rest2} = parse_ComponentTypeLists(Rest),
483    case Rest2  of
484	[{'}',_}|Rest3] ->
485	    {#type{def=#'SET'{components=ComponentTypeLists}},Rest3};
486	_ ->
487	    throw({asn1_error,{get_line(hd(Rest2)),get(asn1_module),
488			       [got,get_token(hd(Rest2)),expected,'}']}})
489    end;
490parse_BuiltinType([{'SET',_},{'OF',_}|Rest]) ->
491    {Type,Rest2} = parse_Type(Rest),
492    {#type{def={'SET OF',Type}},Rest2};
493
494%% The so called Useful types
495parse_BuiltinType([{'GeneralizedTime',_}|Rest]) ->
496    {#type{def='GeneralizedTime'},Rest};
497parse_BuiltinType([{'UTCTime',_}|Rest]) ->
498    {#type{def='UTCTime'},Rest};
499parse_BuiltinType([{'ObjectDescriptor',_}|Rest]) ->
500    {#type{def='ObjectDescriptor'},Rest};
501
502%% For compatibility with old standard
503parse_BuiltinType([{'ANY',_},{'DEFINED',_},{'BY',_},{identifier,_,Id}|Rest]) ->
504    {#type{def={'ANY_DEFINED_BY',Id}},Rest};
505parse_BuiltinType([{'ANY',_}|Rest]) ->
506    {#type{def='ANY'},Rest};
507
508parse_BuiltinType(Tokens) ->
509    parse_ObjectClassFieldType(Tokens).
510%    throw({asn1_error,unhandled_type}).
511
512
513parse_TypeWithConstraint([{'SEQUENCE',_},Lpar = {'(',_}|Rest]) ->
514    {Constraint,Rest2} = parse_Constraint([Lpar|Rest]),
515    case Rest2 of
516	[{'OF',_}|Rest3] ->
517	    {Type,Rest4} = parse_Type(Rest3),
518	    {#type{def = {'SEQUENCE OF',Type}, constraint = merge_constraints([Constraint])},Rest4};
519	_ ->
520	    throw({asn1_error,{get_line(hd(Rest2)),get(asn1_module),
521			       [got,get_token(hd(Rest2)),expected,'OF']}})
522    end;
523parse_TypeWithConstraint([{'SEQUENCE',_},{'SIZE',_},Lpar = {'(',_}|Rest]) ->
524    {Constraint,Rest2} = parse_Constraint([Lpar|Rest]),
525    Constraint2 =
526	case Constraint of
527	    #constraint{c=C} ->
528		Constraint#constraint{c={'SizeConstraint',C}};
529	    _ -> Constraint
530	end,
531    case Rest2 of
532	[{'OF',_}|Rest3] ->
533	    {Type,Rest4} = parse_Type(Rest3),
534	    {#type{def = {'SEQUENCE OF',Type}, constraint = merge_constraints([Constraint2])},Rest4};
535	_ ->
536	    throw({asn1_error,{get_line(hd(Rest2)),get(asn1_module),
537			       [got,get_token(hd(Rest2)),expected,'OF']}})
538    end;
539parse_TypeWithConstraint([{'SET',_},Lpar = {'(',_}|Rest]) ->
540    {Constraint,Rest2} = parse_Constraint([Lpar|Rest]),
541    case Rest2 of
542	[{'OF',_}|Rest3] ->
543	    {Type,Rest4} = parse_Type(Rest3),
544	    {#type{def = {'SET OF',Type}, constraint = merge_constraints([Constraint])},Rest4};
545	_ ->
546	    throw({asn1_error,{get_line(hd(Rest2)),get(asn1_module),
547			       [got,get_token(hd(Rest2)),expected,'OF']}})
548    end;
549parse_TypeWithConstraint([{'SET',_},{'SIZE',_},Lpar = {'(',_}|Rest]) ->
550    {Constraint,Rest2} = parse_Constraint([Lpar|Rest]),
551    Constraint2 =
552	case Constraint of
553	    #constraint{c=C} ->
554		Constraint#constraint{c={'SizeConstraint',C}};
555	    _ -> Constraint
556	end,
557    case Rest2 of
558	[{'OF',_}|Rest3] ->
559	    {Type,Rest4} = parse_Type(Rest3),
560	    {#type{def = {'SET OF',Type}, constraint = merge_constraints([Constraint2])},Rest4};
561	_ ->
562	    throw({asn1_error,{get_line(hd(Rest2)),get(asn1_module),
563			       [got,get_token(hd(Rest2)),expected,'OF']}})
564    end;
565parse_TypeWithConstraint(Tokens) ->
566    throw({asn1_error,{get_line(hd(Tokens)),get(asn1_module),
567		       [got,get_token(hd(Tokens)),expected,
568		       ['SEQUENCE','SEQUENCE SIZE','SET','SET SIZE'],
569		       followed,by,a,constraint]}}).
570
571
572%% --------------------------
573
574parse_ReferencedType(Tokens) ->
575    Flist = [fun parse_DefinedType/1,
576	     fun parse_SelectionType/1,
577	     fun parse_TypeFromObject/1,
578	     fun parse_ValueSetFromObjects/1],
579    case (catch parse_or(Tokens,Flist)) of
580	{'EXIT',Reason} ->
581	    exit(Reason);
582	AsnErr = {asn1_error,_} ->
583	    throw(AsnErr);
584	Result ->
585	    Result
586    end.
587
588parse_DefinedType(Tokens=[{typereference,_,_},{'{',_}|_Rest]) ->
589    parse_ParameterizedType(Tokens);
590parse_DefinedType(Tokens=[{typereference,L1,TypeName},
591			  T2={typereference,_,_},T3={'{',_}|Rest]) ->
592    case (catch parse_ParameterizedType(Tokens)) of
593	{'EXIT',_Reason} ->
594	    Rest2 = [T2,T3|Rest],
595	    {#type{def = #'Externaltypereference'{pos=L1,
596						  module=get(asn1_module),
597						  type=TypeName}},Rest2};
598	{asn1_error,_} ->
599	    Rest2 = [T2,T3|Rest],
600	    {#type{def = #'Externaltypereference'{pos=L1,
601						  module=get(asn1_module),
602						  type=TypeName}},Rest2};
603	Result ->
604	    Result
605    end;
606parse_DefinedType([{typereference,L1,Module},{'.',_},{typereference,_,TypeName}|Rest]) ->
607    {#type{def = #'Externaltypereference'{pos=L1,module=Module,type=TypeName}},Rest};
608parse_DefinedType([{typereference,L1,TypeName}|Rest]) ->
609    {#type{def = #'Externaltypereference'{pos=L1,module=get(asn1_module),
610					  type=TypeName}},Rest};
611parse_DefinedType(Tokens) ->
612    throw({asn1_error,{get_line(hd(Tokens)),get(asn1_module),
613		       [got,get_token(hd(Tokens)),expected,
614			[typereference,'typereference.typereference',
615			 'typereference typereference']]}}).
616
617parse_SelectionType([{identifier,_,Name},{'<',_}|Rest]) ->
618    {Type,Rest2} = parse_Type(Rest),
619    {{'SelectionType',Name,Type},Rest2};
620parse_SelectionType(Tokens) ->
621    throw({asn1_error,{get_line(hd(Tokens)),get(asn1_module),
622		       [got,get_token(hd(Tokens)),expected,'identifier <']}}).
623
624
625%% --------------------------
626
627
628%% This should probably be removed very soon
629% parse_ConstrainedType(Tokens) ->
630%     case (catch parse_TypeWithConstraint(Tokens)) of
631% 	{'EXIT',Reason} ->
632% 	    {Type,Rest} = parse_Type(Tokens),
633% 	    {Constraint,Rest2} = parse_Constraint(Rest),
634% 	    {Type#type{constraint=Constraint},Rest2};
635% 	{asn1_error,Reason2} ->
636% 	    {Type,Rest} = parse_Type(Tokens),
637% 	    {Constraint,Rest2} = parse_Constraint(Rest),
638% 	    {Type#type{constraint=Constraint},Rest2};
639% 	Result ->
640% 	    Result
641%     end.
642
643parse_Constraints(Tokens) ->
644    parse_Constraints(Tokens,[]).
645
646parse_Constraints(Tokens,Acc) ->
647    {Constraint,Rest} = parse_Constraint(Tokens),
648    case Rest of
649	[{'(',_}|_Rest2] ->
650	    parse_Constraints(Rest,[Constraint|Acc]);
651	_ ->
652	    {lists:reverse([Constraint|Acc]),Rest}
653    end.
654
655parse_Constraint([{'(',_}|Rest]) ->
656    {Constraint,Rest2} = parse_ConstraintSpec(Rest),
657    {Exception,Rest3} = parse_ExceptionSpec(Rest2),
658    case Rest3 of
659	[{')',_}|Rest4] ->
660	    {#constraint{c=Constraint,e=Exception},Rest4};
661	[H|_T] ->
662	    throw({asn1_error,{get_line(H),get(asn1_module),
663			       [got,get_token(H),expected,')']}})
664    end;
665parse_Constraint(Tokens) ->
666    throw({asn1_error,{get_line(hd(Tokens)),get(asn1_module),
667		       [got,get_token(hd(Tokens)),expected,'(']}}).
668
669parse_ConstraintSpec(Tokens) ->
670    Flist = [fun parse_GeneralConstraint/1,
671	     fun parse_SubtypeConstraint/1],
672    case (catch parse_or(Tokens,Flist)) of
673	{'EXIT',Reason} ->
674	    exit(Reason);
675	{asn1_error,Reason2} ->
676	    throw({asn1_error,Reason2});
677	Result ->
678	    Result
679    end.
680
681parse_ExceptionSpec([LPar={')',_}|Rest]) ->
682    {undefined,[LPar|Rest]};
683parse_ExceptionSpec([{'!',_}|Rest]) ->
684    parse_ExceptionIdentification(Rest);
685parse_ExceptionSpec(Tokens) ->
686    throw({asn1_error,{get_line(hd(Tokens)),get(asn1_module),
687		       [got,get_token(hd(Tokens)),expected,[')','!']]}}).
688
689parse_ExceptionIdentification(Tokens) ->
690    Flist = [fun parse_SignedNumber/1,
691	     fun parse_DefinedValue/1,
692	     fun parse_TypeColonValue/1],
693    case (catch parse_or(Tokens,Flist)) of
694	{'EXIT',Reason} ->
695	    exit(Reason);
696	{asn1_error,Reason2} ->
697	    throw({asn1_error,Reason2});
698	Result ->
699	    Result
700    end.
701
702parse_TypeColonValue(Tokens) ->
703    {Type,Rest} = parse_Type(Tokens),
704    case Rest of
705	[{':',_}|Rest2] ->
706	    {Value,Rest3} = parse_Value(Rest2),
707	    {{Type,Value},Rest3};
708	[H|_T] ->
709	    throw({asn1_error,{get_line(H),get(asn1_module),
710			       [got,get_token(H),expected,':']}})
711    end.
712
713parse_SubtypeConstraint(Tokens) ->
714    parse_ElementSetSpecs(Tokens).
715
716parse_ElementSetSpecs([{'...',_}|Rest]) ->
717    {Elements,Rest2} = parse_ElementSetSpec(Rest),
718    {{[],Elements},Rest2};
719parse_ElementSetSpecs(Tokens) ->
720    {RootElems,Rest} = parse_ElementSetSpec(Tokens),
721    case Rest of
722	[{',',_},{'...',_},{',',_}|Rest2] ->
723	    {AdditionalElems,Rest3} = parse_ElementSetSpec(Rest2),
724	    {{RootElems,AdditionalElems},Rest3};
725	[{',',_},{'...',_}|Rest2] ->
726	    {{RootElems,[]},Rest2};
727	_ ->
728	    {RootElems,Rest}
729    end.
730
731parse_ElementSetSpec([{'ALL',_},{'EXCEPT',_}|Rest]) ->
732    {Exclusions,Rest2} = parse_Elements(Rest),
733    {{'ALL',{'EXCEPT',Exclusions}},Rest2};
734parse_ElementSetSpec(Tokens) ->
735    parse_Unions(Tokens).
736
737
738parse_Unions(Tokens) ->
739    {InterSec,Rest} = parse_Intersections(Tokens),
740    {Unions,Rest2} = parse_UnionsRec(Rest),
741    case {InterSec,Unions} of
742	{InterSec,[]} ->
743	    {InterSec,Rest2};
744	{{'SingleValue',V1},{'SingleValue',V2}} ->
745	    {{'SingleValue',ordsets:union(to_set(V1),to_set(V2))},Rest2};
746	{V1,V2} when list(V2) ->
747	    {[V1] ++ [union|V2],Rest2};
748	{V1,V2} ->
749	    {[V1,union,V2],Rest2}
750%	Other ->
751%	    throw(Other)
752    end.
753
754parse_UnionsRec([{'|',_}|Rest]) ->
755    {InterSec,Rest2} = parse_Intersections(Rest),
756    {URec,Rest3} = parse_UnionsRec(Rest2),
757    case {InterSec,URec} of
758	{V1,[]} ->
759	    {V1,Rest3};
760	{{'SingleValue',V1},{'SingleValue',V2}} ->
761	    {{'SingleValue',ordsets:union(to_set(V1),to_set(V2))},Rest3};
762	{V1,V2} when list(V2) ->
763	    {[V1] ++ V2,Rest3};
764	{V1,V2} ->
765	    {[V1,V2],Rest3}
766	end;
767parse_UnionsRec([{'UNION',_}|Rest]) ->
768    {InterSec,Rest2} = parse_Intersections(Rest),
769    {URec,Rest3} = parse_UnionsRec(Rest2),
770    case {InterSec,URec} of
771	{V1,[]} ->
772	    {V1,Rest3};
773	{{'SingleValue',V1},{'SingleValue',V2}} ->
774	    {{'SingleValue',ordsets:union(to_set(V1),to_set(V2))},Rest3};
775	{V1,V2} when list(V2) ->
776	    {[V1] ++ V2,Rest3};
777	{V1,V2} ->
778	    {[V1,V2],Rest3}
779	end;
780parse_UnionsRec(Tokens) ->
781    {[],Tokens}.
782
783parse_Intersections(Tokens) ->
784    {InterSec,Rest} = parse_IntersectionElements(Tokens),
785    {IRec,Rest2} = parse_IElemsRec(Rest),
786    case {InterSec,IRec} of
787	{V1,[]} ->
788	    {V1,Rest2};
789	{{'SingleValue',V1},{'SingleValue',V2}} ->
790	    {{'SingleValue',
791	      ordsets:intersection(to_set(V1),to_set(V2))},Rest2};
792	{V1,V2} when list(V2) ->
793	    {[V1] ++ [intersection|V2],Rest2};
794	{V1,V2} ->
795	    {[V1,intersection,V2],Rest2};
796	_ ->
797	    throw({asn1_error,{get_line(hd(Tokens)),get(asn1_module),
798			       [got,get_token(hd(Tokens)),expected,'a Union']}})
799    end.
800
801parse_IElemsRec([{'^',_}|Rest]) ->
802    {InterSec,Rest2} = parse_IntersectionElements(Rest),
803    {IRec,Rest3} = parse_IElemsRec(Rest2),
804    case {InterSec,IRec} of
805	{{'SingleValue',V1},{'SingleValue',V2}} ->
806	    {{'SingleValue',
807	      ordsets:intersection(to_set(V1),to_set(V2))},Rest3};
808	{V1,[]} ->
809	    {V1,Rest3};
810	{V1,V2} when list(V2) ->
811	    {[V1] ++ V2,Rest3};
812	{V1,V2} ->
813	    {[V1,V2],Rest3};
814	_ ->
815	    throw({asn1_error,{get_line(hd(Rest)),get(asn1_module),
816			       [got,get_token(hd(Rest)),expected,'an Intersection']}})
817    end;
818parse_IElemsRec([{'INTERSECTION',_}|Rest]) ->
819    {InterSec,Rest2} = parse_IntersectionElements(Rest),
820    {IRec,Rest3} = parse_IElemsRec(Rest2),
821    case {InterSec,IRec} of
822	{{'SingleValue',V1},{'SingleValue',V2}} ->
823	    {{'SingleValue',
824	      ordsets:intersection(to_set(V1),to_set(V2))},Rest3};
825	{V1,[]} ->
826	    {V1,Rest3};
827	{V1,V2} when list(V2) ->
828	    {[V1] ++ V2,Rest3};
829	{V1,V2} ->
830	    {[V1,V2],Rest3};
831	_ ->
832	    throw({asn1_error,{get_line(hd(Rest)),get(asn1_module),
833			       [got,get_token(hd(Rest)),expected,'an Intersection']}})
834    end;
835parse_IElemsRec(Tokens) ->
836    {[],Tokens}.
837
838parse_IntersectionElements(Tokens) ->
839    {InterSec,Rest} = parse_Elements(Tokens),
840    case Rest of
841	[{'EXCEPT',_}|Rest2] ->
842	    {Exclusion,Rest3} = parse_Elements(Rest2),
843	    {{InterSec,{'EXCEPT',Exclusion}},Rest3};
844	Rest ->
845	    {InterSec,Rest}
846    end.
847
848parse_Elements([{'(',_}|Rest]) ->
849    {Elems,Rest2} = parse_ElementSetSpec(Rest),
850    case Rest2 of
851	[{')',_}|Rest3] ->
852	    {Elems,Rest3};
853	[H|_T] ->
854	    throw({asn1_error,{get_line(H),get(asn1_module),
855			       [got,get_token(H),expected,')']}})
856    end;
857parse_Elements(Tokens) ->
858    Flist = [fun parse_SubtypeElements/1,
859	     fun parse_ObjectSetElements/1],
860    case (catch parse_or(Tokens,Flist)) of
861	{'EXIT',Reason} ->
862	    exit(Reason);
863	Err = {asn1_error,_} ->
864	    throw(Err);
865	Result ->
866	    Result
867    end.
868
869
870
871
872%% --------------------------
873
874parse_DefinedObjectClass([{typereference,_,_ModName},{'.',_},Tr={typereference,_,_ObjClName}|Rest]) ->
875%%    {{objectclassname,ModName,ObjClName},Rest};
876%    {{objectclassname,tref2Exttref(Tr)},Rest};
877    {tref2Exttref(Tr),Rest};
878parse_DefinedObjectClass([Tr={typereference,_,_ObjClName}|Rest]) ->
879%    {{objectclassname,tref2Exttref(Tr)},Rest};
880    {tref2Exttref(Tr),Rest};
881parse_DefinedObjectClass([{'TYPE-IDENTIFIER',_}|Rest]) ->
882    {'TYPE-IDENTIFIER',Rest};
883parse_DefinedObjectClass([{'ABSTRACT-SYNTAX',_}|Rest]) ->
884    {'ABSTRACT-SYNTAX',Rest};
885parse_DefinedObjectClass(Tokens) ->
886    throw({asn1_error,{get_line(hd(Tokens)),get(asn1_module),
887		       [got,get_token(hd(Tokens)),expected,
888			['typereference . typereference',
889			 typereference,
890			 'TYPE-IDENTIFIER',
891			 'ABSTRACT-SYNTAX']]}}).
892
893parse_ObjectClassAssignment([{typereference,L1,ObjClName},{'::=',_}|Rest]) ->
894    {Type,Rest2} = parse_ObjectClass(Rest),
895    {#classdef{pos=L1,name=ObjClName,typespec=Type},Rest2};
896parse_ObjectClassAssignment(Tokens) ->
897    throw({asn1_assignment_error,{get_line(hd(Tokens)),get(asn1_module),
898				  [got,get_token(hd(Tokens)),expected,
899				   'typereference ::=']}}).
900
901parse_ObjectClass(Tokens) ->
902    Flist = [fun parse_DefinedObjectClass/1,
903	     fun parse_ObjectClassDefn/1,
904	     fun parse_ParameterizedObjectClass/1],
905    case (catch parse_or(Tokens,Flist)) of
906	{'EXIT',Reason} ->
907	    exit(Reason);
908	{asn1_error,Reason2} ->
909	    throw({asn1_error,Reason2});
910	Result ->
911	    Result
912    end.
913
914parse_ObjectClassDefn([{'CLASS',_},{'{',_}|Rest]) ->
915    {Type,Rest2} = parse_FieldSpec(Rest),
916    {WithSyntaxSpec,Rest3} = parse_WithSyntaxSpec(Rest2),
917    {#objectclass{fields=Type,syntax=WithSyntaxSpec},Rest3};
918parse_ObjectClassDefn(Tokens) ->
919    throw({asn1_error,{get_line(hd(Tokens)),get(asn1_module),
920		       [got,get_token(hd(Tokens)),expected,'CLASS {']}}).
921
922parse_FieldSpec(Tokens) ->
923    parse_FieldSpec(Tokens,[]).
924
925parse_FieldSpec(Tokens,Acc) ->
926    Flist = [fun parse_FixedTypeValueFieldSpec/1,
927	     fun parse_VariableTypeValueFieldSpec/1,
928	     fun parse_ObjectFieldSpec/1,
929	     fun parse_FixedTypeValueSetFieldSpec/1,
930	     fun parse_VariableTypeValueSetFieldSpec/1,
931	     fun parse_TypeFieldSpec/1,
932	     fun parse_ObjectSetFieldSpec/1],
933    case (catch parse_or(Tokens,Flist)) of
934	{'EXIT',Reason} ->
935	    exit(Reason);
936	AsnErr = {asn1_error,_} ->
937	    throw(AsnErr);
938	{Type,[{'}',_}|Rest]} ->
939	    {lists:reverse([Type|Acc]),Rest};
940	{Type,[{',',_}|Rest2]} ->
941	    parse_FieldSpec(Rest2,[Type|Acc]);
942	{_,[H|_T]}  ->
943	    throw({asn1_error,{get_line(H),get(asn1_module),
944			       [got,get_token(H),expected,'}']}})
945    end.
946
947parse_PrimitiveFieldName([{typefieldreference,_,FieldName}|Rest]) ->
948    {{typefieldreference,FieldName},Rest};
949parse_PrimitiveFieldName([{valuefieldreference,_,FieldName}|Rest]) ->
950    {{valuefieldreference,FieldName},Rest};
951parse_PrimitiveFieldName(Tokens) ->
952    throw({asn1_error,{get_line(hd(Tokens)),get(asn1_module),
953		       [got,get_token(hd(Tokens)),expected,
954			[typefieldreference,valuefieldreference]]}}).
955
956parse_FieldName(Tokens) ->
957    {Field,Rest} = parse_PrimitiveFieldName(Tokens),
958    parse_FieldName(Rest,[Field]).
959
960parse_FieldName([{'.',_}|Rest],Acc) ->
961    case (catch parse_PrimitiveFieldName(Rest)) of
962	{'EXIT',Reason} ->
963	    exit(Reason);
964	AsnErr = {asn1_error,_} ->
965	    throw(AsnErr);
966	{FieldName,Rest2} ->
967	    parse_FieldName(Rest2,[FieldName|Acc])
968    end;
969parse_FieldName(Tokens,Acc) ->
970    {lists:reverse(Acc),Tokens}.
971
972parse_FixedTypeValueFieldSpec([{valuefieldreference,L1,VFieldName}|Rest]) ->
973    {Type,Rest2} = parse_Type(Rest),
974    {Unique,Rest3} =
975	case Rest2 of
976	    [{'UNIQUE',_}|Rest4] ->
977		{'UNIQUE',Rest4};
978	    _  ->
979		{undefined,Rest2}
980	end,
981    {OptionalitySpec,Rest5} = parse_ValueOptionalitySpec(Rest3),
982    case Unique of
983	'UNIQUE' ->
984	    case OptionalitySpec of
985		{'DEFAULT',_} ->
986		    throw({asn1_error,
987			   {L1,get(asn1_module),
988			    ['UNIQUE and DEFAULT in same field',VFieldName]}});
989		_ ->
990		    {{fixedtypevaluefield,VFieldName,Type,Unique,OptionalitySpec},Rest5}
991	    end;
992	_ ->
993	    {{object_or_fixedtypevalue_field,VFieldName,Type,Unique,OptionalitySpec},Rest5}
994    end;
995parse_FixedTypeValueFieldSpec(Tokens) ->
996    throw({asn1_error,{get_line(hd(Tokens)),get(asn1_module),
997		       [got,get_token(hd(Tokens)),expected,valuefieldreference]}}).
998
999parse_VariableTypeValueFieldSpec([{valuefieldreference,_,VFieldName}|Rest]) ->
1000    {FieldRef,Rest2} = parse_FieldName(Rest),
1001    {OptionalitySpec,Rest3} = parse_ValueOptionalitySpec(Rest2),
1002    {{variabletypevaluefield,VFieldName,FieldRef,OptionalitySpec},Rest3};
1003parse_VariableTypeValueFieldSpec(Tokens) ->
1004    throw({asn1_error,{get_line(hd(Tokens)),get(asn1_module),
1005		       [got,get_token(hd(Tokens)),expected,valuefieldreference]}}).
1006
1007parse_ObjectFieldSpec([{valuefieldreference,_,VFieldName}|Rest]) ->
1008    {Class,Rest2} = parse_DefinedObjectClass(Rest),
1009    {OptionalitySpec,Rest3} = parse_ObjectOptionalitySpec(Rest2),
1010    {{objectfield,VFieldName,Class,OptionalitySpec},Rest3};
1011parse_ObjectFieldSpec(Tokens) ->
1012    throw({asn1_error,{get_line(hd(Tokens)),get(asn1_module),
1013		       [got,get_token(hd(Tokens)),expected,valuefieldreference]}}).
1014
1015parse_TypeFieldSpec([{typefieldreference,_,TFieldName}|Rest]) ->
1016    {OptionalitySpec,Rest2} = parse_TypeOptionalitySpec(Rest),
1017    {{typefield,TFieldName,OptionalitySpec},Rest2};
1018parse_TypeFieldSpec(Tokens) ->
1019    throw({asn1_error,{get_line(hd(Tokens)),get(asn1_module),
1020		       [got,get_token(hd(Tokens)),expected,typefieldreference]}}).
1021
1022parse_FixedTypeValueSetFieldSpec([{typefieldreference,_,TFieldName}|Rest]) ->
1023    {Type,Rest2} = parse_Type(Rest),
1024    {OptionalitySpec,Rest3} = parse_ValueSetOptionalitySpec(Rest2),
1025    {{objectset_or_fixedtypevalueset_field,TFieldName,Type,
1026      OptionalitySpec},Rest3};
1027parse_FixedTypeValueSetFieldSpec(Tokens) ->
1028    throw({asn1_error,{get_line(hd(Tokens)),get(asn1_module),
1029		       [got,get_token(hd(Tokens)),expected,typefieldreference]}}).
1030
1031parse_VariableTypeValueSetFieldSpec([{typefieldreference,_,TFieldName}|Rest]) ->
1032    {FieldRef,Rest2} = parse_FieldName(Rest),
1033    {OptionalitySpec,Rest3} = parse_ValueSetOptionalitySpec(Rest2),
1034    {{variabletypevaluesetfield,TFieldName,FieldRef,OptionalitySpec},Rest3};
1035parse_VariableTypeValueSetFieldSpec(Tokens) ->
1036    throw({asn1_error,{get_line(hd(Tokens)),get(asn1_module),
1037		       [got,get_token(hd(Tokens)),expected,typefieldreference]}}).
1038
1039parse_ObjectSetFieldSpec([{typefieldreference,_,TFieldName}|Rest]) ->
1040    {Class,Rest2} = parse_DefinedObjectClass(Rest),
1041    {OptionalitySpec,Rest3} = parse_ObjectSetOptionalitySpec(Rest2),
1042    {{objectsetfield,TFieldName,Class,OptionalitySpec},Rest3};
1043parse_ObjectSetFieldSpec(Tokens) ->
1044    throw({asn1_error,{get_line(hd(Tokens)),get(asn1_module),
1045		       [got,get_token(hd(Tokens)),expected,typefieldreference]}}).
1046
1047parse_ValueOptionalitySpec(Tokens)->
1048    case Tokens of
1049	[{'OPTIONAL',_}|Rest] -> {'OPTIONAL',Rest};
1050	[{'DEFAULT',_}|Rest] ->
1051	    {Value,Rest2} = parse_Value(Rest),
1052	    {{'DEFAULT',Value},Rest2};
1053	_  -> {'MANDATORY',Tokens}
1054    end.
1055
1056parse_ObjectOptionalitySpec(Tokens) ->
1057    case Tokens of
1058	[{'OPTIONAL',_}|Rest] -> {'OPTIONAL',Rest};
1059	[{'DEFAULT',_}|Rest] ->
1060	    {Object,Rest2} = parse_Object(Rest),
1061	    {{'DEFAULT',Object},Rest2};
1062	_  -> {'MANDATORY',Tokens}
1063    end.
1064
1065parse_TypeOptionalitySpec(Tokens) ->
1066    case Tokens of
1067	[{'OPTIONAL',_}|Rest] -> {'OPTIONAL',Rest};
1068	[{'DEFAULT',_}|Rest] ->
1069	    {Type,Rest2} = parse_Type(Rest),
1070	    {{'DEFAULT',Type},Rest2};
1071	_  -> {'MANDATORY',Tokens}
1072    end.
1073
1074parse_ValueSetOptionalitySpec(Tokens) ->
1075    case Tokens of
1076	[{'OPTIONAL',_}|Rest] -> {'OPTIONAL',Rest};
1077	[{'DEFAULT',_}|Rest] ->
1078	    {ValueSet,Rest2} = parse_ValueSet(Rest),
1079	    {{'DEFAULT',ValueSet},Rest2};
1080	_  -> {'MANDATORY',Tokens}
1081    end.
1082
1083parse_ObjectSetOptionalitySpec(Tokens) ->
1084        case Tokens of
1085	[{'OPTIONAL',_}|Rest] -> {'OPTIONAL',Rest};
1086	[{'DEFAULT',_}|Rest] ->
1087	    {ObjectSet,Rest2} = parse_ObjectSet(Rest),
1088	    {{'DEFAULT',ObjectSet},Rest2};
1089	_  -> {'MANDATORY',Tokens}
1090    end.
1091
1092parse_WithSyntaxSpec([{'WITH',_},{'SYNTAX',_}|Rest]) ->
1093    {SyntaxList,Rest2} = parse_SyntaxList(Rest),
1094    {{'WITH SYNTAX',SyntaxList},Rest2};
1095parse_WithSyntaxSpec(Tokens) ->
1096    {[],Tokens}.
1097
1098parse_SyntaxList([{'{',_},{'}',_}|Rest]) ->
1099    {[],Rest};
1100parse_SyntaxList([{'{',_}|Rest]) ->
1101    parse_SyntaxList(Rest,[]);
1102parse_SyntaxList(Tokens) ->
1103    throw({asn1_error,{get_line(hd(Tokens)),get(asn1_module),
1104		       [got,get_token(hd(Tokens)),expected,['{}','{']]}}).
1105
1106parse_SyntaxList(Tokens,Acc) ->
1107    {SyntaxList,Rest} = parse_TokenOrGroupSpec(Tokens),
1108    case Rest of
1109	[{'}',_}|Rest2] ->
1110	    {lists:reverse([SyntaxList|Acc]),Rest2};
1111	_ ->
1112	    parse_SyntaxList(Rest,[SyntaxList|Acc])
1113    end.
1114
1115parse_TokenOrGroupSpec(Tokens) ->
1116    Flist = [fun parse_RequiredToken/1,
1117	     fun parse_OptionalGroup/1],
1118    case (catch parse_or(Tokens,Flist)) of
1119	{'EXIT',Reason} ->
1120	    exit(Reason);
1121	AsnErr = {asn1_error,_} ->
1122	    throw(AsnErr);
1123	Result ->
1124	    Result
1125    end.
1126
1127parse_RequiredToken([{typereference,L1,WordName}|Rest]) ->
1128    case is_word(WordName) of
1129	false ->
1130	    throw({asn1_error,{L1,get(asn1_module),
1131			       [got,WordName,expected,a,'Word']}});
1132	true ->
1133	    {WordName,Rest}
1134    end;
1135parse_RequiredToken([{',',L1}|Rest]) ->
1136    {{',',L1},Rest};
1137parse_RequiredToken([{WordName,L1}|Rest]) ->
1138    case is_word(WordName) of
1139	false ->
1140	    throw({asn1_error,{L1,get(asn1_module),
1141			       [got,WordName,expected,a,'Word']}});
1142	true ->
1143	    {WordName,Rest}
1144    end;
1145parse_RequiredToken(Tokens) ->
1146    parse_PrimitiveFieldName(Tokens).
1147
1148parse_OptionalGroup([{'[',_}|Rest]) ->
1149    {Spec,Rest2} = parse_TokenOrGroupSpec(Rest),
1150    {SpecList,Rest3} = parse_OptionalGroup(Rest2,[Spec]),
1151    {SpecList,Rest3}.
1152
1153parse_OptionalGroup([{']',_}|Rest],Acc) ->
1154    {lists:reverse(Acc),Rest};
1155parse_OptionalGroup(Tokens,Acc) ->
1156    {Spec,Rest} = parse_TokenOrGroupSpec(Tokens),
1157    parse_OptionalGroup(Rest,[Spec|Acc]).
1158
1159parse_DefinedObject([Id={identifier,_,_ObjName}|Rest]) ->
1160    {{object,identifier2Extvalueref(Id)},Rest};
1161parse_DefinedObject([{typereference,L1,ModName},{'.',_},{identifier,_,ObjName}|Rest]) ->
1162    {{object, #'Externaltypereference'{pos=L1,module=ModName,type=ObjName}},Rest};
1163parse_DefinedObject(Tokens) ->
1164    throw({asn1_error,{get_line(hd(Tokens)),get(asn1_module),
1165		       [got,get_token(hd(Tokens)),expected,
1166		       [identifier,'typereference.identifier']]}}).
1167
1168parse_ObjectAssignment([{identifier,L1,ObjName}|Rest]) ->
1169    {Class,Rest2} = parse_DefinedObjectClass(Rest),
1170    case Rest2 of
1171	[{'::=',_}|Rest3] ->
1172	    {Object,Rest4} = parse_Object(Rest3),
1173	    {#typedef{pos=L1,name=ObjName,
1174		      typespec=#'Object'{classname=Class,def=Object}},Rest4};
1175	[H|_T]  ->
1176	    throw({asn1_error,{get_line(H),get(asn1_module),
1177			       [got,get_token(H),expected,'::=']}});
1178	Other ->
1179	    throw({asn1_error,{L1,get(asn1_module),
1180			       [got,Other,expected,'::=']}})
1181    end;
1182parse_ObjectAssignment(Tokens) ->
1183    throw({asn1_assignment_error,{get_line(hd(Tokens)),get(asn1_module),
1184				  [got,get_token(hd(Tokens)),expected,identifier]}}).
1185
1186parse_Object(Tokens) ->
1187    Flist=[fun parse_ObjectDefn/1,
1188	   fun parse_ObjectFromObject/1,
1189	   fun parse_ParameterizedObject/1,
1190	   fun parse_DefinedObject/1],
1191    case (catch parse_or(Tokens,Flist)) of
1192	{'EXIT',Reason} ->
1193	    exit(Reason);
1194	AsnErr = {asn1_error,_} ->
1195	    throw(AsnErr);
1196	Result ->
1197	    Result
1198    end.
1199
1200parse_ObjectDefn(Tokens) ->
1201    Flist=[fun parse_DefaultSyntax/1,
1202	   fun parse_DefinedSyntax/1],
1203    case (catch parse_or(Tokens,Flist)) of
1204	{'EXIT',Reason} ->
1205	    exit(Reason);
1206	AsnErr = {asn1_error,_} ->
1207	    throw(AsnErr);
1208	Result ->
1209	    Result
1210    end.
1211
1212parse_DefaultSyntax([{'{',_},{'}',_}|Rest]) ->
1213    {{object,defaultsyntax,[]},Rest};
1214parse_DefaultSyntax([{'{',_}|Rest]) ->
1215    parse_DefaultSyntax(Rest,[]);
1216parse_DefaultSyntax(Tokens) ->
1217    throw({asn1_error,{get_line(hd(Tokens)),get(asn1_module),
1218		       [got,get_token(hd(Tokens)),expected,['{}','{']]}}).
1219
1220parse_DefaultSyntax(Tokens,Acc) ->
1221    {Setting,Rest} = parse_FieldSetting(Tokens),
1222    case Rest of
1223	[{',',_}|Rest2] ->
1224	    parse_DefaultSyntax(Rest2,[Setting|Acc]);
1225	[{'}',_}|Rest3] ->
1226	    {{object,defaultsyntax,lists:reverse([Setting|Acc])},Rest3};
1227	[H|_T] ->
1228	    throw({asn1_error,{get_line(H),get(asn1_module),
1229			       [got,get_token(H),expected,[',','}']]}})
1230    end.
1231
1232parse_FieldSetting(Tokens) ->
1233    {{_,PrimFieldName},Rest} = parse_PrimitiveFieldName(Tokens),
1234    {Setting,Rest2} = parse_Setting(Rest),
1235    {{PrimFieldName,Setting},Rest2}.
1236
1237parse_DefinedSyntax([{'{',_}|Rest]) ->
1238    parse_DefinedSyntax(Rest,[]).
1239
1240parse_DefinedSyntax(Tokens,Acc) ->
1241    case Tokens of
1242	[{'}',_}|Rest2] ->
1243	    {{object,definedsyntax,lists:reverse(Acc)},Rest2};
1244	_ ->
1245	    {DefSynTok,Rest3} = parse_DefinedSyntaxToken(Tokens),
1246	    parse_DefinedSyntax(Rest3,[DefSynTok|Acc])
1247    end.
1248
1249parse_DefinedSyntaxToken([{',',L1}|Rest]) ->
1250    {{',',L1},Rest};
1251parse_DefinedSyntaxToken([{typereference,L1,Name}|Rest]) ->
1252    case is_word(Name) of
1253	false ->
1254	    {{setting,L1,Name},Rest};
1255	true ->
1256	    {{word_or_setting,L1,Name},Rest}
1257    end;
1258parse_DefinedSyntaxToken(Tokens) ->
1259    case catch parse_Setting(Tokens) of
1260	{asn1_error,_} ->
1261	    parse_Word(Tokens);
1262	{'EXIT',Reason} ->
1263	    exit(Reason);
1264	Result ->
1265	    Result
1266    end.
1267
1268parse_Word([{Name,Pos}|Rest]) ->
1269    case is_word(Name) of
1270	false ->
1271	    throw({asn1_error,{Pos,get(asn1_module),
1272			       [got,Name, expected,a,'Word']}});
1273	true ->
1274	    {{word_or_setting,Pos,Name},Rest}
1275    end.
1276
1277parse_Setting(Tokens) ->
1278    Flist = [fun parse_Type/1,
1279	     fun parse_Value/1,
1280	     fun parse_Object/1,
1281	     fun parse_ObjectSet/1],
1282    case (catch parse_or(Tokens,Flist)) of
1283	{'EXIT',Reason} ->
1284	    exit(Reason);
1285	AsnErr = {asn1_error,_} ->
1286	    throw(AsnErr);
1287	Result ->
1288	    Result
1289    end.
1290
1291parse_DefinedObjectSet([{typereference,L1,ModuleName},{'.',_},
1292			{typereference,L2,ObjSetName}|Rest]) ->
1293    {{objectset,L1,#'Externaltypereference'{pos=L2,module=ModuleName,
1294					    type=ObjSetName}},Rest};
1295parse_DefinedObjectSet([{typereference,L1,ObjSetName}|Rest]) ->
1296    {{objectset,L1,#'Externaltypereference'{pos=L1,module=get(asn1_module),
1297					    type=ObjSetName}},Rest};
1298parse_DefinedObjectSet(Tokens) ->
1299    throw({asn1_error,{get_line(hd(Tokens)),get(asn1_module),
1300		       [got,get_token(hd(Tokens)),expected,
1301			[typereference,'typereference.typereference']]}}).
1302
1303parse_ObjectSetAssignment([{typereference,L1,ObjSetName}|Rest]) ->
1304    {Class,Rest2} = parse_DefinedObjectClass(Rest),
1305    case Rest2 of
1306	[{'::=',_}|Rest3] ->
1307	    {ObjectSet,Rest4} = parse_ObjectSet(Rest3),
1308	    {#typedef{pos=L1,name=ObjSetName,
1309		      typespec=#'ObjectSet'{class=Class,
1310					    set=ObjectSet}},Rest4};
1311	[H|_T]  ->
1312	    throw({asn1_error,{get_line(H),get(asn1_module),
1313			       [got,get_token(H),expected,'::=']}})
1314%%%	Other ->
1315%%%	    throw(Other)
1316    end;
1317parse_ObjectSetAssignment(Tokens) ->
1318    throw({asn1_assignment_error,{get_line(hd(Tokens)),get(asn1_module),
1319				  [got,get_token(hd(Tokens)),expected,
1320				   typereference]}}).
1321
1322parse_ObjectSet([{'{',_}|Rest]) ->
1323    {ObjSetSpec,Rest2} = parse_ObjectSetSpec(Rest),
1324    case Rest2 of
1325	[{'}',_}|Rest3] ->
1326	    {ObjSetSpec,Rest3};
1327	[H|_T] ->
1328	    throw({asn1_error,{get_line(H),get(asn1_module),
1329			       [got,get_token(H),expected,'}']}})
1330    end;
1331parse_ObjectSet(Tokens) ->
1332    throw({asn1_error,{get_line(hd(Tokens)),get(asn1_module),
1333		       [got,get_token(hd(Tokens)),expected,'{']}}).
1334
1335parse_ObjectSetSpec([{'...',_}|Rest]) ->
1336    {['EXTENSIONMARK'],Rest};
1337parse_ObjectSetSpec(Tokens) ->
1338    parse_ElementSetSpecs(Tokens).
1339
1340parse_ObjectSetElements(Tokens) ->
1341    Flist = [fun parse_Object/1,
1342	     fun parse_DefinedObjectSet/1,
1343	     fun parse_ObjectSetFromObjects/1,
1344	     fun parse_ParameterizedObjectSet/1],
1345    case (catch parse_or(Tokens,Flist)) of
1346	{'EXIT',Reason} ->
1347	    exit(Reason);
1348	AsnErr = {asn1_error,_} ->
1349	    throw(AsnErr);
1350	Result ->
1351	    Result
1352    end.
1353
1354parse_ObjectClassFieldType(Tokens) ->
1355    {Class,Rest} = parse_DefinedObjectClass(Tokens),
1356    case Rest of
1357	[{'.',_}|Rest2] ->
1358	    {FieldName,Rest3} = parse_FieldName(Rest2),
1359	    OCFT = #'ObjectClassFieldType'{
1360	      classname=Class,
1361	      class=Class,fieldname=FieldName},
1362	    {#type{def=OCFT},Rest3};
1363	[H|_T] ->
1364	    throw({asn1_error,{get_line(H),get(asn1_module),
1365			       [got,get_token(H),expected,'.']}})
1366%%%	Other ->
1367%%%	    throw(Other)
1368    end.
1369
1370%parse_ObjectClassFieldValue(Tokens) ->
1371%    Flist = [fun parse_OpenTypeFieldVal/1,
1372%	     fun parse_FixedTypeFieldVal/1],
1373%    case (catch parse_or(Tokens,Flist)) of
1374%	{'EXIT',Reason} ->
1375%	    throw(Reason);
1376%	AsnErr = {asn1_error,_} ->
1377%	    throw(AsnErr);
1378%	Result ->
1379%	    Result
1380%    end.
1381
1382parse_ObjectClassFieldValue(Tokens) ->
1383    parse_OpenTypeFieldVal(Tokens).
1384
1385parse_OpenTypeFieldVal(Tokens) ->
1386    {Type,Rest} = parse_Type(Tokens),
1387    case Rest of
1388	[{':',_}|Rest2] ->
1389	    {Value,Rest3} = parse_Value(Rest2),
1390	    {{opentypefieldvalue,Type,Value},Rest3};
1391	[H|_T] ->
1392	    throw({asn1_error,{get_line(H),get(asn1_module),
1393			       [got,get_token(H),expected,':']}})
1394    end.
1395
1396% parse_FixedTypeFieldVal(Tokens) ->
1397%     parse_Value(Tokens).
1398
1399% parse_InformationFromObjects(Tokens) ->
1400%     Flist = [fun parse_ValueFromObject/1,
1401% 	     fun parse_ValueSetFromObjects/1,
1402% 	     fun parse_TypeFromObject/1,
1403% 	     fun parse_ObjectFromObject/1],
1404%     case (catch parse_or(Tokens,Flist)) of
1405% 	{'EXIT',Reason} ->
1406% 	    throw(Reason);
1407% 	AsnErr = {asn1_error,_} ->
1408% 	    throw(AsnErr);
1409% 	Result ->
1410% 	    Result
1411%     end.
1412
1413parse_ReferencedObjects(Tokens) ->
1414    Flist = [fun parse_DefinedObject/1,
1415	     fun parse_DefinedObjectSet/1,
1416	     fun parse_ParameterizedObject/1,
1417	     fun parse_ParameterizedObjectSet/1],
1418        case (catch parse_or(Tokens,Flist)) of
1419	{'EXIT',Reason} ->
1420	    exit(Reason);
1421	AsnErr = {asn1_error,_} ->
1422	    throw(AsnErr);
1423	Result ->
1424	    Result
1425    end.
1426
1427parse_ValueFromObject(Tokens) ->
1428    {Objects,Rest} = parse_ReferencedObjects(Tokens),
1429    case Rest of
1430	[{'.',_}|Rest2] ->
1431	    {Name,Rest3} = parse_FieldName(Rest2),
1432	    case lists:last(Name) of
1433		{valuefieldreference,_} ->
1434		    {{'ValueFromObject',Objects,Name},Rest3};
1435		_ ->
1436		    throw({asn1_error,{get_line(hd(Tokens)),get(asn1_module),
1437				       [got,typefieldreference,expected,
1438					valuefieldreference]}})
1439	    end;
1440	[H|_T] ->
1441	    throw({asn1_error,{get_line(H),get(asn1_module),
1442			       [got,get_token(H),expected,'.']}})
1443%%%	Other ->
1444%%%	    throw({asn1_error,{got,Other,expected,'.'}})
1445    end.
1446
1447parse_ValueSetFromObjects(Tokens) ->
1448    {Objects,Rest} = parse_ReferencedObjects(Tokens),
1449    case Rest of
1450	[{'.',_}|Rest2] ->
1451	    {Name,Rest3} = parse_FieldName(Rest2),
1452	    case lists:last(Name) of
1453		{typefieldreference,_FieldName} ->
1454		    {{'ValueSetFromObjects',Objects,Name},Rest3};
1455		_ ->
1456		    throw({asn1_error,{get_line(hd(Rest2)),get(asn1_module),
1457				       [got,get_token(hd(Rest2)),expected,
1458					typefieldreference]}})
1459	    end;
1460	[H|_T] ->
1461	    throw({asn1_error,{get_line(H),get(asn1_module),
1462			       [got,get_token(H),expected,'.']}})
1463%%%	Other ->
1464%%%	    throw({asn1_error,{got,Other,expected,'.'}})
1465    end.
1466
1467parse_TypeFromObject(Tokens) ->
1468    {Objects,Rest} = parse_ReferencedObjects(Tokens),
1469    case Rest of
1470	[{'.',_}|Rest2] ->
1471	    {Name,Rest3} = parse_FieldName(Rest2),
1472	    case lists:last(Name) of
1473		{typefieldreference,_FieldName} ->
1474		    {{'TypeFromObject',Objects,Name},Rest3};
1475		_ ->
1476		    throw({asn1_error,{get_line(hd(Rest2)),get(asn1_module),
1477				       [got,get_token(hd(Rest2)),expected,
1478					typefieldreference]}})
1479	    end;
1480	[H|_T] ->
1481	    throw({asn1_error,{get_line(H),get(asn1_module),
1482			       [got,get_token(H),expected,'.']}})
1483%%%	Other ->
1484%%%	    throw({asn1_error,{got,Other,expected,'.'}})
1485    end.
1486
1487parse_ObjectFromObject(Tokens) ->
1488    {Objects,Rest} = parse_ReferencedObjects(Tokens),
1489    case Rest of
1490	[{'.',_}|Rest2] ->
1491	    {Name,Rest3} = parse_FieldName(Rest2),
1492	    {{'ObjectFromObject',Objects,Name},Rest3};
1493	[H|_T] ->
1494	    throw({asn1_error,{get_line(H),get(asn1_module),
1495			       [got,get_token(H),expected,'.']}})
1496%%%	Other ->
1497%%%	    throw({asn1_error,{got,Other,expected,'.'}})
1498    end.
1499
1500parse_ObjectSetFromObjects(Tokens) ->
1501    {Objects,Rest} = parse_ReferencedObjects(Tokens),
1502    case Rest of
1503	[{'.',_}|Rest2] ->
1504	    {Name,Rest3} = parse_FieldName(Rest2),
1505	    {{'ObjectSetFromObjects',Objects,Name},Rest3};
1506	[H|_T] ->
1507	    throw({asn1_error,{get_line(H),get(asn1_module),
1508			       [got,get_token(H),expected,'.']}})
1509%%%	Other ->
1510%%%	    throw({asn1_error,{got,Other,expected,'.'}})
1511    end.
1512
1513% parse_InstanceOfType([{'INSTANCE',_},{'OF',_}|Rest]) ->
1514%     {Class,Rest2} = parse_DefinedObjectClass(Rest),
1515%     {{'InstanceOfType',Class},Rest2}.
1516
1517% parse_InstanceOfValue(Tokens) ->
1518%     parse_Value(Tokens).
1519
1520
1521
1522%% X.682 constraint specification
1523
1524parse_GeneralConstraint(Tokens) ->
1525    Flist = [fun parse_UserDefinedConstraint/1,
1526	     fun parse_TableConstraint/1],
1527    case (catch parse_or(Tokens,Flist)) of
1528	{'EXIT',Reason} ->
1529	    exit(Reason);
1530	AsnErr = {asn1_error,_} ->
1531	    throw(AsnErr);
1532	Result ->
1533	    Result
1534    end.
1535
1536parse_UserDefinedConstraint([{'CONSTRAINED',_},{'BY',_},{'{',_},{'}',_}|Rest])->
1537    {{constrained_by,[]},Rest};
1538parse_UserDefinedConstraint([{'CONSTRAINED',_},
1539			     {'BY',_},
1540			     {'{',_}|Rest]) ->
1541    {Param,Rest2} = parse_UserDefinedConstraintParameter(Rest),
1542    case Rest2 of
1543	[{'}',_}|Rest3] ->
1544	    {{constrained_by,Param},Rest3};
1545	[H|_T] ->
1546	    throw({asn1_error,{get_line(H),get(asn1_module),
1547			       [got,get_token(H),expected,'}']}})
1548    end;
1549parse_UserDefinedConstraint(Tokens) ->
1550    throw({asn1_error,{get_line(hd(Tokens)),get(asn1_module),
1551		       [got,get_token(hd(Tokens)),expected,
1552			['CONSTRAINED BY {}','CONSTRAINED BY {']]}}).
1553
1554parse_UserDefinedConstraintParameter(Tokens) ->
1555    parse_UserDefinedConstraintParameter(Tokens,[]).
1556parse_UserDefinedConstraintParameter(Tokens,Acc) ->
1557    Flist = [fun parse_GovernorAndActualParameter/1,
1558	     fun parse_ActualParameter/1],
1559    case (catch parse_or(Tokens,Flist)) of
1560	{'EXIT',Reason} ->
1561	    exit(Reason);
1562	AsnErr = {asn1_error,_} ->
1563	    throw(AsnErr);
1564	{Result,Rest} ->
1565	    case Rest of
1566		[{',',_}|_Rest2] ->
1567		    parse_UserDefinedConstraintParameter(Tokens,[Result|Acc]);
1568		_  ->
1569		    {lists:reverse([Result|Acc]),Rest}
1570	    end
1571    end.
1572
1573parse_GovernorAndActualParameter(Tokens) ->
1574    {Governor,Rest} = parse_Governor(Tokens),
1575    case Rest of
1576	[{':',_}|Rest2] ->
1577	    {Params,Rest3} = parse_ActualParameter(Rest2),
1578	    {{'Governor_Params',Governor,Params},Rest3};
1579	[H|_T] ->
1580	    throw({asn1_error,{get_line(H),get(asn1_module),
1581			       [got,get_token(H),expected,':']}})
1582    end.
1583
1584parse_TableConstraint(Tokens) ->
1585    Flist = [fun parse_ComponentRelationConstraint/1,
1586	     fun parse_SimpleTableConstraint/1],
1587    case (catch parse_or(Tokens,Flist)) of
1588	{'EXIT',Reason} ->
1589	    exit(Reason);
1590	AsnErr = {asn1_error,_} ->
1591	    throw(AsnErr);
1592	Result ->
1593	    Result
1594    end.
1595
1596parse_SimpleTableConstraint(Tokens) ->
1597    {ObjectSet,Rest} = parse_ObjectSet(Tokens),
1598    {{simpletable,ObjectSet},Rest}.
1599
1600parse_ComponentRelationConstraint([{'{',_}|Rest]) ->
1601    {ObjectSet,Rest2} = parse_DefinedObjectSet(Rest),
1602    case Rest2 of
1603	[{'}',_},{'{',_}|Rest3] ->
1604	    {AtNot,Rest4} = parse_AtNotationList(Rest3,[]),
1605	    case Rest4 of
1606		[{'}',_}|Rest5] ->
1607		    {{componentrelation,ObjectSet,AtNot},Rest5};
1608		[H|_T]  ->
1609		    throw({asn1_error,{get_line(H),get(asn1_module),
1610				       [got,get_token(H),expected,'}']}})
1611	    end;
1612	[H|_T]  ->
1613	    throw({asn1_error,{get_line(H),get(asn1_module),
1614			       [got,get_token(H),expected,
1615				'ComponentRelationConstraint',ended,with,'}']}})
1616%%%	Other ->
1617%%%	    throw(Other)
1618    end;
1619parse_ComponentRelationConstraint(Tokens) ->
1620    throw({asn1_error,{get_line(hd(Tokens)),get(asn1_module),
1621		       [got,get_token(hd(Tokens)),expected,'{']}}).
1622
1623parse_AtNotationList(Tokens,Acc) ->
1624    {AtNot,Rest} = parse_AtNotation(Tokens),
1625    case Rest of
1626	[{',',_}|Rest2] ->
1627	    parse_AtNotationList(Rest2,[AtNot|Acc]);
1628	_  ->
1629	    {lists:reverse([AtNot|Acc]),Rest}
1630    end.
1631
1632parse_AtNotation([{'@',_},{'.',_}|Rest]) ->
1633    {CIdList,Rest2} = parse_ComponentIdList(Rest),
1634    {{innermost,CIdList},Rest2};
1635parse_AtNotation([{'@',_}|Rest]) ->
1636    {CIdList,Rest2} = parse_ComponentIdList(Rest),
1637    {{outermost,CIdList},Rest2};
1638parse_AtNotation(Tokens) ->
1639    throw({asn1_error,{get_line(hd(Tokens)),get(asn1_module),
1640		       [got,get_token(hd(Tokens)),expected,['@','@.']]}}).
1641
1642parse_ComponentIdList(Tokens) ->
1643    parse_ComponentIdList(Tokens,[]).
1644
1645parse_ComponentIdList([Id = {identifier,_,_},{'.',_}|Rest],Acc) ->
1646    parse_ComponentIdList(Rest,[identifier2Extvalueref(Id)|Acc]);
1647parse_ComponentIdList([Id = {identifier,_,_}|Rest],Acc) ->
1648    {lists:reverse([identifier2Extvalueref(Id)|Acc]),Rest};
1649parse_ComponentIdList(Tokens,_) ->
1650    throw({asn1_error,{get_line(hd(Tokens)),get(asn1_module),
1651		       [got,get_token(hd(Tokens)),expected,
1652			[identifier,'identifier.']]}}).
1653
1654
1655
1656
1657
1658% X.683 Parameterization of ASN.1 specifications
1659
1660parse_Governor(Tokens) ->
1661    Flist = [fun parse_Type/1,
1662	     fun parse_DefinedObjectClass/1],
1663    case (catch parse_or(Tokens,Flist)) of
1664	{'EXIT',Reason} ->
1665	    exit(Reason);
1666	AsnErr = {asn1_error,_} ->
1667	    throw(AsnErr);
1668	Result ->
1669	    Result
1670    end.
1671
1672parse_ActualParameter(Tokens) ->
1673    Flist = [fun parse_Type/1,
1674	     fun parse_Value/1,
1675	     fun parse_ValueSet/1,
1676	     fun parse_DefinedObjectClass/1,
1677	     fun parse_Object/1,
1678	     fun parse_ObjectSet/1],
1679    case (catch parse_or(Tokens,Flist)) of
1680	{'EXIT',Reason} ->
1681	    exit(Reason);
1682	AsnErr = {asn1_error,_} ->
1683	    throw(AsnErr);
1684	Result ->
1685	    Result
1686    end.
1687
1688parse_ParameterizedAssignment(Tokens) ->
1689    Flist = [fun parse_ParameterizedTypeAssignment/1,
1690	     fun parse_ParameterizedValueAssignment/1,
1691	     fun parse_ParameterizedValueSetTypeAssignment/1,
1692	     fun parse_ParameterizedObjectClassAssignment/1,
1693	     fun parse_ParameterizedObjectAssignment/1,
1694	     fun parse_ParameterizedObjectSetAssignment/1],
1695    case (catch parse_or(Tokens,Flist)) of
1696	{'EXIT',Reason} ->
1697	    exit(Reason);
1698	AsnErr = {asn1_error,_} ->
1699	    throw(AsnErr);
1700	AsnAssErr = {asn1_assignment_error,_} ->
1701	    throw(AsnAssErr);
1702	Result ->
1703	    Result
1704    end.
1705
1706parse_ParameterizedTypeAssignment([{typereference,L1,Name}|Rest]) ->
1707    {ParameterList,Rest2} = parse_ParameterList(Rest),
1708    case Rest2 of
1709	[{'::=',_}|Rest3] ->
1710	    {Type,Rest4} = parse_Type(Rest3),
1711	    {#ptypedef{pos=L1,name=Name,args=ParameterList,typespec=Type},
1712	     Rest4};
1713	[H|_T] ->
1714	    throw({asn1_error,{get_line(H),get(asn1_module),
1715			       [got,get_token(H),expected,'::=']}})
1716    end;
1717parse_ParameterizedTypeAssignment(Tokens) ->
1718    throw({asn1_assignment_error,{get_line(hd(Tokens)),get(asn1_module),
1719				  [got,get_token(hd(Tokens)),expected,
1720				   typereference]}}).
1721
1722parse_ParameterizedValueAssignment([{identifier,L1,Name}|Rest]) ->
1723    {ParameterList,Rest2} = parse_ParameterList(Rest),
1724    {Type,Rest3} = parse_Type(Rest2),
1725    case Rest3 of
1726	[{'::=',_}|Rest4] ->
1727	    {Value,Rest5} = parse_Value(Rest4),
1728	    {#pvaluedef{pos=L1,name=Name,args=ParameterList,type=Type,
1729			 value=Value},Rest5};
1730	[H|_T] ->
1731	    throw({asn1_error,{get_line(H),get(asn1_module),
1732			       [got,get_token(H),expected,'::=']}})
1733    end;
1734parse_ParameterizedValueAssignment(Tokens) ->
1735    throw({asn1_assignment_error,{get_line(hd(Tokens)),get(asn1_module),
1736				  [got,get_token(hd(Tokens)),expected,identifier]}}).
1737
1738parse_ParameterizedValueSetTypeAssignment([{typereference,L1,Name}|Rest]) ->
1739    {ParameterList,Rest2} = parse_ParameterList(Rest),
1740    {Type,Rest3} = parse_Type(Rest2),
1741    case Rest3 of
1742	[{'::=',_}|Rest4] ->
1743	    {ValueSet,Rest5} = parse_ValueSet(Rest4),
1744	    {#pvaluesetdef{pos=L1,name=Name,args=ParameterList,
1745			   type=Type,valueset=ValueSet},Rest5};
1746	[H|_T] ->
1747	    throw({asn1_error,{get_line(H),get(asn1_module),
1748			       [got,get_token(H),expected,'::=']}})
1749    end;
1750parse_ParameterizedValueSetTypeAssignment(Tokens) ->
1751    throw({asn1_assignment_error,{get_line(hd(Tokens)),get(asn1_module),
1752				  [got,get_token(hd(Tokens)),expected,
1753				   typereference]}}).
1754
1755parse_ParameterizedObjectClassAssignment([{typereference,L1,Name}|Rest]) ->
1756    {ParameterList,Rest2} = parse_ParameterList(Rest),
1757    case Rest2 of
1758	[{'::=',_}|Rest3] ->
1759	    {Class,Rest4} = parse_ObjectClass(Rest3),
1760	    {#ptypedef{pos=L1,name=Name,args=ParameterList,typespec=Class},
1761	     Rest4};
1762	[H|_T] ->
1763	    throw({asn1_error,{get_line(H),get(asn1_module),
1764			       [got,get_token(H),expected,'::=']}})
1765    end;
1766parse_ParameterizedObjectClassAssignment(Tokens) ->
1767    throw({asn1_assignment_error,{get_line(hd(Tokens)),get(asn1_module),
1768				  [got,get_token(hd(Tokens)),expected,
1769				   typereference]}}).
1770
1771parse_ParameterizedObjectAssignment([{identifier,L1,Name}|Rest]) ->
1772    {ParameterList,Rest2} = parse_ParameterList(Rest),
1773    {Class,Rest3} = parse_DefinedObjectClass(Rest2),
1774    case Rest3 of
1775	[{'::=',_}|Rest4] ->
1776	    {Object,Rest5} = parse_Object(Rest4),
1777	    {#pobjectdef{pos=L1,name=Name,args=ParameterList,
1778			 class=Class,def=Object},Rest5};
1779	[H|_T] ->
1780	    throw({asn1_error,{get_line(H),get(asn1_module),
1781			       [got,get_token(H),expected,'::=']}})
1782%%%	Other ->
1783%%%	    throw(Other)
1784    end;
1785parse_ParameterizedObjectAssignment(Tokens) ->
1786    throw({asn1_assignment_error,{get_line(hd(Tokens)),get(asn1_module),
1787				  [got,get_token(hd(Tokens)),expected,identifier]}}).
1788
1789parse_ParameterizedObjectSetAssignment([{typereference,L1,Name}|Rest]) ->
1790    {ParameterList,Rest2} = parse_ParameterList(Rest),
1791    {Class,Rest3} = parse_DefinedObjectClass(Rest2),
1792    case Rest3 of
1793	[{'::=',_}|Rest4] ->
1794	    {ObjectSet,Rest5} = parse_ObjectSet(Rest4),
1795	    {#pobjectsetdef{pos=L1,name=Name,args=ParameterList,
1796			    class=Class,def=ObjectSet},Rest5};
1797	[H|_T] ->
1798	    throw({asn1_error,{get_line(H),get(asn1_module),
1799			       [got,get_token(H),expected,'::=']}})
1800%%%	Other ->
1801%%%	    throw(Other)
1802    end;
1803parse_ParameterizedObjectSetAssignment(Tokens) ->
1804    throw({asn1_assignment_error,{get_line(hd(Tokens)),get(asn1_module),
1805				  [got,get_token(hd(Tokens)),expected,
1806				   typereference]}}).
1807
1808parse_ParameterList([{'{',_}|Rest]) ->
1809    parse_ParameterList(Rest,[]);
1810parse_ParameterList(Tokens) ->
1811    throw({asn1_error,{get_line(hd(Tokens)),get(asn1_module),
1812		       [got,get_token(hd(Tokens)),expected,'{']}}).
1813
1814parse_ParameterList(Tokens,Acc) ->
1815    {Parameter,Rest} = parse_Parameter(Tokens),
1816    case Rest of
1817	[{',',_}|Rest2] ->
1818	    parse_ParameterList(Rest2,[Parameter|Acc]);
1819	[{'}',_}|Rest3] ->
1820	    {lists:reverse([Parameter|Acc]),Rest3};
1821	[H|_T]  ->
1822	    throw({asn1_error,{get_line(H),get(asn1_module),
1823			       [got,get_token(H),expected,[',','}']]}})
1824    end.
1825
1826parse_Parameter(Tokens) ->
1827    Flist = [fun parse_ParamGovAndRef/1,
1828	     fun parse_Reference/1],
1829    case (catch parse_or(Tokens,Flist)) of
1830	{'EXIT',Reason} ->
1831	    exit(Reason);
1832	AsnErr = {asn1_error,_} ->
1833	    throw(AsnErr);
1834	Result ->
1835	    Result
1836    end.
1837
1838parse_ParamGovAndRef(Tokens) ->
1839    {ParamGov,Rest} = parse_ParamGovernor(Tokens),
1840    case Rest of
1841	[{':',_}|Rest2] ->
1842	    {Ref,Rest3} = parse_Reference(Rest2),
1843	    {{ParamGov,Ref},Rest3};
1844	[H|_T] ->
1845	   throw({asn1_error,{get_line(H),get(asn1_module),
1846			      [got,get_token(H),expected,':']}})
1847    end.
1848
1849parse_ParamGovernor(Tokens) ->
1850    Flist = [fun parse_Governor/1,
1851	     fun parse_Reference/1],
1852    case (catch parse_or(Tokens,Flist)) of
1853	{'EXIT',Reason} ->
1854	    exit(Reason);
1855	AsnErr = {asn1_error,_} ->
1856	    throw(AsnErr);
1857	Result ->
1858	    Result
1859    end.
1860
1861% parse_ParameterizedReference(Tokens) ->
1862%     {Ref,Rest} = parse_Reference(Tokens),
1863%     case Rest of
1864% 	[{'{',_},{'}',_}|Rest2] ->
1865% 	    {{ptref,Ref},Rest2};
1866% 	_  ->
1867% 	    {{ptref,Ref},Rest}
1868%     end.
1869
1870parse_SimpleDefinedType([{typereference,L1,ModuleName},{'.',_},
1871			 {typereference,_,TypeName}|Rest]) ->
1872    {#'Externaltypereference'{pos=L1,module=ModuleName,
1873						 type=TypeName},Rest};
1874parse_SimpleDefinedType([Tref={typereference,_,_}|Rest]) ->
1875%    {#'Externaltypereference'{pos=L2,module=get(asn1_module),
1876%						 type=TypeName},Rest};
1877    {tref2Exttref(Tref),Rest};
1878parse_SimpleDefinedType(Tokens) ->
1879    throw({asn1_error,{get_line(hd(Tokens)),get(asn1_module),
1880		       [got,get_token(hd(Tokens)),expected,
1881			[typereference,'typereference.typereference']]}}).
1882
1883parse_SimpleDefinedValue([{typereference,L1,ModuleName},{'.',_},
1884			  {identifier,_,Value}|Rest]) ->
1885    {{simpledefinedvalue,#'Externalvaluereference'{pos=L1,module=ModuleName,
1886						   value=Value}},Rest};
1887parse_SimpleDefinedValue([{identifier,L2,Value}|Rest]) ->
1888    {{simpledefinedvalue,L2,Value},Rest};
1889parse_SimpleDefinedValue(Tokens) ->
1890    throw({asn1_error,{get_line(hd(Tokens)),get(asn1_module),
1891		       [got,get_token(hd(Tokens)),expected,
1892			['typereference.identifier',identifier]]}}).
1893
1894parse_ParameterizedType(Tokens) ->
1895    {Type,Rest} = parse_SimpleDefinedType(Tokens),
1896    {Params,Rest2} = parse_ActualParameterList(Rest),
1897    {{pt,Type,Params},Rest2}.
1898
1899parse_ParameterizedValue(Tokens) ->
1900    {Value,Rest} = parse_SimpleDefinedValue(Tokens),
1901    {Params,Rest2} = parse_ActualParameterList(Rest),
1902    {{pv,Value,Params},Rest2}.
1903
1904parse_ParameterizedObjectClass(Tokens) ->
1905    {Type,Rest} = parse_DefinedObjectClass(Tokens),
1906    {Params,Rest2} = parse_ActualParameterList(Rest),
1907    {{poc,Type,Params},Rest2}.
1908
1909parse_ParameterizedObjectSet(Tokens) ->
1910    {ObjectSet,Rest} = parse_DefinedObjectSet(Tokens),
1911    {Params,Rest2} = parse_ActualParameterList(Rest),
1912    {{pos,ObjectSet,Params},Rest2}.
1913
1914parse_ParameterizedObject(Tokens) ->
1915    {Object,Rest} = parse_DefinedObject(Tokens),
1916    {Params,Rest2} = parse_ActualParameterList(Rest),
1917    {{po,Object,Params},Rest2}.
1918
1919parse_ActualParameterList([{'{',_}|Rest]) ->
1920    parse_ActualParameterList(Rest,[]);
1921parse_ActualParameterList(Tokens) ->
1922    throw({asn1_error,{get_line(hd(Tokens)),get(asn1_module),
1923		       [got,get_token(hd(Tokens)),expected,'{']}}).
1924
1925parse_ActualParameterList(Tokens,Acc) ->
1926    {Parameter,Rest} = parse_ActualParameter(Tokens),
1927    case Rest of
1928	[{',',_}|Rest2] ->
1929	    parse_ActualParameterList(Rest2,[Parameter|Acc]);
1930	[{'}',_}|Rest3] ->
1931	    {lists:reverse([Parameter|Acc]),Rest3};
1932	[H|_T] ->
1933	    throw({asn1_error,{get_line(H),get(asn1_module),
1934			       [got,get_token(H),expected,[',','}']]}})
1935%%%	Other ->
1936%%%	    throw(Other)
1937    end.
1938
1939
1940
1941
1942
1943
1944
1945%-------------------------
1946
1947is_word(Token) ->
1948    case not_allowed_word(Token) of
1949	true -> false;
1950	_ ->
1951	    if
1952		atom(Token) ->
1953		    Item = atom_to_list(Token),
1954		    is_word(Item);
1955		list(Token), length(Token) == 1 ->
1956		    check_one_char_word(Token);
1957		list(Token) ->
1958		    [A|Rest] = Token,
1959		    case check_first(A) of
1960			true ->
1961			    check_rest(Rest);
1962			_ ->
1963			    false
1964		    end
1965	    end
1966    end.
1967
1968not_allowed_word(Name) ->
1969    lists:member(Name,["BIT",
1970		       "BOOLEAN",
1971		       "CHARACTER",
1972		       "CHOICE",
1973		       "EMBEDDED",
1974		       "END",
1975		       "ENUMERATED",
1976		       "EXTERNAL",
1977		       "FALSE",
1978		       "INSTANCE",
1979		       "INTEGER",
1980		       "INTERSECTION",
1981		       "MINUS-INFINITY",
1982		       "NULL",
1983		       "OBJECT",
1984		       "OCTET",
1985		       "PLUS-INFINITY",
1986		       "REAL",
1987		       "SEQUENCE",
1988		       "SET",
1989		       "TRUE",
1990		       "UNION"]).
1991
1992check_one_char_word([A]) when $A =< A, $Z >= A ->
1993    true;
1994check_one_char_word([_]) ->
1995    false. %% unknown item in SyntaxList
1996
1997check_first(A) when $A =< A, $Z >= A ->
1998    true;
1999check_first(_) ->
2000    false. %% unknown item in SyntaxList
2001
2002check_rest([R,R|_Rs]) when $- == R ->
2003    false; %% two consecutive hyphens are not allowed in a word
2004check_rest([R]) when $- == R ->
2005    false; %% word cannot end with hyphen
2006check_rest([R|Rs]) when $A=<R, $Z>=R; $-==R ->
2007    check_rest(Rs);
2008check_rest([]) ->
2009    true;
2010check_rest(_) ->
2011    false.
2012
2013
2014to_set(V) when list(V) ->
2015	ordsets:list_to_set(V);
2016to_set(V) ->
2017	ordsets:list_to_set([V]).
2018
2019
2020parse_AlternativeTypeLists(Tokens) ->
2021    {AlternativeTypeList,Rest1} = parse_AlternativeTypeList(Tokens),
2022    {ExtensionAndException,Rest2} =
2023	case Rest1 of
2024	    [{',',_},{'...',L1},{'!',_}|Rest12] ->
2025		{_,Rest13} = parse_ExceptionIdentification(Rest12),
2026		%% Exception info is currently thrown away
2027		{[#'EXTENSIONMARK'{pos=L1}],Rest13};
2028	    [{',',_},{'...',L1}|Rest12] ->
2029		{[#'EXTENSIONMARK'{pos=L1}],Rest12};
2030	    _ ->
2031		{[],Rest1}
2032	end,
2033    case ExtensionAndException of
2034	[] ->
2035	    {AlternativeTypeList,Rest2};
2036	_ ->
2037	    {ExtensionAddition,Rest3} =
2038		case Rest2 of
2039		    [{',',_}|Rest23] ->
2040			parse_ExtensionAdditionAlternativeList(Rest23);
2041		    _ ->
2042			{[],Rest2}
2043		end,
2044	    {OptionalExtensionMarker,Rest4} =
2045		case Rest3 of
2046		    [{',',_},{'...',L3}|Rest31] ->
2047			{[#'EXTENSIONMARK'{pos=L3}],Rest31};
2048		    _ ->
2049			{[],Rest3}
2050		end,
2051	    {AlternativeTypeList ++ ExtensionAndException ++ ExtensionAddition ++ OptionalExtensionMarker, Rest4}
2052    end.
2053
2054
2055parse_AlternativeTypeList(Tokens) ->
2056    parse_AlternativeTypeList(Tokens,[]).
2057
2058parse_AlternativeTypeList(Tokens,Acc) ->
2059    {NamedType,Rest} = parse_NamedType(Tokens),
2060    case Rest of
2061	[{',',_},Id = {identifier,_,_}|Rest2] ->
2062	    parse_AlternativeTypeList([Id|Rest2],[NamedType|Acc]);
2063	_ ->
2064	    {lists:reverse([NamedType|Acc]),Rest}
2065    end.
2066
2067
2068
2069parse_ExtensionAdditionAlternativeList(Tokens) ->
2070    parse_ExtensionAdditionAlternativeList(Tokens,[]).
2071
2072parse_ExtensionAdditionAlternativeList(Tokens,Acc) ->
2073    {Element,Rest0} =
2074	case Tokens of
2075	    [{identifier,_,_}|_Rest] ->
2076		parse_NamedType(Tokens);
2077	    [{'[[',_}|_] ->
2078		parse_ExtensionAdditionAlternatives(Tokens)
2079	end,
2080    case Rest0 of
2081	[{',',_}|Rest01] ->
2082	    parse_ExtensionAdditionAlternativeList(Rest01,[Element|Acc]);
2083	_  ->
2084	    {lists:reverse([Element|Acc]),Rest0}
2085    end.
2086
2087parse_ExtensionAdditionAlternatives([{'[[',_}|Rest]) ->
2088    parse_ExtensionAdditionAlternatives(Rest,[]);
2089parse_ExtensionAdditionAlternatives(Tokens) ->
2090    throw({asn1_error,{get_line(hd(Tokens)),get(asn1_module),
2091		       [got,get_token(hd(Tokens)),expected,'[[']}}).
2092
2093parse_ExtensionAdditionAlternatives([Id = {identifier,_,_}|Rest],Acc) ->
2094    {NamedType, Rest2} = parse_NamedType([Id|Rest]),
2095    case Rest2 of
2096	[{',',_}|Rest21] ->
2097	    parse_ExtensionAdditionAlternatives(Rest21,[NamedType|Acc]);
2098	[{']]',_}|Rest21] ->
2099	    {lists:reverse(Acc),Rest21};
2100	_ ->
2101	    throw({asn1_error,{get_line(hd(Rest2)),get(asn1_module),
2102			       [got,get_token(hd(Rest2)),expected,[',',']]']]}})
2103    end.
2104
2105parse_NamedType([{identifier,L1,Idname}|Rest]) ->
2106    {Type,Rest2} = parse_Type(Rest),
2107    {#'ComponentType'{pos=L1,name=Idname,typespec=Type,prop=mandatory},Rest2};
2108parse_NamedType(Tokens) ->
2109    throw({asn1_error,{get_line(hd(Tokens)),get(asn1_module),
2110		       [got,get_token(hd(Tokens)),expected,identifier]}}).
2111
2112
2113parse_ComponentTypeLists(Tokens) ->
2114%    Resulting tuple {ComponentTypeList,Rest1} is returned
2115    case Tokens of
2116	[{identifier,_,_}|_Rest0] ->
2117	    {Clist,Rest01} = parse_ComponentTypeList(Tokens),
2118	    case Rest01 of
2119		[{',',_}|Rest02] ->
2120		    parse_ComponentTypeLists(Rest02,Clist);
2121		_ ->
2122		    {Clist,Rest01}
2123	    end;
2124	[{'COMPONENTS',_},{'OF',_}|_Rest] ->
2125	    {Clist,Rest01} = parse_ComponentTypeList(Tokens),
2126	    case Rest01 of
2127		[{',',_}|Rest02] ->
2128		    parse_ComponentTypeLists(Rest02,Clist);
2129		_ ->
2130		    {Clist,Rest01}
2131	    end;
2132	_ ->
2133	    parse_ComponentTypeLists(Tokens,[])
2134    end.
2135
2136parse_ComponentTypeLists([{'...',L1},{'!',_}|Rest],Clist1) ->
2137    {_,Rest2} = parse_ExceptionIdentification(Rest),
2138    %% Exception info is currently thrown away
2139    parse_ComponentTypeLists2(Rest2,Clist1++[#'EXTENSIONMARK'{pos=L1}]);
2140parse_ComponentTypeLists([{'...',L1}|Rest],Clist1) ->
2141    parse_ComponentTypeLists2(Rest,Clist1++[#'EXTENSIONMARK'{pos=L1}]);
2142parse_ComponentTypeLists(Tokens,Clist1) ->
2143    {Clist1,Tokens}.
2144
2145
2146parse_ComponentTypeLists2(Tokens,Clist1) ->
2147    {ExtensionAddition,Rest2} =
2148	case Tokens of
2149	    [{',',_}|Rest1] ->
2150		parse_ExtensionAdditionList(Rest1);
2151	    _ ->
2152		{[],Tokens}
2153	end,
2154    {OptionalExtensionMarker,Rest3} =
2155	case Rest2 of
2156	    [{',',_},{'...',L2}|Rest21] ->
2157		{[#'EXTENSIONMARK'{pos=L2}],Rest21};
2158	    _ ->
2159		{[],Rest2}
2160	end,
2161    {RootComponentTypeList,Rest4} =
2162	case Rest3 of
2163	    [{',',_}|Rest31] ->
2164		parse_ComponentTypeList(Rest31);
2165	    _ ->
2166		{[],Rest3}
2167	end,
2168    {Clist1 ++ ExtensionAddition ++ OptionalExtensionMarker ++ RootComponentTypeList, Rest4}.
2169
2170
2171parse_ComponentTypeList(Tokens) ->
2172    parse_ComponentTypeList(Tokens,[]).
2173
2174parse_ComponentTypeList(Tokens,Acc) ->
2175    {ComponentType,Rest} = parse_ComponentType(Tokens),
2176    case Rest of
2177	[{',',_},Id = {identifier,_,_}|Rest2] ->
2178	    parse_ComponentTypeList([Id|Rest2],[ComponentType|Acc]);
2179	[{',',_},C1={'COMPONENTS',_},C2={'OF',_}|Rest2] ->
2180	    parse_ComponentTypeList([C1,C2|Rest2],[ComponentType|Acc]);
2181% 	_ ->
2182% 	    {lists:reverse([ComponentType|Acc]),Rest}
2183	[{'}',_}|_] ->
2184	    {lists:reverse([ComponentType|Acc]),Rest};
2185	[{',',_},{'...',_}|_] ->
2186	    {lists:reverse([ComponentType|Acc]),Rest};
2187	_ ->
2188	    throw({asn1_error,
2189		   {get_line(hd(Tokens)),get(asn1_module),
2190		    [got,[get_token(hd(Rest)),get_token(hd(tl(Rest)))],
2191		     expected,['}',', identifier']]}})
2192    end.
2193
2194
2195parse_ExtensionAdditionList(Tokens) ->
2196    parse_ExtensionAdditionList(Tokens,[]).
2197
2198parse_ExtensionAdditionList(Tokens,Acc) ->
2199    {Element,Rest0} =
2200	case Tokens of
2201	    [{identifier,_,_}|_Rest] ->
2202		parse_ComponentType(Tokens);
2203	    [{'[[',_}|_] ->
2204		parse_ExtensionAdditions(Tokens);
2205	    _ ->
2206		throw({asn1_error,{get_line(hd(Tokens)),get(asn1_module),
2207				   [got,get_token(hd(Tokens)),expected,
2208				    [identifier,'[[']]}})
2209	end,
2210    case Rest0 of
2211	[{',',_}|Rest01] ->
2212	    parse_ExtensionAdditionList(Rest01,[Element|Acc]);
2213	_  ->
2214	    {lists:reverse([Element|Acc]),Rest0}
2215    end.
2216
2217parse_ExtensionAdditions([{'[[',_}|Rest]) ->
2218    parse_ExtensionAdditions(Rest,[]);
2219parse_ExtensionAdditions(Tokens) ->
2220    throw({asn1_error,{get_line(hd(Tokens)),get(asn1_module),
2221		       [got,get_token(hd(Tokens)),expected,'[[']}}).
2222
2223parse_ExtensionAdditions([Id = {identifier,_,_}|Rest],Acc) ->
2224    {ComponentType, Rest2} = parse_ComponentType([Id|Rest]),
2225    case Rest2 of
2226	[{',',_}|Rest21] ->
2227	    parse_ExtensionAdditions(Rest21,[ComponentType|Acc]);
2228	[{']]',_}|Rest21] ->
2229	    {lists:reverse(Acc),Rest21};
2230	_ ->
2231	    throw({asn1_error,{get_line(hd(Rest2)),get(asn1_module),
2232			       [got,get_token(hd(Rest2)),expected,[',',']]']]}})
2233    end;
2234parse_ExtensionAdditions(Tokens,_) ->
2235    throw({asn1_error,{get_line(hd(Tokens)),get(asn1_module),
2236		       [got,get_token(hd(Tokens)),expected,identifier]}}).
2237
2238parse_ComponentType([{'COMPONENTS',_},{'OF',_}|Rest]) ->
2239    {Type,Rest2} = parse_Type(Rest),
2240    {{'COMPONENTS OF',Type},Rest2};
2241parse_ComponentType(Tokens) ->
2242    {NamedType,Rest} = parse_NamedType(Tokens),
2243    case Rest of
2244	[{'OPTIONAL',_}|Rest2] ->
2245	    {NamedType#'ComponentType'{prop='OPTIONAL'},Rest2};
2246	[{'DEFAULT',_}|Rest2] ->
2247	    {Value,Rest21} = parse_Value(Rest2),
2248	    {NamedType#'ComponentType'{prop={'DEFAULT',Value}},Rest21};
2249	_ ->
2250	    {NamedType,Rest}
2251    end.
2252
2253
2254
2255parse_SignedNumber([{number,_,Value}|Rest]) ->
2256    {Value,Rest};
2257parse_SignedNumber([{'-',_},{number,_,Value}|Rest]) ->
2258    {-Value,Rest};
2259parse_SignedNumber(Tokens) ->
2260    throw({asn1_error,{get_line(hd(Tokens)),get(asn1_module),
2261		       [got,get_token(hd(Tokens)),expected,
2262			[number,'-number']]}}).
2263
2264parse_Enumerations(Tokens=[{identifier,_,_}|_Rest]) ->
2265    parse_Enumerations(Tokens,[]);
2266parse_Enumerations([H|_T]) ->
2267    throw({asn1_error,{get_line(H),get(asn1_module),
2268		       [got,get_token(H),expected,identifier]}}).
2269
2270parse_Enumerations(Tokens = [{identifier,_,_},{'(',_}|_Rest], Acc) ->
2271    {NamedNumber,Rest2} = parse_NamedNumber(Tokens),
2272    case Rest2 of
2273	[{',',_}|Rest3] ->
2274	    parse_Enumerations(Rest3,[NamedNumber|Acc]);
2275	_ ->
2276	    {lists:reverse([NamedNumber|Acc]),Rest2}
2277    end;
2278parse_Enumerations([{identifier,_,Id}|Rest], Acc) ->
2279    case Rest of
2280	[{',',_}|Rest2] ->
2281	    parse_Enumerations(Rest2,[Id|Acc]);
2282	_ ->
2283	    {lists:reverse([Id|Acc]),Rest}
2284    end;
2285parse_Enumerations([{'...',_}|Rest], Acc) ->
2286    case Rest of
2287	[{',',_}|Rest2] ->
2288	    parse_Enumerations(Rest2,['EXTENSIONMARK'|Acc]);
2289	_ ->
2290	    {lists:reverse(['EXTENSIONMARK'|Acc]),Rest}
2291    end;
2292parse_Enumerations([H|_T],_) ->
2293    throw({asn1_error,{get_line(H),get(asn1_module),
2294		       [got,get_token(H),expected,identifier]}}).
2295
2296parse_NamedNumberList(Tokens) ->
2297    parse_NamedNumberList(Tokens,[]).
2298
2299parse_NamedNumberList(Tokens,Acc) ->
2300    {NamedNum,Rest} = parse_NamedNumber(Tokens),
2301    case Rest of
2302	[{',',_}|Rest2] ->
2303	    parse_NamedNumberList(Rest2,[NamedNum|Acc]);
2304	_ ->
2305	    {lists:reverse([NamedNum|Acc]),Rest}
2306    end.
2307
2308parse_NamedNumber([{identifier,_,Name},{'(',_}|Rest]) ->
2309    Flist = [fun parse_SignedNumber/1,
2310	     fun parse_DefinedValue/1],
2311    case (catch parse_or(Rest,Flist)) of
2312	{'EXIT',Reason} ->
2313	    exit(Reason);
2314	AsnErr = {asn1_error,_} ->
2315	    throw(AsnErr);
2316	{NamedNum,[{')',_}|Rest2]} ->
2317	    {{'NamedNumber',Name,NamedNum},Rest2};
2318	_ ->
2319	    throw({asn1_error,{get_line(hd(Rest)),get(asn1_module),
2320			       [got,get_token(hd(Rest)),expected,'NamedNumberList']}})
2321    end;
2322parse_NamedNumber(Tokens) ->
2323    throw({asn1_error,{get_line(hd(Tokens)),get(asn1_module),
2324		       [got,get_token(hd(Tokens)),expected,identifier]}}).
2325
2326
2327parse_Tag([{'[',_}|Rest]) ->
2328    {Class,Rest2} = parse_Class(Rest),
2329    {ClassNumber,Rest3} =
2330	case Rest2 of
2331	    [{number,_,Num}|Rest21] ->
2332		{Num,Rest21};
2333	    _ ->
2334		parse_DefinedValue(Rest2)
2335	end,
2336    case Rest3 of
2337	[{']',_}|Rest4] ->
2338	    {#tag{class=Class,number=ClassNumber},Rest4};
2339	_ ->
2340	    throw({asn1_error,{get_line(hd(Rest3)),get(asn1_module),
2341			       [got,get_token(hd(Rest3)),expected,']']}})
2342    end;
2343parse_Tag(Tokens) ->
2344    throw({asn1_error,{get_line(hd(Tokens)),get(asn1_module),
2345		       [got,get_token(hd(Tokens)),expected,'[']}}).
2346
2347parse_Class([{'UNIVERSAL',_}|Rest]) ->
2348    {'UNIVERSAL',Rest};
2349parse_Class([{'APPLICATION',_}|Rest]) ->
2350    {'APPLICATION',Rest};
2351parse_Class([{'PRIVATE',_}|Rest]) ->
2352    {'PRIVATE',Rest};
2353parse_Class(Tokens) ->
2354    {'CONTEXT',Tokens}.
2355
2356parse_Value(Tokens) ->
2357    Flist = [fun parse_BuiltinValue/1,
2358	     fun parse_ValueFromObject/1,
2359	     fun parse_DefinedValue/1],
2360
2361    case (catch parse_or(Tokens,Flist)) of
2362	{'EXIT',Reason} ->
2363	    exit(Reason);
2364	AsnErr = {asn1_error,_} ->
2365	    throw(AsnErr);
2366	Result ->
2367	    Result
2368    end.
2369
2370parse_BuiltinValue([{bstring,_,Bstr}|Rest]) ->
2371    {{bstring,Bstr},Rest};
2372parse_BuiltinValue([{hstring,_,Hstr}|Rest]) ->
2373    {{hstring,Hstr},Rest};
2374parse_BuiltinValue([{'{',_},{'}',_}|Rest]) ->
2375    {[],Rest};
2376parse_BuiltinValue(Tokens = [{'{',_}|_Rest]) ->
2377    Flist = [
2378	     fun parse_SequenceOfValue/1,
2379	     fun parse_SequenceValue/1,
2380	     fun parse_ObjectIdentifierValue/1],
2381    case (catch parse_or(Tokens,Flist)) of
2382	{'EXIT',Reason} ->
2383	    exit(Reason);
2384	AsnErr = {asn1_error,_} ->
2385	    throw(AsnErr);
2386	Result ->
2387	    Result
2388    end;
2389parse_BuiltinValue([{identifier,_,IdName},{':',_}|Rest]) ->
2390    {Value,Rest2} = parse_Value(Rest),
2391    {{'CHOICE',{IdName,Value}},Rest2};
2392parse_BuiltinValue([{'NULL',_}|Rest]) ->
2393    {'NULL',Rest};
2394parse_BuiltinValue([{'TRUE',_}|Rest]) ->
2395    {true,Rest};
2396parse_BuiltinValue([{'FALSE',_}|Rest]) ->
2397    {false,Rest};
2398parse_BuiltinValue([{'PLUS-INFINITY',_}|Rest]) ->
2399    {'PLUS-INFINITY',Rest};
2400parse_BuiltinValue([{'MINUS-INFINITY',_}|Rest]) ->
2401    {'MINUS-INFINITY',Rest};
2402parse_BuiltinValue([{cstring,_,Cstr}|Rest]) ->
2403    {Cstr,Rest};
2404parse_BuiltinValue([{number,_,Num}|Rest]) ->
2405    {Num,Rest};
2406parse_BuiltinValue([{'-',_},{number,_,Num}|Rest]) ->
2407    {- Num,Rest};
2408parse_BuiltinValue(Tokens) ->
2409    parse_ObjectClassFieldValue(Tokens).
2410
2411%% Externalvaluereference
2412parse_DefinedValue([{typereference,L1,Tname},{'.',_},{identifier,_,Idname}|Rest]) ->
2413    {#'Externalvaluereference'{pos=L1,module=Tname,value=Idname},Rest};
2414%% valuereference
2415parse_DefinedValue([Id = {identifier,_,_}|Rest]) ->
2416    {identifier2Extvalueref(Id),Rest};
2417%% ParameterizedValue
2418parse_DefinedValue(Tokens) ->
2419    parse_ParameterizedValue(Tokens).
2420
2421
2422parse_SequenceValue([{'{',_}|Tokens]) ->
2423    parse_SequenceValue(Tokens,[]);
2424parse_SequenceValue(Tokens) ->
2425    throw({asn1_error,{get_line(hd(Tokens)),get(asn1_module),
2426		       [got,get_token(hd(Tokens)),expected,'{']}}).
2427
2428parse_SequenceValue([{identifier,_,IdName}|Rest],Acc) ->
2429    {Value,Rest2} = parse_Value(Rest),
2430    case Rest2 of
2431	[{',',_}|Rest3] ->
2432	    parse_SequenceValue(Rest3,[{IdName,Value}|Acc]);
2433	[{'}',_}|Rest3] ->
2434	    {lists:reverse([{IdName,Value}|Acc]),Rest3};
2435	_ ->
2436	    throw({asn1_error,{get_line(hd(Rest2)),get(asn1_module),
2437			       [got,get_token(hd(Rest2)),expected,'}']}})
2438    end;
2439parse_SequenceValue(Tokens,_Acc) ->
2440    throw({asn1_error,{get_line(hd(Tokens)),get(asn1_module),
2441		       [got,get_token(hd(Tokens)),expected,identifier]}}).
2442
2443parse_SequenceOfValue([{'{',_}|Tokens]) ->
2444    parse_SequenceOfValue(Tokens,[]);
2445parse_SequenceOfValue(Tokens) ->
2446    throw({asn1_error,{get_line(hd(Tokens)),get(asn1_module),
2447		       [got,get_token(hd(Tokens)),expected,'{']}}).
2448
2449parse_SequenceOfValue(Tokens,Acc) ->
2450    {Value,Rest2} = parse_Value(Tokens),
2451    case Rest2 of
2452	[{',',_}|Rest3] ->
2453	    parse_SequenceOfValue(Rest3,[Value|Acc]);
2454	[{'}',_}|Rest3] ->
2455	    {lists:reverse([Value|Acc]),Rest3};
2456	_ ->
2457	    throw({asn1_error,{get_line(hd(Rest2)),get(asn1_module),
2458			       [got,get_token(hd(Rest2)),expected,'}']}})
2459    end.
2460
2461parse_ValueSetTypeAssignment([{typereference,L1,Name}|Rest]) ->
2462    {Type,Rest2} = parse_Type(Rest),
2463    case Rest2 of
2464	[{'::=',_}|Rest3] ->
2465	    {ValueSet,Rest4} = parse_ValueSet(Rest3),
2466	    {#valuedef{pos=L1,name=Name,type=Type,value=ValueSet},Rest4};
2467	[H|_T] ->
2468	    throw({asn1_error,{get_line(L1),get(asn1_module),
2469			       [got,get_token(H),expected,'::=']}})
2470    end;
2471parse_ValueSetTypeAssignment(Tokens) ->
2472    throw({asn1_assignment_error,{get_line(hd(Tokens)),get(asn1_module),
2473				  [got,get_token(hd(Tokens)),expected,
2474				   typereference]}}).
2475
2476parse_ValueSet([{'{',_}|Rest]) ->
2477    {Elems,Rest2} = parse_ElementSetSpecs(Rest),
2478    case Rest2 of
2479	[{'}',_}|Rest3] ->
2480	    {{valueset,Elems},Rest3};
2481	[H|_T] ->
2482	    throw({asn1_error,{get_line(H),get(asn1_module),
2483			       [got,get_token(H),expected,'}']}})
2484    end;
2485parse_ValueSet(Tokens) ->
2486    throw({asn1_error,{get_line(hd(Tokens)),get(asn1_module),
2487		       [got,get_token(hd(Tokens)),expected,'{']}}).
2488
2489parse_ValueAssignment([{identifier,L1,IdName}|Rest]) ->
2490    {Type,Rest2} = parse_Type(Rest),
2491    case Rest2 of
2492	[{'::=',_}|Rest3] ->
2493	    {Value,Rest4} = parse_Value(Rest3),
2494	    case lookahead_assignment(Rest4) of
2495		ok ->
2496		    {#valuedef{pos=L1,name=IdName,type=Type,value=Value},Rest4};
2497		_ ->
2498		    throw({asn1_error,{get_line(hd(Rest2)),get(asn1_module),
2499				       [got,get_token(hd(Rest2)),expected,'::=']}})
2500	    end;
2501	_ ->
2502	    throw({asn1_error,{get_line(hd(Rest2)),get(asn1_module),
2503			       [got,get_token(hd(Rest2)),expected,'::=']}})
2504    end;
2505parse_ValueAssignment(Tokens) ->
2506    throw({asn1_assignment_error,{get_line(hd(Tokens)),get(asn1_module),
2507				  [got,get_token(hd(Tokens)),expected,identifier]}}).
2508
2509%% SizeConstraint
2510parse_SubtypeElements([{'SIZE',_}|Tokens]) ->
2511    {Constraint,Rest} = parse_Constraint(Tokens),
2512    {{'SizeConstraint',Constraint#constraint.c},Rest};
2513%% PermittedAlphabet
2514parse_SubtypeElements([{'FROM',_}|Tokens]) ->
2515    {Constraint,Rest} = parse_Constraint(Tokens),
2516    {{'PermittedAlphabet',Constraint#constraint.c},Rest};
2517%% InnerTypeConstraints
2518parse_SubtypeElements([{'WITH',_},{'COMPONENT',_}|Tokens]) ->
2519    {Constraint,Rest} = parse_Constraint(Tokens),
2520    {{'WITH COMPONENT',Constraint},Rest};
2521parse_SubtypeElements([{'WITH',_},{'COMPONENTS',_},{'{',_},{'...',_},{',',_}|Tokens]) ->
2522    {Constraint,Rest} = parse_TypeConstraints(Tokens),
2523    case Rest of
2524	[{'}',_}|Rest2] ->
2525	    {{'WITH COMPONENTS',{'PartialSpecification',Constraint}},Rest2};
2526	_ ->
2527	    throw({asn1_error,{get_line(hd(Rest)),get(asn1_module),
2528			       [got,get_token(hd(Rest)),expected,'}']}})
2529    end;
2530parse_SubtypeElements([{'WITH',_},{'COMPONENTS',_},{'{',_}|Tokens]) ->
2531    {Constraint,Rest} = parse_TypeConstraints(Tokens),
2532    case Rest of
2533	[{'}',_}|Rest2] ->
2534	    {{'WITH COMPONENTS',{'FullSpecification',Constraint}},Rest2};
2535	_ ->
2536	    throw({asn1_error,{get_line(hd(Rest)),get(asn1_module),
2537			       [got,get_token(hd(Rest)),expected,'}']}})
2538    end;
2539%% SingleValue
2540%% ContainedSubtype
2541%% ValueRange
2542%% TypeConstraint
2543parse_SubtypeElements(Tokens) ->
2544    Flist = [fun parse_ContainedSubtype/1,
2545	     fun parse_Value/1,
2546	     fun([{'MIN',_}|T]) -> {'MIN',T} end,
2547	     fun parse_Type/1],
2548    case (catch parse_or(Tokens,Flist)) of
2549	{'EXIT',Reason} ->
2550	    exit(Reason);
2551	{asn1_error,Reason} ->
2552	    throw(Reason);
2553	Result = {Val,_} when record(Val,type) ->
2554	    Result;
2555	{Lower,[{'..',_}|Rest]} ->
2556	    {Upper,Rest2} = parse_UpperEndpoint(Rest),
2557	    {{'ValueRange',{Lower,Upper}},Rest2};
2558	{Lower,[{'<',_},{'..',_}|Rest]} ->
2559	    {Upper,Rest2} = parse_UpperEndpoint(Rest),
2560	    {{'ValueRange',{{gt,Lower},Upper}},Rest2};
2561	{Res={'ContainedSubtype',_Type},Rest} ->
2562	    {Res,Rest};
2563	{Value,Rest} ->
2564	    {{'SingleValue',Value},Rest}
2565    end.
2566
2567parse_ContainedSubtype([{'INCLUDES',_}|Rest]) ->
2568    {Type,Rest2} = parse_Type(Rest),
2569    {{'ContainedSubtype',Type},Rest2};
2570parse_ContainedSubtype(Tokens) ->
2571    throw({asn1_error,{get_line(hd(Tokens)),get(asn1_module),
2572		       [got,get_token(hd(Tokens)),expected,'INCLUDES']}}).
2573%%parse_ContainedSubtype(Tokens) -> %this option is moved to parse_SubtypeElements
2574%%    parse_Type(Tokens).
2575
2576parse_UpperEndpoint([{'<',_}|Rest]) ->
2577    parse_UpperEndpoint(lt,Rest);
2578parse_UpperEndpoint(Tokens) ->
2579    parse_UpperEndpoint(false,Tokens).
2580
2581parse_UpperEndpoint(Lt,Tokens) ->
2582    Flist = [ fun([{'MAX',_}|T]) -> {'MAX',T} end,
2583	      fun parse_Value/1],
2584    case (catch parse_or(Tokens,Flist)) of
2585	{'EXIT',Reason} ->
2586	    exit(Reason);
2587	AsnErr = {asn1_error,_} ->
2588	    throw(AsnErr);
2589	{Value,Rest2} when Lt == lt ->
2590	    {{lt,Value},Rest2};
2591	{Value,Rest2} ->
2592	    {Value,Rest2}
2593    end.
2594
2595parse_TypeConstraints(Tokens) ->
2596    parse_TypeConstraints(Tokens,[]).
2597
2598parse_TypeConstraints([{identifier,_,_}|Rest],Acc) ->
2599    {ComponentConstraint,Rest2} = parse_ComponentConstraint(Rest),
2600    case Rest2 of
2601	[{',',_}|Rest3] ->
2602	    parse_TypeConstraints(Rest3,[ComponentConstraint|Acc]);
2603	_ ->
2604	    {lists:reverse([ComponentConstraint|Acc]),Rest2}
2605    end;
2606parse_TypeConstraints([H|_T],_) ->
2607    throw({asn1_error,{get_line(H),get(asn1_module),
2608		       [got,get_token(H),expected,identifier]}}).
2609
2610parse_ComponentConstraint(Tokens = [{'(',_}|_Rest]) ->
2611    {ValueConstraint,Rest2} = parse_Constraint(Tokens),
2612    {PresenceConstraint,Rest3} = parse_PresenceConstraint(Rest2),
2613    {{ValueConstraint,PresenceConstraint},Rest3};
2614parse_ComponentConstraint(Tokens) ->
2615    {PresenceConstraint,Rest} = parse_PresenceConstraint(Tokens),
2616    {{asn1_empty,PresenceConstraint},Rest}.
2617
2618parse_PresenceConstraint([{'PRESENT',_}|Rest]) ->
2619    {'PRESENT',Rest};
2620parse_PresenceConstraint([{'ABSENT',_}|Rest]) ->
2621    {'ABSENT',Rest};
2622parse_PresenceConstraint([{'OPTIONAL',_}|Rest]) ->
2623    {'OPTIONAL',Rest};
2624parse_PresenceConstraint(Tokens) ->
2625    {asn1_empty,Tokens}.
2626
2627
2628merge_constraints({Rlist,ExtList}) -> % extensionmarker in constraint
2629    {merge_constraints(Rlist,[],[]),
2630     merge_constraints(ExtList,[],[])};
2631
2632merge_constraints(Clist) ->
2633    merge_constraints(Clist, [], []).
2634
2635merge_constraints([Ch|Ct],Cacc, Eacc) ->
2636    NewEacc = case Ch#constraint.e of
2637		  undefined -> Eacc;
2638		  E -> [E|Eacc]
2639	      end,
2640    merge_constraints(Ct,[fixup_constraint(Ch#constraint.c)|Cacc],NewEacc);
2641
2642merge_constraints([],Cacc,[]) ->
2643%%    lists:flatten(Cacc);
2644    lists:reverse(Cacc);
2645merge_constraints([],Cacc,Eacc) ->
2646%%    lists:flatten(Cacc) ++ [{'Errors',Eacc}].
2647    lists:reverse(Cacc) ++ [{'Errors',Eacc}].
2648
2649fixup_constraint(C) ->
2650    case C of
2651	{'SingleValue',SubType} when element(1,SubType) == 'ContainedSubtype' ->
2652	    SubType;
2653	{'SingleValue',V} when list(V) ->
2654	    C;
2655	%%	    [C,{'ValueRange',{lists:min(V),lists:max(V)}}];
2656	%% bug, turns wrong when an element in V is a reference to a defined value
2657	{'PermittedAlphabet',{'SingleValue',V}} when list(V) ->
2658	    %%sort and remove duplicates
2659	    V2 = {'SingleValue',
2660		  ordsets:list_to_set(lists:flatten(V))},
2661	    {'PermittedAlphabet',V2};
2662	{'PermittedAlphabet',{'SingleValue',V}} ->
2663	    V2 = {'SingleValue',[V]},
2664	    {'PermittedAlphabet',V2};
2665	{'SizeConstraint',Sc} ->
2666	    {'SizeConstraint',fixup_size_constraint(Sc)};
2667
2668	List when list(List) ->  %% In This case maybe a union or intersection
2669	    [fixup_constraint(Xc)||Xc <- List];
2670	Other ->
2671	    Other
2672    end.
2673
2674fixup_size_constraint({'ValueRange',{Lb,Ub}}) ->
2675	{Lb,Ub};
2676fixup_size_constraint({{'ValueRange',R},[]}) ->
2677	{R,[]};
2678fixup_size_constraint({[],{'ValueRange',R}}) ->
2679	{[],R};
2680fixup_size_constraint({{'ValueRange',R1},{'ValueRange',R2}}) ->
2681	{R1,R2};
2682fixup_size_constraint({'SingleValue',[Sv]}) ->
2683	fixup_size_constraint({'SingleValue',Sv});
2684fixup_size_constraint({'SingleValue',L}) when list(L) ->
2685	ordsets:list_to_set(L);
2686fixup_size_constraint({'SingleValue',L}) ->
2687	{L,L};
2688fixup_size_constraint({C1,C2}) ->
2689	{fixup_size_constraint(C1), fixup_size_constraint(C2)}.
2690
2691get_line({_,Pos,Token}) when integer(Pos),atom(Token) ->
2692    Pos;
2693get_line({Token,Pos}) when integer(Pos),atom(Token) ->
2694    Pos;
2695get_line(_) ->
2696    undefined.
2697
2698get_token({_,Pos,Token}) when integer(Pos),atom(Token) ->
2699    Token;
2700get_token({'$end',Pos}) when integer(Pos) ->
2701    undefined;
2702get_token({Token,Pos}) when integer(Pos),atom(Token) ->
2703    Token;
2704get_token(_) ->
2705    undefined.
2706
2707prioritize_error(ErrList) ->
2708    case lists:keymember(asn1_error,1,ErrList) of
2709	false -> % only asn1_assignment_error -> take the last
2710	    lists:last(ErrList);
2711	true -> % contains errors from deeper in a Type
2712	    NewErrList = [_Err={_,_}|_RestErr] =
2713		lists:filter(fun({asn1_error,_})->true;(_)->false end,
2714			     ErrList),
2715	    SplitErrs =
2716		lists:splitwith(fun({_,X})->
2717					case element(1,X) of
2718					    Int when integer(Int) -> true;
2719					    _ -> false
2720					end
2721				end,
2722				NewErrList),
2723	    case SplitErrs of
2724		{[],UndefPosErrs} -> % if no error with Position exists
2725		    lists:last(UndefPosErrs);
2726		{IntPosErrs,_} ->
2727		    IntPosReasons = lists:map(fun(X)->element(2,X) end,IntPosErrs),
2728		    SortedReasons = lists:keysort(1,IntPosReasons),
2729		    {asn1_error,lists:last(SortedReasons)}
2730	    end
2731    end.
2732
2733%% most_prio_error([H={_,Reason}|T],Atom,Err) when atom(Atom) ->
2734%%     most_prio_error(T,element(1,Reason),H);
2735%% most_prio_error([H={_,Reason}|T],Greatest,Err) ->
2736%%     case element(1,Reason) of
2737%% 	Pos when integer(Pos),Pos>Greatest ->
2738%% 	    most_prio_error(
2739
2740
2741tref2Exttref(#typereference{pos=Pos,val=Name}) ->
2742    #'Externaltypereference'{pos=Pos,
2743			     module=get(asn1_module),
2744			     type=Name}.
2745
2746tref2Exttref(Pos,Name) ->
2747    #'Externaltypereference'{pos=Pos,
2748			     module=get(asn1_module),
2749			     type=Name}.
2750
2751identifier2Extvalueref(#identifier{pos=Pos,val=Name}) ->
2752    #'Externalvaluereference'{pos=Pos,
2753			      module=get(asn1_module),
2754			      value=Name}.
2755
2756%% lookahead_assignment/1 checks that the next sequence of tokens
2757%% in Token contain a valid assignment or the
2758%% 'END' token. Otherwise an exception is thrown.
2759lookahead_assignment([{'END',_}|_Rest]) ->
2760    ok;
2761lookahead_assignment(Tokens) ->
2762    parse_Assignment(Tokens),
2763    ok.
2764