1%% vim: tabstop=8:shiftwidth=4 2%% 3%% %CopyrightBegin% 4%% 5%% Copyright Ericsson AB 2000-2017. All Rights Reserved. 6%% 7%% Licensed under the Apache License, Version 2.0 (the "License"); 8%% you may not use this file except in compliance with the License. 9%% You may obtain a copy of the License at 10%% 11%% http://www.apache.org/licenses/LICENSE-2.0 12%% 13%% Unless required by applicable law or agreed to in writing, software 14%% distributed under the License is distributed on an "AS IS" BASIS, 15%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16%% See the License for the specific language governing permissions and 17%% limitations under the License. 18%% 19%% %CopyrightEnd% 20%% 21%% 22-module(asn1ct_parser2). 23 24-export([parse/2,format_error/1]). 25-include("asn1_records.hrl"). 26 27%% Only used internally within this module. 28-record(typereference, {pos,val}). 29-record(constraint, {c,e}). 30-record(identifier, {pos,val}). 31 32parse(File0, Tokens0) -> 33 try do_parse(Tokens0) of 34 {ok,#module{}}=Result -> 35 Result 36 catch 37 throw:{asn1_error,Fun} when is_function(Fun, 0) -> 38 handle_parse_error(File0, Fun()); 39 throw:{asn1_error,{parse_error,Tokens}} -> 40 handle_parse_error(File0, Tokens) 41 after 42 clean_process_dictionary() 43 end. 44 45handle_parse_error(File0, [Token|_]) -> 46 File = filename:basename(File0), 47 Line = get_line(Token), 48 Error = {structured_error,{File,Line},?MODULE, 49 {syntax_error,get_token(Token)}}, 50 {error,[Error]}. 51 52do_parse(Tokens0) -> 53 {ModuleDefinition,Tokens1} = parse_ModuleDefinition(Tokens0), 54 {Types,Tokens2} = parse_AssignmentList(Tokens1), 55 case Tokens2 of 56 [{'END',_}|_Rest3] -> 57 {ok,ModuleDefinition#module{typeorval=Types}}; 58 _ -> 59 parse_error(Tokens2) 60 end. 61 62clean_process_dictionary() -> 63 Mod = erase(asn1_module), 64 _ = erase({Mod,imports}), 65 _ = erase(tagdefault), 66 _ = erase(extensiondefault), 67 ok. 68 69format_error({syntax_error,Token}) when is_atom(Token) -> 70 io_lib:format("syntax error before: '~s'", [Token]); 71format_error({syntax_error,Token}) -> 72 io_lib:format("syntax error before: '~p'", [Token]). 73 74parse_ModuleDefinition([{typereference,L1,ModuleIdentifier}|Rest0]) -> 75 put(asn1_module,ModuleIdentifier), 76 {_DefinitiveIdentifier,Rest02} = 77 case Rest0 of 78 [{'{',_}|_Rest01] -> 79 parse_ObjectIdentifierValue(Rest0); 80 _ -> 81 {[],Rest0} 82 end, 83 Rest = case Rest02 of 84 [{'DEFINITIONS',_}|Rest03] -> 85 Rest03; 86 _ -> 87 parse_error(Rest02) 88 end, 89 {TagDefault,Rest2} = 90 case Rest of 91 [{'EXPLICIT',_L3},{'TAGS',_L4}|Rest1] -> 92 put(tagdefault,'EXPLICIT'), {'EXPLICIT',Rest1}; 93 [{'IMPLICIT',_L3},{'TAGS',_L4}|Rest1] -> 94 put(tagdefault,'IMPLICIT'), {'IMPLICIT',Rest1}; 95 [{'AUTOMATIC',_L3},{'TAGS',_L4}|Rest1] -> 96 put(tagdefault,'AUTOMATIC'), {'AUTOMATIC',Rest1}; 97 Rest1 -> 98 put(tagdefault,'EXPLICIT'), {'EXPLICIT',Rest1} % The default 99 end, 100 {ExtensionDefault,Rest3} = 101 case Rest2 of 102 [{'EXTENSIBILITY',_L5}, {'IMPLIED',_L6}|Rest21] -> 103 put(extensiondefault,'IMPLIED'),{'IMPLIED',Rest21}; 104 _ -> 105 put(extensiondefault,undefined),{undefined,Rest2} 106 end, 107 case Rest3 of 108 [{'::=',_L7}, {'BEGIN',_L8}|Rest4] -> 109 {Exports, Rest5} = parse_Exports(Rest4), 110 {{imports, Imports}, Rest6} = parse_Imports(Rest5), 111 put({get(asn1_module), imports}, Imports), 112 {#module{ pos = L1, 113 name = ModuleIdentifier, 114 defid = [], % fix this 115 tagdefault = TagDefault, 116 extensiondefault = ExtensionDefault, 117 exports = Exports, 118 imports = {imports, Imports}}, Rest6}; 119 _ -> 120 parse_error(Rest3) 121 end; 122parse_ModuleDefinition(Tokens) -> 123 parse_error(Tokens). 124 125parse_Exports([{'EXPORTS',_L1},{';',_L2}|Rest]) -> 126 {{exports,[]},Rest}; 127parse_Exports([{'EXPORTS',_},{'ALL',_},{';',_}|Rest]) -> 128 %% Same as no exports definition. 129 {{exports,all},Rest}; 130parse_Exports([{'EXPORTS',_L1}|Rest]) -> 131 {SymbolList,Rest2} = parse_SymbolList(Rest), 132 case Rest2 of 133 [{';',_}|Rest3] -> 134 {{exports,SymbolList},Rest3}; 135 _ -> 136 parse_error(Rest2) 137 end; 138parse_Exports(Rest) -> 139 {{exports,all},Rest}. 140 141parse_SymbolList(Tokens) -> 142 parse_SymbolList(Tokens,[]). 143 144parse_SymbolList(Tokens,Acc) -> 145 {Symbol,Rest} = parse_Symbol(Tokens), 146 case Rest of 147 [{',',_L1}|Rest2] -> 148 parse_SymbolList(Rest2,[Symbol|Acc]); 149 Rest2 -> 150 {lists:reverse(Acc, [Symbol]),Rest2} 151 end. 152 153parse_Symbol(Tokens) -> 154 parse_Reference(Tokens). 155 156parse_Reference([{typereference,L1,TrefName},{'{',_L2},{'}',_L3}|Rest]) -> 157 {tref2Exttref(L1,TrefName),Rest}; 158parse_Reference([Tref1 = {typereference,_,_},{'.',_},Tref2 = {typereference,_,_}, 159 {'{',_L2},{'}',_L3}|Rest]) -> 160 {{tref2Exttref(Tref1),tref2Exttref(Tref2)},Rest}; 161parse_Reference([Tref = {typereference,_L1,_TrefName}|Rest]) -> 162 {tref2Exttref(Tref),Rest}; 163parse_Reference([#identifier{}=Vref,{'{',_L2},{'}',_L3}|Rest]) -> 164 {identifier2Extvalueref(Vref),Rest}; 165parse_Reference([#identifier{}=Vref|Rest]) -> 166 {identifier2Extvalueref(Vref),Rest}; 167parse_Reference(Tokens) -> 168 parse_error(Tokens). 169 170parse_Imports([{'IMPORTS',_L1},{';',_L2}|Rest]) -> 171 {{imports,[]},Rest}; 172parse_Imports([{'IMPORTS',_L1}|Rest]) -> 173 {SymbolsFromModuleList,Rest2} = parse_SymbolsFromModuleList(Rest), 174 case Rest2 of 175 [{';',_L2}|Rest3] -> 176 {{imports,SymbolsFromModuleList},Rest3}; 177 _ -> 178 parse_error(Rest2) 179 end; 180parse_Imports(Tokens) -> 181 {{imports,[]},Tokens}. 182 183parse_SymbolsFromModuleList(Tokens) -> 184 parse_SymbolsFromModuleList(Tokens,[]). 185 186parse_SymbolsFromModuleList(Tokens,Acc) -> 187 {SymbolsFromModule,Rest} = parse_SymbolsFromModule(Tokens), 188 try parse_SymbolsFromModule(Rest) of 189 {Sl,_Rest2} when is_record(Sl,'SymbolsFromModule') -> 190 parse_SymbolsFromModuleList(Rest, [SymbolsFromModule|Acc]) 191 catch 192 throw:{asn1_error,_} -> 193 {lists:reverse(Acc, [SymbolsFromModule]),Rest} 194 end. 195 196parse_SymbolsFromModule(Tokens) -> 197 SetRefModuleName = 198 fun(N) -> 199 fun(X) when is_record(X,'Externaltypereference')-> 200 X#'Externaltypereference'{module=N}; 201 (X) when is_record(X,'Externalvaluereference')-> 202 X#'Externalvaluereference'{module=N} 203 end 204 end, 205 {SymbolList,Rest} = parse_SymbolList(Tokens), 206 case Rest of 207 [{'FROM',_L1},{typereference,_,Name}=Tref| 208 [#identifier{},{',',_}|_]=Rest2] -> 209 NewSymbolList = lists:map(SetRefModuleName(Name), SymbolList), 210 {#'SymbolsFromModule'{symbols=NewSymbolList, 211 module=tref2Exttref(Tref)},Rest2}; 212 213 %% This a special case when there is only one Symbol imported 214 %% from the next module. No other way to distinguish Ref from 215 %% a part of the GlobalModuleReference of Name. 216 [{'FROM',_L1},{typereference,_,Name}=Tref| 217 [#identifier{},{'FROM',_}|_]=Rest2] -> 218 NewSymbolList = lists:map(SetRefModuleName(Name), SymbolList), 219 {#'SymbolsFromModule'{symbols=NewSymbolList, 220 module=tref2Exttref(Tref)},Rest2}; 221 [{'FROM',_L1},{typereference,_,Name}=Tref,#identifier{}|Rest2] -> 222 NewSymbolList = lists:map(SetRefModuleName(Name), SymbolList), 223 {#'SymbolsFromModule'{symbols=NewSymbolList, 224 module=tref2Exttref(Tref)},Rest2}; 225 [{'FROM',_L1},{typereference,_,Name}=Tref|[{'{',_}|_]=Rest2] -> 226 {_ObjIdVal,Rest3} = parse_ObjectIdentifierValue(Rest2), % value not used yet, fix me 227 NewSymbolList = lists:map(SetRefModuleName(Name), SymbolList), 228 {#'SymbolsFromModule'{symbols=NewSymbolList, 229 module=tref2Exttref(Tref)},Rest3}; 230 [{'FROM',_L1},{typereference,_,Name}=Tref|Rest2] -> 231 NewSymbolList = lists:map(SetRefModuleName(Name), SymbolList), 232 {#'SymbolsFromModule'{symbols=NewSymbolList, 233 module=tref2Exttref(Tref)},Rest2}; 234 _ -> 235 parse_error(Rest) 236 end. 237 238parse_ObjectIdentifierValue([{'{',_}|Rest]) -> 239 parse_ObjectIdentifierValue(Rest,[]). 240 241parse_ObjectIdentifierValue([{number,_,Num}|Rest], Acc) -> 242 parse_ObjectIdentifierValue(Rest,[Num|Acc]); 243parse_ObjectIdentifierValue([#identifier{val=Id},{'(',_},{number,_,Num},{')',_}|Rest], Acc) -> 244 parse_ObjectIdentifierValue(Rest,[{'NamedNumber',Id,Num}|Acc]); 245parse_ObjectIdentifierValue([#identifier{val=Id},{'(',_},#identifier{val=Id2},{')',_}|Rest], Acc) -> 246 parse_ObjectIdentifierValue(Rest,[{'NamedNumber',Id,Id2}|Acc]); 247parse_ObjectIdentifierValue([#identifier{val=Id},{'(',_},{typereference,_,Tref},{'.',_},#identifier{val=Id2}, {')',_}|Rest], Acc) -> 248 parse_ObjectIdentifierValue(Rest, [{'NamedNumber',Id,{'ExternalValue',Tref,Id2}}|Acc]); 249parse_ObjectIdentifierValue([#identifier{}=Id|Rest], Acc) -> 250 parse_ObjectIdentifierValue(Rest, [identifier2Extvalueref(Id)|Acc]); 251parse_ObjectIdentifierValue([{'}',_}|Rest], Acc) -> 252 {lists:reverse(Acc),Rest}; 253parse_ObjectIdentifierValue(Tokens, _Acc) -> 254 parse_error(Tokens). 255 256parse_AssignmentList(Tokens) -> 257 parse_AssignmentList(Tokens, []). 258 259parse_AssignmentList([{'END',_}|_]=Tokens, Acc) -> 260 {lists:reverse(Acc),Tokens}; 261parse_AssignmentList([{'$end',_}|_]=Tokens, Acc) -> 262 {lists:reverse(Acc),Tokens}; 263parse_AssignmentList(Tokens0, Acc) -> 264 {Assignment,Tokens} = parse_Assignment(Tokens0), 265 parse_AssignmentList(Tokens, [Assignment|Acc]). 266 267parse_Assignment([{typereference,L1,Name},{'::=',_}|Tokens0]) -> 268 %% 1) Type ::= TypeDefinition 269 %% 2) CLASS-NAME ::= CLASS {...} 270 Flist = [{type,fun parse_Type/1}, 271 {class,fun parse_ObjectClass/1}], 272 case parse_or_tag(Tokens0, Flist) of 273 {{type,Type},Tokens} -> 274 %% TypeAssignment 275 {#typedef{pos=L1,name=Name,typespec=Type},Tokens}; 276 {{class,Type},Tokens} -> 277 %% ObjectClassAssignment 278 {#classdef{pos=L1,name=Name,module=resolve_module(Type), 279 typespec=Type},Tokens} 280 end; 281parse_Assignment([{typereference,_,_},{'{',_}|_]=Tokens) -> 282 %% 1) Type{...} ::= ... 283 %% 2) ValueSet{...} Type ::= ... 284 %% ObjectSet{...} CLASS-NAME ::= CLASS {...} 285 %% 3) CLASS-NAME{...} ::= CLASS {...} 286 %% A parameterized value set and and a parameterized object set 287 %% cannot be distinguished from each other without type information. 288 Flist = [fun parse_ParameterizedTypeAssignment/1, 289 fun parse_ParameterizedValueSetTypeAssignment/1, 290 fun parse_ParameterizedObjectClassAssignment/1], 291 parse_or(Tokens, Flist); 292parse_Assignment([{typereference,_,_}|_]=Tokens) -> 293 %% 1) ObjectSet CLASS-NAME ::= ... 294 %% 2) ValueSet Type ::= ... 295 Flist = [fun parse_ObjectSetAssignment/1, 296 fun parse_ValueSetTypeAssignment/1], 297 parse_or(Tokens, Flist); 298parse_Assignment([#identifier{},{'{',_}|_]=Tokens) -> 299 %% 1) value{...} Type ::= ... 300 %% 2) object{...} CLASS-NAME ::= ... 301 Flist = [fun parse_ParameterizedValueAssignment/1, 302 fun parse_ParameterizedObjectAssignment/1], 303 parse_or(Tokens, Flist); 304parse_Assignment([#identifier{}|_]=Tokens) -> 305 %% 1) value Type ::= ... 306 %% 2) object CLASS-NAME ::= ... 307 Flist = [fun parse_ValueAssignment/1, 308 fun parse_ObjectAssignment/1], 309 parse_or(Tokens, Flist); 310parse_Assignment(Tokens) -> 311 parse_error(Tokens). 312 313parse_or(Tokens,Flist) -> 314 parse_or(Tokens,Flist,[]). 315 316parse_or(Tokens, [Fun|Funs], ErrList) when is_function(Fun, 1) -> 317 try Fun(Tokens) of 318 {_,Rest}=Result when is_list(Rest) -> 319 Result 320 catch 321 throw:{asn1_error,Error} -> 322 parse_or(Tokens, Funs, [Error|ErrList]) 323 end; 324parse_or(_Tokens, [], ErrList) -> 325 throw({asn1_error,fun() -> prioritize_error(ErrList) end}). 326 327parse_or_tag(Tokens, Flist) -> 328 parse_or_tag(Tokens, Flist, []). 329 330parse_or_tag(Tokens, [{Tag,Fun}|Funs], ErrList) when is_function(Fun, 1) -> 331 try Fun(Tokens) of 332 {Parsed,Rest} when is_list(Rest) -> 333 {{Tag,Parsed},Rest} 334 catch 335 throw:{asn1_error,Error} -> 336 parse_or_tag(Tokens, Funs, [Error|ErrList]) 337 end; 338parse_or_tag(_Tokens, [], ErrList) -> 339 throw({asn1_error,fun() -> prioritize_error(ErrList) end}). 340 341prioritize_error(Errors0) -> 342 Errors1 = prioritize_error_1(Errors0), 343 Errors2 = [{length(L),L} || L <- Errors1], 344 Errors = lists:sort(Errors2), 345 [Res|_] = [L || {_,L} <- Errors], 346 Res. 347 348prioritize_error_1([F|T]) when is_function(F, 0) -> 349 [F()|prioritize_error_1(T)]; 350prioritize_error_1([{parse_error,Tokens}|T]) -> 351 [Tokens|prioritize_error_1(T)]; 352prioritize_error_1([]) -> 353 []. 354 355 356%% parse_Type(Tokens) -> Ret 357%% 358%% Tokens = [Tok] 359%% Tok = tuple() 360%% Ret = #type{} 361%% 362parse_Type(Tokens) -> 363 {Tag,Rest3} = case Tokens of 364 [{'[',_}|_] -> parse_Tag(Tokens); 365 _ -> {[],Tokens} 366 end, 367 {Tag2,Rest4} = case Rest3 of 368 [{'IMPLICIT',_}|Rest31] when is_record(Tag,tag)-> 369 {[Tag#tag{type='IMPLICIT'}],Rest31}; 370 [{'EXPLICIT',_}|Rest31] when is_record(Tag,tag)-> 371 {[Tag#tag{type='EXPLICIT'}],Rest31}; 372 Rest31 when is_record(Tag,tag) -> 373 {[Tag#tag{type={default,get(tagdefault)}}],Rest31}; 374 Rest31 -> 375 {Tag,Rest31} 376 end, 377 Flist = [fun parse_BuiltinType/1, 378 fun parse_ReferencedType/1, 379 fun parse_TypeWithConstraint/1], 380 {Type,Rest5} = parse_or(Rest4, Flist), 381 case Rest5 of 382 [{'(',_}|_] -> 383 {Constraints,Rest6} = parse_Constraints(Rest5), 384 {Type#type{tag=Tag2, 385 constraint=merge_constraints(Constraints)},Rest6}; 386 [_|_] -> 387 {Type#type{tag=Tag2},Rest5} 388 end. 389 390parse_BuiltinType([{'BIT',_},{'STRING',_}|Rest]) -> 391 case Rest of 392 [{'{',_}|Rest2] -> 393 {NamedNumberList,Rest3} = parse_NamedNumberList(Rest2), 394 case Rest3 of 395 [{'}',_}|Rest4] -> 396 {#type{def={'BIT STRING',NamedNumberList}},Rest4}; 397 _ -> 398 parse_error(Rest3) 399 end; 400 _ -> 401 {#type{def={'BIT STRING',[]}},Rest} 402 end; 403parse_BuiltinType([{'BOOLEAN',_}|Rest]) -> 404 {#type{def='BOOLEAN'},Rest}; 405%% CharacterStringType ::= RestrictedCharacterStringType | 406%% UnrestrictedCharacterStringType 407parse_BuiltinType([{restrictedcharacterstringtype,_,StringName}|Rest]) -> 408 {#type{def=StringName},Rest}; 409parse_BuiltinType([{'CHARACTER',_},{'STRING',_}|Rest]) -> 410 {#type{def='CHARACTER STRING'},Rest}; 411 412parse_BuiltinType([{'CHOICE',_},{'{',_}|Rest]) -> 413 {L0,Rest2} = parse_AlternativeTypeLists(Rest), 414 case Rest2 of 415 [{'}',_}|Rest3] -> 416 NeedExt = not lists:keymember('EXTENSIONMARK', 1, L0) andalso 417 get(extensiondefault) =:= 'IMPLIED', 418 L = case NeedExt of 419 true -> 420 L0 ++ [#'EXTENSIONMARK'{}]; 421 false -> 422 L0 423 end, 424 {#type{def={'CHOICE',L}},Rest3}; 425 _ -> 426 parse_error(Rest2) 427 end; 428parse_BuiltinType([{'EMBEDDED',_},{'PDV',_}|Rest]) -> 429 {#type{def='EMBEDDED PDV'},Rest}; 430parse_BuiltinType([{'ENUMERATED',_},{'{',_}|Rest]) -> 431 {Enumerations,Rest2} = parse_Enumerations(Rest), 432 case Rest2 of 433 [{'}',_}|Rest3] -> 434 {#type{def={'ENUMERATED',Enumerations}},Rest3}; 435 _ -> 436 parse_error(Rest2) 437 end; 438parse_BuiltinType([{'EXTERNAL',_}|Rest]) -> 439 {#type{def='EXTERNAL'},Rest}; 440parse_BuiltinType([{'INSTANCE',_},{'OF',_}|Rest]) -> 441 {DefinedObjectClass,Rest2} = parse_DefinedObjectClass(Rest), 442 case Rest2 of 443 [{'(',_}|_] -> 444 {Constraint0,Rest3} = parse_Constraint(Rest2), 445 Constraint = merge_constraints([Constraint0]), 446 {#type{def={'INSTANCE OF',DefinedObjectClass,Constraint}},Rest3}; 447 _ -> 448 {#type{def={'INSTANCE OF',DefinedObjectClass,[]}},Rest2} 449 end; 450parse_BuiltinType([{'INTEGER',_}|Rest]) -> 451 case Rest of 452 [{'{',_}|Rest2] -> 453 {NamedNumberList,Rest3} = parse_NamedNumberList(Rest2), 454 case Rest3 of 455 [{'}',_}|Rest4] -> 456 {#type{def={'INTEGER',NamedNumberList}},Rest4}; 457 _ -> 458 parse_error(Rest3) 459 end; 460 _ -> 461 {#type{def='INTEGER'},Rest} 462 end; 463parse_BuiltinType([{'NULL',_}|Rest]) -> 464 {#type{def='NULL'},Rest}; 465parse_BuiltinType([{'OBJECT',_},{'IDENTIFIER',_}|Rest]) -> 466 {#type{def='OBJECT IDENTIFIER'},Rest}; 467parse_BuiltinType([{'OCTET',_},{'STRING',_}|Rest]) -> 468 {#type{def='OCTET STRING'},Rest}; 469parse_BuiltinType([{'REAL',_}|Rest]) -> 470 {#type{def='REAL'},Rest}; 471parse_BuiltinType([{'RELATIVE-OID',_}|Rest]) -> 472 {#type{def='RELATIVE-OID'},Rest}; 473parse_BuiltinType([{'SEQUENCE',_},{'{',_},{'}',_}|Rest]) -> 474 {#type{def=#'SEQUENCE'{components=[]}}, 475 Rest}; 476parse_BuiltinType([{'SEQUENCE',_},{'{',_},{'...',Line},{'}',_}|Rest]) -> 477 {#type{def=#'SEQUENCE'{components=[#'EXTENSIONMARK'{pos = Line}]}},Rest}; 478parse_BuiltinType([{'SEQUENCE',_},{'{',_},{'...',Line},{'!',_}|Rest]) -> 479 {ExceptionIdentification,Rest2} = parse_ExceptionIdentification(Rest), 480 case Rest2 of 481 [{'}',_}|Rest3] -> 482 {#type{def=#'SEQUENCE'{ 483 components=[#'EXTENSIONMARK'{ 484 pos = Line, 485 val = ExceptionIdentification}]}}, 486 Rest3}; 487 _ -> 488 {ComponentTypeLists,Rest3}= 489 parse_ComponentTypeLists2(Rest2,[#'EXTENSIONMARK'{pos=Line}]), 490 case Rest3 of 491 [{'}',_}|Rest4] -> 492 {#type{def=#'SEQUENCE'{components=ComponentTypeLists}},Rest4}; 493 _ -> 494 parse_error(Rest3) 495 end 496 end; 497parse_BuiltinType([{'SEQUENCE',_},{'{',_}|Rest]) -> 498 {ComponentTypeLists,Rest2} = parse_ComponentTypeLists(Rest), 499 case Rest2 of 500 [{'}',_}|Rest3] -> 501 ComponentTypeLists2 = 502 case {[Ext||Ext = #'EXTENSIONMARK'{} <- ComponentTypeLists], 503 get(extensiondefault)} of 504 {[],'IMPLIED'} -> ComponentTypeLists ++ [#'EXTENSIONMARK'{}]; 505 _ -> ComponentTypeLists 506 end, 507 {#type{def=#'SEQUENCE'{components = ComponentTypeLists2}}, 508 Rest3}; 509 _ -> 510 parse_error(Rest2) 511 end; 512parse_BuiltinType([{'SEQUENCE',_},{'OF',_}| 513 [#identifier{},{'<',_}|_]=Tokens0]) -> 514 {Type,Tokens} = parse_SelectionType(Tokens0), 515 {#type{def={'SEQUENCE OF',Type}},Tokens}; 516parse_BuiltinType([{'SEQUENCE',_},{'OF',_},#identifier{} |Rest]) -> 517%% TODO: take care of the identifier for something useful 518 {Type,Rest2} = parse_Type(Rest), 519 {#type{def={'SEQUENCE OF',Type}},Rest2}; 520parse_BuiltinType([{'SEQUENCE',_},{'OF',_}|Rest]) -> 521 {Type,Rest2} = parse_Type(Rest), 522 {#type{def={'SEQUENCE OF',Type}},Rest2}; 523parse_BuiltinType([{'SET',_},{'{',_},{'...',Line},{'}',_}|Rest]) -> 524 {#type{def=#'SET'{components=[#'EXTENSIONMARK'{pos = Line}]}},Rest}; 525parse_BuiltinType([{'SET',_},{'{',_},{'...',Line},{'!',_}|Rest]) -> 526 {ExceptionIdentification,Rest2} = parse_ExceptionIdentification(Rest), 527 case Rest2 of 528 [{'}',_}|Rest3] -> 529 {#type{def=#'SET'{components= 530 [#'EXTENSIONMARK'{pos = Line, 531 val = ExceptionIdentification}]}}, 532 Rest3}; 533 _ -> 534 {ComponentTypeLists,Rest3}= 535 parse_ComponentTypeLists2(Rest2,[#'EXTENSIONMARK'{pos=Line}]), 536 case Rest3 of 537 [{'}',_}|Rest4] -> 538 {#type{def=#'SET'{components=ComponentTypeLists}},Rest4}; 539 _ -> 540 parse_error(Rest3) 541 end 542 end; 543parse_BuiltinType([{'SET',_},{'{',_}|Rest]) -> 544 {ComponentTypeLists,Rest2} = parse_ComponentTypeLists(Rest), 545 case Rest2 of 546 [{'}',_}|Rest3] -> 547 ComponentTypeLists2 = 548 case {[Ext||Ext = #'EXTENSIONMARK'{} <- ComponentTypeLists], 549 get(extensiondefault)} of 550 {[],'IMPLIED'} -> ComponentTypeLists ++ [#'EXTENSIONMARK'{}]; 551 _ -> ComponentTypeLists 552 end, 553 {#type{def=#'SET'{components = ComponentTypeLists2}}, 554 Rest3}; 555 _ -> 556 parse_error(Rest2) 557 end; 558parse_BuiltinType([{'SET',_},{'OF',_}| 559 [#identifier{},{'<',_}|_]=Tokens0]) -> 560 {Type,Tokens} = parse_SelectionType(Tokens0), 561 {#type{def={'SET OF',Type}},Tokens}; 562parse_BuiltinType([{'SET',_},{'OF',_},#identifier{}|Rest]) -> 563%%TODO: take care of the identifier for something useful 564 {Type,Rest2} = parse_Type(Rest), 565 {#type{def={'SET OF',Type}},Rest2}; 566parse_BuiltinType([{'SET',_},{'OF',_}|Rest]) -> 567 {Type,Rest2} = parse_Type(Rest), 568 {#type{def={'SET OF',Type}},Rest2}; 569parse_BuiltinType([{'GeneralizedTime',_}|Rest]) -> 570 {#type{def='GeneralizedTime'},Rest}; 571parse_BuiltinType([{'UTCTime',_}|Rest]) -> 572 {#type{def='UTCTime'},Rest}; 573parse_BuiltinType([{'ObjectDescriptor',_}|Rest]) -> 574 {#type{def='ObjectDescriptor'},Rest}; 575parse_BuiltinType([{'ANY',_},{'DEFINED',_},{'BY',_},#identifier{val=Id}|Rest]) -> 576 %% For compatibility with the old standard. 577 {#type{def={'ANY_DEFINED_BY',Id}},Rest}; 578parse_BuiltinType([{'ANY',_}|Rest]) -> 579 %% For compatibility with the old standard. 580 {#type{def='ANY'},Rest}; 581parse_BuiltinType(Tokens) -> 582 parse_ObjectClassFieldType(Tokens). 583 584 585parse_TypeWithConstraint([{'SEQUENCE',_}|[{'(',_}|_]=Rest0]) -> 586 {Constraint,Rest2} = parse_Constraint(Rest0), 587 Rest4 = case Rest2 of 588 [{'OF',_},#identifier{}|Rest3] -> 589%%% TODO: make some use of the identifier, maybe useful in the XML mapping 590 Rest3; 591 [{'OF',_}|Rest3] -> 592 Rest3; 593 _ -> 594 parse_error(Rest2) 595 end, 596 {Type,Rest5} = parse_Type(Rest4), 597 {#type{def = {'SEQUENCE OF',Type}, 598 constraint = merge_constraints([Constraint])},Rest5}; 599 600parse_TypeWithConstraint([{'SEQUENCE',_},{'SIZE',_}|[{'(',_}|_]=Rest0]) -> 601 {Constraint,Rest2} = parse_Constraint(Rest0), 602 #constraint{c=C} = Constraint, 603 Constraint2 = Constraint#constraint{c={element_set,{'SizeConstraint',C}, 604 none}}, 605 Rest4 = case Rest2 of 606 [{'OF',_},#identifier{}|Rest3] -> 607%%% TODO: make some use of the identifier, maybe useful in the XML mapping 608 Rest3; 609 [{'OF',_}|Rest3] -> 610 Rest3; 611 _ -> 612 parse_error(Rest2) 613 end, 614 {Type,Rest5} = parse_Type(Rest4), 615 {#type{def = {'SEQUENCE OF',Type}, constraint = merge_constraints([Constraint2])},Rest5}; 616 617parse_TypeWithConstraint([{'SET',_}|[{'(',_}|_]=Rest0]) -> 618 {Constraint,Rest2} = parse_Constraint(Rest0), 619 Rest4 = case Rest2 of 620 [{'OF',_},#identifier{}|Rest3] -> 621%%% TODO: make some use of the identifier, maybe useful in the XML mapping 622 Rest3; 623 [{'OF',_}|Rest3] -> 624 Rest3; 625 _ -> 626 parse_error(Rest2) 627 end, 628 {Type,Rest5} = parse_Type(Rest4), 629 {#type{def = {'SET OF',Type}, 630 constraint = merge_constraints([Constraint])},Rest5}; 631 632parse_TypeWithConstraint([{'SET',_},{'SIZE',_}|[{'(',_}|_]=Rest0]) -> 633 {Constraint,Rest2} = parse_Constraint(Rest0), 634 #constraint{c=C} = Constraint, 635 Constraint2 = Constraint#constraint{c={element_set, 636 {'SizeConstraint',C},none}}, 637 Rest4 = case Rest2 of 638 [{'OF',_},#identifier{}|Rest3] -> 639%%% TODO: make some use of the identifier, maybe useful in the XML mapping 640 Rest3; 641 [{'OF',_}|Rest3] -> 642 Rest3; 643 _ -> 644 parse_error(Rest2) 645 end, 646 {Type,Rest5} = parse_Type(Rest4), 647 {#type{def = {'SET OF',Type}, 648 constraint = merge_constraints([Constraint2])},Rest5}; 649 650parse_TypeWithConstraint(Tokens) -> 651 parse_error(Tokens). 652 653 654%% -------------------------- 655 656parse_ReferencedType(Tokens) -> 657 Flist = [fun parse_ParameterizedType/1, 658 fun parse_DefinedType/1, 659 fun parse_SelectionType/1, 660 fun parse_TypeFromObject/1], 661 parse_or(Tokens, Flist). 662 663parse_DefinedType([{typereference,L1,Module}, 664 {'.',_}, 665 {typereference,_,TypeName}|Tokens]) -> 666 {#type{def = #'Externaltypereference'{pos=L1,module=Module, 667 type=TypeName}},Tokens}; 668parse_DefinedType([{typereference,_,_}=Tr|Tokens]) -> 669 {#type{def=tref2Exttref(Tr)},Tokens}; 670parse_DefinedType(Tokens) -> 671 parse_error(Tokens). 672 673parse_SelectionType([#identifier{val=Name},{'<',_}|Rest]) -> 674 {Type,Rest2} = parse_Type(Rest), 675 {#type{def={'SelectionType',Name,Type}},Rest2}; 676parse_SelectionType(Tokens) -> 677 parse_error(Tokens). 678 679 680resolve_module(Type) -> 681 Current = get(asn1_module), 682 Imports = get({Current, imports}), 683 resolve_module(Type, Current, Imports). 684 685resolve_module(_Type, Current, undefined) -> 686 Current; 687resolve_module(Type, Current, Imports) -> 688 case [Mod || #'SymbolsFromModule'{symbols = S, module = Mod} <- Imports, 689 #'Externaltypereference'{type = T} <- S, 690 Type =:= T] of 691 [#'Externaltypereference'{type = Mod}|_] -> Mod; 692 %% This allows the same symbol to be imported several times 693 %% which ought to be checked elsewhere and flagged as an error 694 [] -> Current 695 end. 696 697 698parse_Constraints(Tokens) -> 699 parse_Constraints(Tokens,[]). 700 701parse_Constraints(Tokens,Acc) -> 702 {Constraint,Rest} = parse_Constraint(Tokens), 703 case Rest of 704 [{'(',_}|_Rest2] -> 705 parse_Constraints(Rest, [Constraint|Acc]); 706 _ -> 707 {lists:reverse(Acc, [Constraint]),Rest} 708 end. 709 710parse_Constraint([{'(',_}|Rest]) -> 711 {Constraint,Rest2} = parse_ConstraintSpec(Rest), 712 {Exception,Rest3} = parse_ExceptionSpec(Rest2), 713 case Rest3 of 714 [{')',_}|Rest4] -> 715 {#constraint{c=Constraint,e=Exception},Rest4}; 716 [_|_] -> 717 parse_error(Rest3) 718 end. 719 720parse_ConstraintSpec(Tokens) -> 721 Flist = [fun parse_GeneralConstraint/1, 722 fun parse_SubtypeConstraint/1], 723 parse_or(Tokens, Flist). 724 725parse_ExceptionSpec([LPar={')',_}|Rest]) -> 726 {undefined,[LPar|Rest]}; 727parse_ExceptionSpec([{'!',_}|Rest]) -> 728 parse_ExceptionIdentification(Rest); 729parse_ExceptionSpec(Tokens) -> 730 parse_error(Tokens). 731 732parse_ExceptionIdentification(Tokens) -> 733 Flist = [fun parse_SignedNumber/1, 734 fun parse_DefinedValue/1, 735 fun parse_TypeColonValue/1], 736 parse_or(Tokens, Flist). 737 738parse_TypeColonValue(Tokens) -> 739 {Type,Rest} = parse_Type(Tokens), 740 case Rest of 741 [{':',_}|Rest2] -> 742 {Value,Rest3} = parse_Value(Rest2), 743 {{Type,Value},Rest3}; 744 [_|_] -> 745 parse_error(Rest) 746 end. 747 748parse_SubtypeConstraint(Tokens) -> 749 parse_ElementSetSpecs(Tokens). 750 751parse_ElementSetSpecs(Tokens) -> 752 {RootElems,Rest} = parse_ElementSetSpec(Tokens), 753 case Rest of 754 [{',',_},{'...',_},{',',_}|Rest2] -> 755 {AdditionalElems,Rest3} = parse_ElementSetSpec(Rest2), 756 {{element_set,RootElems,AdditionalElems},Rest3}; 757 [{',',_},{'...',_}|Rest2] -> 758 {{element_set,RootElems,empty},Rest2}; 759 _ -> 760 {{element_set,RootElems,none},Rest} 761 end. 762 763parse_ElementSetSpec([{'ALL',_},{'EXCEPT',_}|Rest]) -> 764 {Exclusions,Rest2} = parse_Elements(Rest), 765 {{'ALL-EXCEPT',Exclusions},Rest2}; 766parse_ElementSetSpec(Tokens) -> 767 parse_Unions(Tokens). 768 769 770%% parse_Unions(Tokens) -> {Ret,Rest} 771%% Tokens = [Tok] 772%% Tok = tuple() 773%% Ret = {'SingleValue',list()} | list() | 774%% 775parse_Unions(Tokens) -> 776 {InterSec,Rest} = parse_Intersections(Tokens), 777 {Unions,Rest2} = parse_UnionsRec(Rest), 778 case {InterSec,Unions} of 779 {InterSec,[]} -> 780 {InterSec,Rest2}; 781 {V1,V2} -> 782 {{union,V1,V2},Rest2} 783 end. 784 785parse_UnionsRec([{'|',_}|Rest]) -> 786 {InterSec,Rest2} = parse_Intersections(Rest), 787 {URec,Rest3} = parse_UnionsRec(Rest2), 788 case {InterSec,URec} of 789 {V1,[]} -> 790 {V1,Rest3}; 791 {V1,V2} -> 792 {{union,V1,V2},Rest3} 793 end; 794parse_UnionsRec([{'UNION',Info}|Rest]) -> 795 parse_UnionsRec([{'|',Info}|Rest]); 796parse_UnionsRec(Tokens) -> 797 {[],Tokens}. 798 799parse_Intersections(Tokens) -> 800 {InterSec,Rest} = parse_IntersectionElements(Tokens), 801 {IRec,Rest2} = parse_IElemsRec(Rest), 802 case {InterSec,IRec} of 803 {V1,[]} -> 804 {V1,Rest2}; 805 {V1,V2} -> 806 {{intersection,V1,V2},Rest2} 807 end. 808 809%% parse_IElemsRec(Tokens) -> Result 810%% Result ::= {'SingleValue',ordered_set()} | list() 811parse_IElemsRec([{'^',_}|Rest]) -> 812 {InterSec,Rest2} = parse_IntersectionElements(Rest), 813 {IRec,Rest3} = parse_IElemsRec(Rest2), 814 case {InterSec,IRec} of 815 {V1,[]} -> 816 {V1,Rest2}; 817 {V1,V2} -> 818 {{intersection,V1,V2},Rest3} 819 end; 820parse_IElemsRec([{'INTERSECTION',Info}|Rest]) -> 821 parse_IElemsRec([{'^',Info}|Rest]); 822parse_IElemsRec(Tokens) -> 823 {[],Tokens}. 824 825%% parse_IntersectionElements(Tokens) -> {Result,Rest} 826%% Result ::= InterSec | {InterSec,{'EXCEPT',Exclusion}} 827%% InterSec ::= {'ALL',{'EXCEPT',Exclusions}} | Unions 828%% Unions ::= {'SingleValue',list()} | list() (see parse_Unions) 829%% Exclusions ::= InterSec 830parse_IntersectionElements(Tokens) -> 831 {InterSec,Rest} = parse_Elements(Tokens), 832 case Rest of 833 [{'EXCEPT',_}|Rest2] -> 834 {Exclusion,Rest3} = parse_Elements(Rest2), 835 {{'EXCEPT',InterSec,Exclusion},Rest3}; 836 Rest -> 837 {InterSec,Rest} 838 end. 839 840%% parse_Elements(Tokens) -> {Result,Rest} 841%% Result ::= {'ALL',{'EXCEPT',Exclusions}} | Unions 842%% Exclusions ::= {'ALL',{'EXCEPT',Exclusions}} | Unions 843%% Unions ::= {'SingleValue',list()} | list() (see parse_Unions) 844parse_Elements([{'(',_}|Rest]) -> 845 {Elems,Rest2} = parse_ElementSetSpec(Rest), 846 case Rest2 of 847 [{')',_}|Rest3] -> 848 {Elems,Rest3}; 849 [_|_] -> 850 parse_error(Rest2) 851 end; 852parse_Elements(Tokens) -> 853 Flist = [fun parse_ObjectSetElements/1, 854 fun parse_SubtypeElements/1, 855 fun parse_Object/1, 856 fun parse_DefinedObjectSet/1], 857 parse_or(Tokens, Flist). 858 859 860%% -------------------------- 861 862parse_DefinedObjectClass([{typereference,_,ModName},{'.',_}, 863 {typereference,Pos,Name}|Tokens]) -> 864 Ext = #'Externaltypereference'{pos=Pos, 865 module=ModName, 866 type=Name}, 867 {Ext,Tokens}; 868parse_DefinedObjectClass([Tr={typereference,_,_ObjClName}|Rest]) -> 869 {tref2Exttref(Tr),Rest}; 870parse_DefinedObjectClass(Tokens) -> 871 parse_error(Tokens). 872 873parse_ObjectClass(Tokens) -> 874 Flist = [fun parse_ObjectClassDefn/1, 875 fun parse_DefinedObjectClass/1], 876 parse_or(Tokens, Flist). 877 878parse_ObjectClassDefn([{'CLASS',_},{'{',_}|Rest]) -> 879 {Type,Rest2} = parse_FieldSpec(Rest), 880 {WithSyntaxSpec,Rest3} = parse_WithSyntaxSpec(Rest2), 881 {#objectclass{fields=Type,syntax=WithSyntaxSpec},Rest3}; 882parse_ObjectClassDefn(Tokens) -> 883 parse_error(Tokens). 884 885parse_FieldSpec(Tokens) -> 886 parse_FieldSpec(Tokens,[]). 887 888parse_FieldSpec(Tokens0, Acc) -> 889 Fl = case Tokens0 of 890 [{valuefieldreference,_,_}|_] -> 891 %% 1) &field Type 892 %% &object CLASS-NAME 893 %% 2) &field &FieldName 894 %% A fixed type field cannot be distinguished from 895 %% an object field without type information. 896 [fun parse_FixedTypeValueFieldSpec/1, 897 fun parse_VariableTypeValueFieldSpec/1]; 898 [{typefieldreference,_,_}|_] -> 899 %% 1) &Set Type 900 %% &ObjectSet CLASS-NAME 901 %% 2) &Set &FieldName 902 %% 3) &Type 903 %% A value set and an object cannot be distinguished 904 %% without type information. 905 [fun parse_FixedTypeValueSetFieldSpec/1, 906 fun parse_VariableTypeValueSetFieldSpec/1, 907 fun parse_TypeFieldSpec/1]; 908 [_|_] -> 909 parse_error(Tokens0) 910 end, 911 case parse_or(Tokens0, Fl) of 912 {Type,[{'}',_}|Rest]} -> 913 {lists:reverse(Acc, [Type]),Rest}; 914 {Type,[{',',_}|Rest2]} -> 915 parse_FieldSpec(Rest2, [Type|Acc]) 916 end. 917 918parse_PrimitiveFieldName([{typefieldreference,_,FieldName}|Rest]) -> 919 {{typefieldreference,FieldName},Rest}; 920parse_PrimitiveFieldName([{valuefieldreference,_,FieldName}|Rest]) -> 921 {{valuefieldreference,FieldName},Rest}; 922parse_PrimitiveFieldName(Tokens) -> 923 parse_error(Tokens). 924 925parse_FieldName(Tokens) -> 926 {Field,Rest} = parse_PrimitiveFieldName(Tokens), 927 parse_FieldName(Rest,[Field]). 928 929parse_FieldName([{'.',_}|Rest0],Acc) -> 930 {FieldName,Rest1} = parse_PrimitiveFieldName(Rest0), 931 parse_FieldName(Rest1, [FieldName|Acc]); 932parse_FieldName(Tokens, Acc) -> 933 {lists:reverse(Acc),Tokens}. 934 935parse_FixedTypeValueFieldSpec([{valuefieldreference,_,VFieldName}|Rest]) -> 936 {Type,Rest2} = parse_Type(Rest), 937 {Unique,Rest3} = 938 case Rest2 of 939 [{'UNIQUE',_}|Rest4] -> 940 {'UNIQUE',Rest4}; 941 _ -> 942 {undefined,Rest2} 943 end, 944 {OptionalitySpec,Rest5} = parse_ValueOptionalitySpec(Rest3), 945 case is_end_delimiter(Rest5) of 946 false -> parse_error(Rest5); 947 true -> ok 948 end, 949 Tag = case Unique of 950 'UNIQUE' -> fixedtypevaluefield; 951 _ -> object_or_fixedtypevalue_field 952 end, 953 {{Tag,VFieldName,Type,Unique,OptionalitySpec},Rest5}. 954 955parse_VariableTypeValueFieldSpec([{valuefieldreference,_,VFieldName}|Rest0]) -> 956 {FieldRef,Rest1} = parse_FieldName(Rest0), 957 {OptionalitySpec,Rest} = parse_ValueOptionalitySpec(Rest1), 958 case is_end_delimiter(Rest) of 959 true -> 960 {{variabletypevaluefield,VFieldName,FieldRef,OptionalitySpec}, 961 Rest}; 962 false -> 963 parse_error(Rest) 964 end. 965 966parse_TypeFieldSpec([{typefieldreference,_,Name}|Rest0]) -> 967 {OptionalitySpec,Rest} = parse_TypeOptionalitySpec(Rest0), 968 case is_end_delimiter(Rest) of 969 true -> 970 {{typefield,Name,OptionalitySpec},Rest}; 971 false -> 972 parse_error(Rest) 973 end. 974 975parse_FixedTypeValueSetFieldSpec([{typefieldreference,_,Name}|Rest0]) -> 976 {Type,Rest1} = parse_Type(Rest0), 977 {OptionalitySpec,Rest} = parse_ValueSetOptionalitySpec(Rest1), 978 case is_end_delimiter(Rest) of 979 true -> 980 {{objectset_or_fixedtypevalueset_field,Name,Type, 981 OptionalitySpec},Rest}; 982 false -> 983 parse_error(Rest) 984 end. 985 986parse_VariableTypeValueSetFieldSpec([{typefieldreference,_,Name}|Rest0]) -> 987 {FieldRef,Rest1} = parse_FieldName(Rest0), 988 {OptionalitySpec,Rest} = parse_ValueSetOptionalitySpec(Rest1), 989 case is_end_delimiter(Rest) of 990 true -> 991 {{variabletypevaluesetfield,Name,FieldRef,OptionalitySpec}, 992 Rest}; 993 false -> 994 parse_error(Rest) 995 end. 996 997is_end_delimiter([{',',_}|_]) -> true; 998is_end_delimiter([{'}',_}|_]) -> true; 999is_end_delimiter([_|_]) -> false. 1000 1001parse_ValueOptionalitySpec(Tokens)-> 1002 case Tokens of 1003 [{'OPTIONAL',_}|Rest] -> {'OPTIONAL',Rest}; 1004 [{'DEFAULT',_}|Rest] -> 1005 {Value,Rest2} = parse_Value(Rest), 1006 {{'DEFAULT',Value},Rest2}; 1007 _ -> {'MANDATORY',Tokens} 1008 end. 1009 1010parse_TypeOptionalitySpec(Tokens) -> 1011 case Tokens of 1012 [{'OPTIONAL',_}|Rest] -> {'OPTIONAL',Rest}; 1013 [{'DEFAULT',_}|Rest] -> 1014 {Type,Rest2} = parse_Type(Rest), 1015 {{'DEFAULT',Type},Rest2}; 1016 _ -> {'MANDATORY',Tokens} 1017 end. 1018 1019parse_ValueSetOptionalitySpec(Tokens) -> 1020 case Tokens of 1021 [{'OPTIONAL',_}|Rest] -> {'OPTIONAL',Rest}; 1022 [{'DEFAULT',_}|Rest] -> 1023 {ValueSet,Rest2} = parse_ValueSet(Rest), 1024 {{'DEFAULT',ValueSet},Rest2}; 1025 _ -> {'MANDATORY',Tokens} 1026 end. 1027 1028parse_WithSyntaxSpec([{'WITH',_},{'SYNTAX',_}|Rest]) -> 1029 {SyntaxList,Rest2} = parse_SyntaxList(Rest), 1030 {{'WITH SYNTAX',SyntaxList},Rest2}; 1031parse_WithSyntaxSpec(Tokens) -> 1032 {[],Tokens}. 1033 1034parse_SyntaxList([{'{',_}|Rest]) -> 1035 parse_SyntaxList(Rest,[]); 1036parse_SyntaxList(Tokens) -> 1037 parse_error(Tokens). 1038 1039parse_SyntaxList(Tokens, Acc) -> 1040 {SyntaxList,Rest} = parse_TokenOrGroupSpec(Tokens), 1041 case Rest of 1042 [{'}',_}|Rest2] -> 1043 {lists:reverse(Acc, [SyntaxList]),Rest2}; 1044 _ -> 1045 parse_SyntaxList(Rest, [SyntaxList|Acc]) 1046 end. 1047 1048parse_TokenOrGroupSpec(Tokens) -> 1049 Flist = [fun parse_RequiredToken/1, 1050 fun parse_OptionalGroup/1], 1051 parse_or(Tokens, Flist). 1052 1053parse_RequiredToken([{typereference,_,WordName}|Rest]=Tokens) -> 1054 case is_word(WordName) of 1055 false -> 1056 parse_error(Tokens); 1057 true -> 1058 {WordName,Rest} 1059 end; 1060parse_RequiredToken([{',',L1}|Rest]) -> 1061 {{',',L1},Rest}; 1062parse_RequiredToken([{WordName,_}|Rest]=Tokens) -> 1063 case is_word(WordName) of 1064 false -> 1065 parse_error(Tokens); 1066 true -> 1067 {WordName,Rest} 1068 end; 1069parse_RequiredToken(Tokens) -> 1070 parse_PrimitiveFieldName(Tokens). 1071 1072parse_OptionalGroup([{'[',_}|Rest]) -> 1073 {Spec,Rest2} = parse_TokenOrGroupSpec(Rest), 1074 {SpecList,Rest3} = parse_OptionalGroup(Rest2,[Spec]), 1075 {SpecList,Rest3}; 1076parse_OptionalGroup(Tokens) -> 1077 parse_error(Tokens). 1078 1079parse_OptionalGroup([{']',_}|Rest],Acc) -> 1080 {lists:reverse(Acc),Rest}; 1081parse_OptionalGroup(Tokens,Acc) -> 1082 {Spec,Rest} = parse_TokenOrGroupSpec(Tokens), 1083 parse_OptionalGroup(Rest,[Spec|Acc]). 1084 1085parse_DefinedObject([#identifier{}=Id|Rest]) -> 1086 {{object,identifier2Extvalueref(Id)},Rest}; 1087parse_DefinedObject([{typereference,L1,ModName},{'.',_},#identifier{val=ObjName}|Rest]) -> 1088 {{object, #'Externaltypereference'{pos=L1,module=ModName,type=ObjName}},Rest}; 1089parse_DefinedObject(Tokens) -> 1090 parse_error(Tokens). 1091 1092parse_ObjectAssignment([#identifier{pos=L1,val=ObjName}|Rest]) -> 1093 {Class,Rest2} = parse_DefinedObjectClass(Rest), 1094 case Rest2 of 1095 [{'::=',_}|Rest3] -> 1096 {Object,Rest4} = parse_Object(Rest3), 1097 {#typedef{pos=L1,name=ObjName, 1098 typespec=#'Object'{classname=Class,def=Object}},Rest4}; 1099 _ -> 1100 parse_error(Rest2) 1101 end. 1102 1103%% parse_Object(Tokens) -> Ret 1104%% Tokens = [Tok] 1105%% Tok = tuple() 1106%% Ret = {object,_} | {object, _, _} 1107parse_Object(Tokens) -> 1108 %% The ObjectFromObject production is not included here, 1109 %% since it will have been catched by the ValueFromObject 1110 %% before we reach this point. 1111 Flist = [fun parse_ObjectDefn/1, 1112 fun parse_DefinedObject/1], 1113 parse_or(Tokens, Flist). 1114 1115parse_ObjectDefn(Tokens) -> 1116 Flist=[fun parse_DefaultSyntax/1, 1117 fun parse_DefinedSyntax/1], 1118 parse_or(Tokens, Flist). 1119 1120parse_DefaultSyntax([{'{',_}|Rest]) -> 1121 parse_DefaultSyntax(Rest,[]); 1122parse_DefaultSyntax(Tokens) -> 1123 parse_error(Tokens). 1124 1125parse_DefaultSyntax(Tokens, Acc) -> 1126 {Setting,Rest} = parse_FieldSetting(Tokens), 1127 case Rest of 1128 [{',',_}|Rest2] -> 1129 parse_DefaultSyntax(Rest2,[Setting|Acc]); 1130 [{'}',_}|Rest3] -> 1131 {{object,defaultsyntax,lists:reverse(Acc, [Setting])},Rest3}; 1132 _ -> 1133 parse_error(Rest) 1134 end. 1135 1136parse_FieldSetting(Tokens) -> 1137 {{_,PrimFieldName},Rest} = parse_PrimitiveFieldName(Tokens), 1138 {Setting,Rest2} = parse_Setting(Rest), 1139 {{PrimFieldName,Setting},Rest2}. 1140 1141parse_DefinedSyntax([{'{',_}|Rest]) -> 1142 parse_DefinedSyntax(Rest, []); 1143parse_DefinedSyntax(Tokens) -> 1144 parse_error(Tokens). 1145 1146parse_DefinedSyntax(Tokens,Acc) -> 1147 case Tokens of 1148 [{'}',_}|Rest2] -> 1149 {{object,definedsyntax,lists:reverse(Acc)},Rest2}; 1150 _ -> 1151 {DefSynTok,Rest3} = parse_DefinedSyntaxToken(Tokens), 1152 parse_DefinedSyntax(Rest3,[DefSynTok|Acc]) 1153 end. 1154 1155 1156%% DefinedSyntaxToken ::= Literal | Setting 1157%% Literal ::= word | ',' 1158%% Setting ::= Type | Value | ValueSet | Object | ObjectSet 1159%% word equals typereference, but no lower cases 1160parse_DefinedSyntaxToken([{',',_}=Comma|Rest]) -> 1161 {Comma,Rest}; 1162%% ObjectClassFieldType or a defined type with a constraint. 1163%% Should also be able to parse a parameterized type. It may be 1164%% impossible to distinguish between a parameterized type and a Literal 1165%% followed by an object set. 1166parse_DefinedSyntaxToken([{typereference,_,_Name},{T,_}|_]=Tokens) 1167 when T =:= '.'; T =:= '(' -> 1168 parse_Setting(Tokens); 1169parse_DefinedSyntaxToken([{typereference,L1,Name}=TRef|Rest]=Tokens) -> 1170 case is_word(Name) of 1171 false -> 1172 case lookahead_definedsyntax(Rest) of 1173 word_or_setting -> 1174 {{setting,L1,tref2Exttref(TRef)},Rest}; 1175 setting -> 1176 parse_Setting(Tokens) 1177 end; 1178 true -> 1179 {{word_or_setting,L1,tref2Exttref(TRef)},Rest} 1180 end; 1181parse_DefinedSyntaxToken(Tokens) -> 1182 try parse_Setting(Tokens) of 1183 {_,_}=Result -> 1184 Result 1185 catch 1186 throw:{asn1_error,_} -> 1187 parse_Word(Tokens) 1188 end. 1189 1190lookahead_definedsyntax([{typereference,_,Name}|_Rest]) -> 1191 case is_word(Name) of 1192 true -> word_or_setting; 1193 false -> setting 1194 end; 1195lookahead_definedsyntax([{'}',_}|_Rest]) -> 1196 word_or_setting; 1197lookahead_definedsyntax(_) -> 1198 setting. 1199 1200parse_Word([{Name,Pos}|Rest]=Tokens) -> 1201 case is_word(Name) of 1202 false -> 1203 parse_error(Tokens); 1204 true -> 1205 {{word_or_setting,Pos,tref2Exttref(Pos,Name)},Rest} 1206 end; 1207parse_Word(Tokens) -> 1208 parse_error(Tokens). 1209 1210parse_Setting(Tokens) -> 1211 Flist = [{type_tag,fun parse_Type/1}, 1212 {value_tag,fun parse_Value/1}, 1213 {object_tag,fun parse_Object/1}, 1214 {objectset_tag,fun parse_ObjectSet/1}], 1215 case parse_or_tag(Tokens, Flist) of 1216 {{value_tag,_},_}=Result -> 1217 %% Keep the value_tag. 1218 Result; 1219 {{Tag,Setting},Rest} when is_atom(Tag) -> 1220 %% Remove all other tags. 1221 {Setting,Rest} 1222 end. 1223 1224parse_DefinedObjectSet([{typereference,L1,ModuleName},{'.',_}, 1225 {typereference,L2,ObjSetName}|Rest]) -> 1226 {{objectset,L1,#'Externaltypereference'{pos=L2,module=ModuleName, 1227 type=ObjSetName}},Rest}; 1228parse_DefinedObjectSet([{typereference,L1,ObjSetName}|Rest]) -> 1229 {{objectset,L1,#'Externaltypereference'{pos=L1,module=resolve_module(ObjSetName), 1230 type=ObjSetName}},Rest}; 1231parse_DefinedObjectSet(Tokens) -> 1232 parse_error(Tokens). 1233 1234parse_ObjectSetAssignment([{typereference,L1,ObjSetName}|Rest]) -> 1235 {Class,Rest2} = parse_DefinedObjectClass(Rest), 1236 case Rest2 of 1237 [{'::=',_}|Rest3] -> 1238 {ObjectSet,Rest4} = parse_ObjectSet(Rest3), 1239 {#typedef{pos=L1,name=ObjSetName, 1240 typespec=#'ObjectSet'{class=Class, 1241 set=ObjectSet}},Rest4}; 1242 _ -> 1243 parse_error(Rest2) 1244 end. 1245 1246%% parse_ObjectSet(Tokens) -> {Ret,Rest} 1247%% Tokens = [Tok] 1248%% Tok = tuple() 1249%% Ret = {[],tuple()} | 1250%% {list(),list()} | 1251%% list() | 1252%% ['EXTENSIONMARK'] | 1253%% {'ALL',{'EXCEPT',Exclusions}} | 1254%% {'SingleValue',SV} 1255%% SV = list() | #'Externalvaluereference'{} | {definedvalue,term()} 1256parse_ObjectSet([{'{',_}|Rest]) -> 1257 {ObjSetSpec,Rest2} = parse_ObjectSetSpec(Rest), 1258 case Rest2 of 1259 [{'}',_}|Rest3] -> 1260 {ObjSetSpec,Rest3}; 1261 _ -> 1262 parse_error(Rest2) 1263 end; 1264parse_ObjectSet(Tokens) -> 1265 parse_error(Tokens). 1266 1267parse_ObjectSetSpec([{'...',_},{',',_}|Tokens0]) -> 1268 {Elements,Tokens} = parse_ElementSetSpec(Tokens0), 1269 {{element_set,empty,Elements},Tokens}; 1270parse_ObjectSetSpec([{'...',_}|Tokens]) -> 1271 {{element_set,empty,empty},Tokens}; 1272parse_ObjectSetSpec(Tokens) -> 1273 parse_ElementSetSpecs(Tokens). 1274 1275%% parse_ObjectSetElements(Tokens) -> {Result,Rest} 1276%% Result ::= {'ObjectSetFromObjects',Objects,Name} | {pos,ObjectSet,Params} 1277%% Objects ::= ReferencedObjects 1278%% ReferencedObjects ::= (see parse_ReferencedObjects/1) 1279%% Name ::= [FieldName] 1280%% FieldName ::= {typefieldreference,atom()} | {valuefieldreference,atom()} 1281%% ObjectSet ::= {objectset,integer(),#'Externaltypereference'{}} 1282%% Params ::= list() (see parse_ActualParameterList/1) 1283parse_ObjectSetElements(Tokens) -> 1284 Flist = [fun parse_ObjectSetFromObjects/1, 1285 fun parse_ParameterizedObjectSet/1], 1286 parse_or(Tokens, Flist). 1287 1288parse_ObjectClassFieldType(Tokens) -> 1289 {Class,Rest} = parse_DefinedObjectClass(Tokens), 1290 case Rest of 1291 [{'.',_}|Rest2] -> 1292 {FieldName,Rest3} = parse_FieldName(Rest2), 1293 OCFT = #'ObjectClassFieldType'{ 1294 classname=Class, 1295 class=Class,fieldname=FieldName}, 1296 {#type{def=OCFT},Rest3}; 1297 _ -> 1298 parse_error(Rest) 1299 end. 1300 1301parse_ObjectClassFieldValue(Tokens) -> 1302 parse_OpenTypeFieldVal(Tokens). 1303 1304parse_OpenTypeFieldVal(Tokens) -> 1305 {Type,Rest} = parse_Type(Tokens), 1306 case Rest of 1307 [{':',_}|Rest2] -> 1308 {Value,Rest3} = parse_Value(Rest2), 1309 {{opentypefieldvalue,Type,Value},Rest3}; 1310 _ -> 1311 parse_error(Rest) 1312 end. 1313 1314%% parse_ReferencedObjects(Tokens) -> {Result,Rest} 1315%% Result ::= DefObject | DefObjSet | 1316%% {po,DefObject,Params} | {pos,DefObjSet,Params} | 1317%% 1318%% DefObject ::= {object,#'Externaltypereference'{}} | 1319%% {object,#'Externalvaluereference'{}} 1320%% DefObjSet ::= {objectset,integer(),#'Externaltypereference'{}} 1321%% Params ::= list() 1322parse_ReferencedObjects(Tokens) -> 1323 Flist = [fun parse_DefinedObject/1, 1324 fun parse_DefinedObjectSet/1, 1325 fun parse_ParameterizedObjectSet/1], 1326 parse_or(Tokens, Flist). 1327 1328parse_ValueFromObject(Tokens) -> 1329 %% This production also matches ObjectFromObject. 1330 {Objects,Rest} = parse_ReferencedObjects(Tokens), 1331 case Rest of 1332 [{'.',_}|Rest2] -> 1333 {Name,Rest3} = parse_FieldName(Rest2), 1334 case lists:last(Name) of 1335 {valuefieldreference,_} -> 1336 {{'ValueFromObject',Objects,Name},Rest3}; 1337 _ -> 1338 parse_error(Rest2) 1339 end; 1340 _ -> 1341 parse_error(Rest) 1342 end. 1343 1344parse_TypeFromObject(Tokens) -> 1345 {Objects,Rest} = parse_ReferencedObjects(Tokens), 1346 case Rest of 1347 [{'.',_}|Rest2] -> 1348 {Name,Rest3} = parse_FieldName(Rest2), 1349 case lists:last(Name) of 1350 {typefieldreference,_FieldName} -> 1351 {#type{def={'TypeFromObject',Objects,Name}},Rest3}; 1352 _ -> 1353 parse_error(Rest2) 1354 end; 1355 _ -> 1356 parse_error(Rest) 1357 end. 1358 1359%% parse_ObjectSetFromObjects(Tokens) -> {Result,Rest} 1360%% Result ::= {'ObjectSetFromObjects',Objects,Name} 1361%% Objects ::= ReferencedObject (see parse_ReferencedObjects/1) 1362%% Name ::= [FieldName] 1363%% FieldName ::= {typefieldreference,atom()} | 1364%% {valuefieldreference,atom()} 1365parse_ObjectSetFromObjects(Tokens) -> 1366 {Objects,Rest} = parse_ReferencedObjects(Tokens), 1367 case Rest of 1368 [{'.',_}|Rest2] -> 1369 {Name,Rest3} = parse_FieldName(Rest2), 1370 case lists:last(Name) of 1371 {typefieldreference,_FieldName} -> 1372 {{'ObjectSetFromObjects',Objects,Name},Rest3}; 1373 _ -> 1374 parse_error(Rest2) 1375 end; 1376 _ -> 1377 parse_error(Rest) 1378 end. 1379 1380 1381%% X.682 constraint specification 1382 1383parse_GeneralConstraint(Tokens) -> 1384 Flist = [fun parse_UserDefinedConstraint/1, 1385 fun parse_TableConstraint/1, 1386 fun parse_ContentsConstraint/1], 1387 parse_or(Tokens, Flist). 1388 1389parse_UserDefinedConstraint([{'CONSTRAINED',_},{'BY',_},{'{',_},{'}',_}|Rest])-> 1390 {{constrained_by,[]},Rest}; 1391parse_UserDefinedConstraint([{'CONSTRAINED',_}, 1392 {'BY',_}, 1393 {'{',_}|Rest]) -> 1394 {Param,Rest2} = parse_UserDefinedConstraintParameter(Rest), 1395 case Rest2 of 1396 [{'}',_}|Rest3] -> 1397 {{constrained_by,Param},Rest3}; 1398 _ -> 1399 parse_error(Rest2) 1400 end; 1401parse_UserDefinedConstraint(Tokens) -> 1402 parse_error(Tokens). 1403 1404parse_UserDefinedConstraintParameter(Tokens) -> 1405 parse_UserDefinedConstraintParameter(Tokens, []). 1406 1407parse_UserDefinedConstraintParameter(Tokens0, Acc) -> 1408 Flist = [fun parse_GovernorAndActualParameter/1, 1409 fun parse_ActualParameter/1], 1410 case parse_or(Tokens0, Flist) of 1411 {Result,[{',',_}|Tokens]} -> 1412 parse_UserDefinedConstraintParameter(Tokens, [Result|Acc]); 1413 {Result,Tokens} -> 1414 {lists:reverse(Acc, [Result]),Tokens} 1415 end. 1416 1417parse_GovernorAndActualParameter(Tokens) -> 1418 {Governor,Rest} = parse_Governor(Tokens), 1419 case Rest of 1420 [{':',_}|Rest2] -> 1421 {Params,Rest3} = parse_ActualParameter(Rest2), 1422 {{'Governor_Params',Governor,Params},Rest3}; 1423 _ -> 1424 parse_error(Rest) 1425 end. 1426 1427parse_TableConstraint(Tokens) -> 1428 Flist = [fun parse_ComponentRelationConstraint/1, 1429 fun parse_SimpleTableConstraint/1], 1430 parse_or(Tokens, Flist). 1431 1432parse_SimpleTableConstraint(Tokens) -> 1433 {ObjectSet,Rest} = parse_ObjectSet(Tokens), 1434 {{element_set,{simpletable,ObjectSet},none},Rest}. 1435 1436parse_ComponentRelationConstraint([{'{',_}|Rest]) -> 1437 {ObjectSet,Rest2} = parse_DefinedObjectSet(Rest), 1438 case Rest2 of 1439 [{'}',_},{'{',_}|Rest3] -> 1440 {AtNot,Rest4} = parse_AtNotationList(Rest3,[]), 1441 case Rest4 of 1442 [{'}',_}|Rest5] -> 1443 Ret = {element_set, 1444 {componentrelation,ObjectSet,AtNot}, 1445 none}, 1446 {Ret,Rest5}; 1447 _ -> 1448 parse_error(Rest4) 1449 end; 1450 _ -> 1451 parse_error(Rest2) 1452 end; 1453parse_ComponentRelationConstraint(Tokens) -> 1454 parse_error(Tokens). 1455 1456parse_AtNotationList(Tokens,Acc) -> 1457 {AtNot,Rest} = parse_AtNotation(Tokens), 1458 case Rest of 1459 [{',',_}|Rest2] -> 1460 parse_AtNotationList(Rest2,[AtNot|Acc]); 1461 _ -> 1462 {lists:reverse(Acc, [AtNot]),Rest} 1463 end. 1464 1465parse_AtNotation([{'@',_},{'.',_}|Rest]) -> 1466 {CIdList,Rest2} = parse_ComponentIdList(Rest), 1467 {{innermost,CIdList},Rest2}; 1468parse_AtNotation([{'@',_}|Rest]) -> 1469 {CIdList,Rest2} = parse_ComponentIdList(Rest), 1470 {{outermost,CIdList},Rest2}; 1471parse_AtNotation(Tokens) -> 1472 parse_error(Tokens). 1473 1474parse_ComponentIdList(Tokens) -> 1475 parse_ComponentIdList(Tokens,[]). 1476 1477parse_ComponentIdList([#identifier{}=Id,{'.',_}|Rest], Acc) -> 1478 parse_ComponentIdList(Rest,[identifier2Extvalueref(Id)|Acc]); 1479parse_ComponentIdList([#identifier{}=Id|Rest], Acc) -> 1480 {lists:reverse(Acc, [identifier2Extvalueref(Id)]),Rest}; 1481parse_ComponentIdList(Tokens,_) -> 1482 parse_error(Tokens). 1483 1484parse_ContentsConstraint([{'CONTAINING',_}|Rest]) -> 1485 {Type,Rest2} = parse_Type(Rest), 1486 case Rest2 of 1487 [{'ENCODED',_},{'BY',_}|Rest3] -> 1488 {Value,Rest4} = parse_Value(Rest3), 1489 {{contentsconstraint,Type,Value},Rest4}; 1490 _ -> 1491 {{contentsconstraint,Type,[]},Rest2} 1492 end; 1493parse_ContentsConstraint([{'ENCODED',_},{'BY',_}|Rest]) -> 1494 {Value,Rest2} = parse_Value(Rest), 1495 {{contentsconstraint,[],Value},Rest2}; 1496parse_ContentsConstraint(Tokens) -> 1497 parse_error(Tokens). 1498 1499%% X.683 Parameterization of ASN.1 specifications 1500 1501parse_Governor(Tokens) -> 1502 Flist = [fun parse_Type/1, 1503 fun parse_DefinedObjectClass/1], 1504 parse_or(Tokens, Flist). 1505 1506parse_ActualParameter(Tokens) -> 1507 Flist = [fun parse_Type/1, 1508 fun parse_Value/1, 1509 fun parse_ValueSet/1, 1510 fun parse_DefinedObjectClass/1, 1511 fun parse_Object/1, 1512 fun parse_ObjectSet/1], 1513 parse_or(Tokens, Flist). 1514 1515%% parse_ParameterizedTypeAssignment(Tokens) -> Result 1516%% Result = {#ptypedef{},Rest} | throw() 1517parse_ParameterizedTypeAssignment([{typereference,L1,Name}|Rest]) -> 1518 {ParameterList,Rest2} = parse_ParameterList(Rest), 1519 case Rest2 of 1520 [{'::=',_}|Rest3] -> 1521 {Type,Rest4} = parse_Type(Rest3), 1522 {#ptypedef{pos=L1,name=Name,args=ParameterList,typespec=Type}, 1523 Rest4}; 1524 _ -> 1525 parse_error(Rest2) 1526 end. 1527 1528%% parse_ParameterizedValueAssignment(Tokens) -> Result 1529%% Result = {#pvaluedef{},Rest} | throw() 1530parse_ParameterizedValueAssignment([#identifier{pos=L1,val=Name}|Rest]) -> 1531 {ParameterList,Rest2} = parse_ParameterList(Rest), 1532 {Type,Rest3} = parse_Type(Rest2), 1533 case Rest3 of 1534 [{'::=',_}|Rest4] -> 1535 {Value,Rest5} = parse_Value(Rest4), 1536 {#pvaluedef{pos=L1,name=Name,args=ParameterList,type=Type, 1537 value=Value},Rest5}; 1538 _ -> 1539 parse_error(Rest3) 1540 end. 1541 1542%% parse_ParameterizedValueSetTypeAssignment(Tokens) -> Result 1543%% Result = {#pvaluesetdef{},Rest} | throw() 1544parse_ParameterizedValueSetTypeAssignment([{typereference,L1,Name}|Rest]) -> 1545 {ParameterList,Rest2} = parse_ParameterList(Rest), 1546 {Type,Rest3} = parse_Type(Rest2), 1547 case Rest3 of 1548 [{'::=',_}|Rest4] -> 1549 {ValueSet,Rest5} = parse_ValueSet(Rest4), 1550 {#pvaluesetdef{pos=L1,name=Name,args=ParameterList, 1551 type=Type,valueset=ValueSet},Rest5}; 1552 _ -> 1553 parse_error(Rest3) 1554 end. 1555 1556%% parse_ParameterizedObjectClassAssignment(Tokens) -> Result 1557%% Result = {#ptypedef{},Rest} | throw() 1558parse_ParameterizedObjectClassAssignment([{typereference,L1,Name}|Rest]) -> 1559 {ParameterList,Rest2} = parse_ParameterList(Rest), 1560 case Rest2 of 1561 [{'::=',_}|Rest3] -> 1562 {Class,Rest4} = parse_ObjectClass(Rest3), 1563 {#ptypedef{pos=L1,name=Name,args=ParameterList,typespec=Class}, 1564 Rest4}; 1565 _ -> 1566 parse_error(Rest2) 1567 end. 1568 1569%% parse_ParameterizedObjectAssignment(Tokens) -> Result 1570%% Result = {#pobjectdef{},Rest} | throw() 1571parse_ParameterizedObjectAssignment([#identifier{pos=L1,val=Name}|Rest]) -> 1572 {ParameterList,Rest2} = parse_ParameterList(Rest), 1573 {Class,Rest3} = parse_DefinedObjectClass(Rest2), 1574 case Rest3 of 1575 [{'::=',_}|Rest4] -> 1576 {Object,Rest5} = parse_Object(Rest4), 1577 {#pobjectdef{pos=L1,name=Name,args=ParameterList, 1578 class=Class,def=Object},Rest5}; 1579 _ -> 1580 parse_error(Rest3) 1581 end. 1582 1583%% parse_ParameterList(Tokens) -> Result 1584%% Result = [Parameter] 1585%% Parameter = {Governor,Reference} | Reference 1586%% Governor = Type | DefinedObjectClass 1587%% Type = #type{} 1588%% DefinedObjectClass = #'Externaltypereference'{} 1589%% Reference = #'Externaltypereference'{} | #'Externalvaluereference'{} 1590parse_ParameterList([{'{',_}|Tokens]) -> 1591 parse_ParameterList(Tokens, []). 1592 1593parse_ParameterList(Tokens,Acc) -> 1594 {Parameter,Rest} = parse_Parameter(Tokens), 1595 case Rest of 1596 [{',',_}|Rest2] -> 1597 parse_ParameterList(Rest2, [Parameter|Acc]); 1598 [{'}',_}|Rest3] -> 1599 {lists:reverse(Acc, [Parameter]),Rest3}; 1600 _ -> 1601 parse_error(Rest) 1602 end. 1603 1604parse_Parameter(Tokens) -> 1605 Flist = [fun parse_ParamGovAndRef/1, 1606 fun parse_Reference/1], 1607 parse_or(Tokens, Flist). 1608 1609parse_ParamGovAndRef(Tokens) -> 1610 {ParamGov,Rest} = parse_ParamGovernor(Tokens), 1611 case Rest of 1612 [{':',_}|Rest2] -> 1613 {Ref,Rest3} = parse_Reference(Rest2), 1614 {{ParamGov,Ref},Rest3}; 1615 _ -> 1616 parse_error(Rest) 1617 end. 1618 1619parse_ParamGovernor(Tokens) -> 1620 Flist = [fun parse_Governor/1, 1621 fun parse_Reference/1], 1622 parse_or(Tokens, Flist). 1623 1624parse_SimpleDefinedType([{typereference,L1,ModuleName},{'.',_}, 1625 {typereference,_,TypeName}|Rest]) -> 1626 {#'Externaltypereference'{pos=L1,module=ModuleName, 1627 type=TypeName},Rest}; 1628parse_SimpleDefinedType([Tref={typereference,_,_}|Rest]) -> 1629 {tref2Exttref(Tref),Rest}; 1630parse_SimpleDefinedType(Tokens) -> 1631 parse_error(Tokens). 1632 1633parse_SimpleDefinedValue([{typereference,L1,ModuleName},{'.',_}, 1634 #identifier{val=Value}|Rest]) -> 1635 {{simpledefinedvalue,#'Externalvaluereference'{pos=L1,module=ModuleName, 1636 value=Value}},Rest}; 1637parse_SimpleDefinedValue([#identifier{}=Id|Rest]) -> 1638 {{simpledefinedvalue,identifier2Extvalueref(Id)},Rest}; 1639parse_SimpleDefinedValue(Tokens) -> 1640 parse_error(Tokens). 1641 1642parse_ParameterizedType(Tokens) -> 1643 %% May also be a parameterized class. 1644 {Type,Rest} = parse_SimpleDefinedType(Tokens), 1645 {Params,Rest2} = parse_ActualParameterList(Rest), 1646 {#type{def={pt,Type,Params}},Rest2}. 1647 1648parse_ParameterizedValue(Tokens) -> 1649 %% May also be a parameterized object. 1650 {Value,Rest} = parse_SimpleDefinedValue(Tokens), 1651 {Params,Rest2} = parse_ActualParameterList(Rest), 1652 {{pv,Value,Params},Rest2}. 1653 1654parse_ParameterizedObjectSet(Tokens) -> 1655 {ObjectSet,Rest} = parse_DefinedObjectSet(Tokens), 1656 {Params,Rest2} = parse_ActualParameterList(Rest), 1657 {{pos,ObjectSet,Params},Rest2}. 1658 1659parse_ActualParameterList([{'{',_}|Rest]) -> 1660 parse_ActualParameterList(Rest,[]); 1661parse_ActualParameterList(Tokens) -> 1662 parse_error(Tokens). 1663 1664parse_ActualParameterList(Tokens,Acc) -> 1665 {Parameter,Rest} = parse_ActualParameter(Tokens), 1666 case Rest of 1667 [{',',_}|Rest2] -> 1668 parse_ActualParameterList(Rest2,[Parameter|Acc]); 1669 [{'}',_}|Rest3] -> 1670 {lists:reverse(Acc, [Parameter]),Rest3}; 1671 _ -> 1672 parse_error(Rest) 1673 end. 1674 1675%% Test whether Token is allowed in a syntax list. 1676is_word(Token) -> 1677 List = atom_to_list(Token), 1678 case not_allowed_word(List) of 1679 true -> false; 1680 false -> is_word_1(List) 1681 end. 1682 1683is_word_1([H|T]) -> 1684 check_first(H) andalso check_rest(T). 1685 1686not_allowed_word(Name) -> 1687 lists:member(Name,["BIT", 1688 "BOOLEAN", 1689 "CHARACTER", 1690 "CHOICE", 1691 "EMBEDDED", 1692 "END", 1693 "ENUMERATED", 1694 "EXTERNAL", 1695 "FALSE", 1696 "INSTANCE", 1697 "INTEGER", 1698 "INTERSECTION", 1699 "MINUS-INFINITY", 1700 "NULL", 1701 "OBJECT", 1702 "OCTET", 1703 "PLUS-INFINITY", 1704 "REAL", 1705 "SEQUENCE", 1706 "SET", 1707 "TRUE", 1708 "UNION"]). 1709 1710check_first(C) -> 1711 $A =< C andalso C =< $Z. 1712 1713check_rest([R|Rs]) when $A =< R, R =< $Z; R =:= $- -> 1714 check_rest(Rs); 1715check_rest([]) -> 1716 true; 1717check_rest(_) -> 1718 false. 1719 1720%%% 1721%%% Parse alternative type lists for CHOICE. 1722%%% 1723 1724parse_AlternativeTypeLists(Tokens0) -> 1725 {Root,Tokens1} = parse_AlternativeTypeList(Tokens0), 1726 case Tokens1 of 1727 [{',',_}|Tokens2] -> 1728 {ExtMarker,Tokens3} = parse_ExtensionAndException(Tokens2), 1729 {ExtAlts,Tokens4} = parse_ExtensionAdditionAlternatives(Tokens3), 1730 {_,Tokens} = parse_OptionalExtensionMarker(Tokens4, []), 1731 {Root++ExtMarker++ExtAlts,Tokens}; 1732 Tokens -> 1733 {Root,Tokens} 1734 end. 1735 1736parse_ExtensionAndException([{'...',L}|Tokens0]) -> 1737 {[#'EXTENSIONMARK'{pos=L}], 1738 case Tokens0 of 1739 [{'!',_}|Tokens1] -> 1740 {_,Tokens} = parse_ExceptionIdentification(Tokens1), 1741 Tokens; 1742 _ -> 1743 Tokens0 1744 end}. 1745 1746parse_AlternativeTypeList([#identifier{}|_]=Tokens0) -> 1747 {AltType,Tokens} = parse_NamedType(Tokens0), 1748 parse_AlternativeTypeList_1(Tokens, [AltType]); 1749parse_AlternativeTypeList(Tokens) -> 1750 parse_error(Tokens). 1751 1752parse_AlternativeTypeList_1([{',',_}|[#identifier{}|_]=Tokens0], Acc) -> 1753 {AltType,Tokens} = parse_NamedType(Tokens0), 1754 parse_AlternativeTypeList_1(Tokens, [AltType|Acc]); 1755parse_AlternativeTypeList_1(Tokens, Acc) -> 1756 {lists:reverse(Acc),Tokens}. 1757 1758parse_ExtensionAdditionAlternatives([{',',_}|_]=Tokens0) -> 1759 parse_ExtensionAdditionAlternativesList(Tokens0, []); 1760parse_ExtensionAdditionAlternatives(Tokens) -> 1761 {[],Tokens}. 1762 1763parse_ExtensionAdditionAlternativesList([{',',_}|Tokens1]=Tokens0, Acc) -> 1764 try parse_ExtensionAdditionAlternative(Tokens1) of 1765 {ExtAddAlt,Tokens2} -> 1766 parse_ExtensionAdditionAlternativesList(Tokens2, [ExtAddAlt|Acc]) 1767 catch 1768 throw:{asn1_error,_} -> 1769 {lists:append(lists:reverse(Acc)),Tokens0} 1770 end; 1771parse_ExtensionAdditionAlternativesList(Tokens, Acc) -> 1772 {lists:append(lists:reverse(Acc)),Tokens}. 1773 1774parse_ExtensionAdditionAlternative([#identifier{}|_]=Tokens0) -> 1775 {NamedType,Tokens} = parse_NamedType(Tokens0), 1776 {[NamedType],Tokens}; 1777parse_ExtensionAdditionAlternative([{'[',_},{'[',_}|Tokens0]) -> 1778 Tokens2 = case Tokens0 of 1779 [{number,_,_},{':',_}|Tokens1] -> Tokens1; 1780 _ -> Tokens0 1781 end, 1782 {GroupList,Tokens3} = parse_AlternativeTypeList(Tokens2), 1783 case Tokens3 of 1784 [{']',_},{']',_}|Tokens] -> 1785 {GroupList,Tokens}; 1786 _ -> 1787 parse_error(Tokens3) 1788 end; 1789parse_ExtensionAdditionAlternative(Tokens) -> 1790 parse_error(Tokens). 1791 1792%%% 1793%%% End of parsing of alternative type lists. 1794%%% 1795 1796parse_NamedType([#identifier{pos=L1,val=Idname}|Rest]) -> 1797 {Type,Rest2} = parse_Type(Rest), 1798 {#'ComponentType'{pos=L1,name=Idname,typespec=Type,prop=mandatory},Rest2}; 1799parse_NamedType(Tokens) -> 1800 parse_error(Tokens). 1801 1802%%% 1803%%% Parse component type lists for SEQUENCE and SET. 1804%%% 1805 1806parse_ComponentTypeLists(Tokens) -> 1807 parse_ComponentTypeLists(Tokens, []). 1808 1809parse_ComponentTypeLists([#identifier{}|_Rest0]=Tokens, Clist) -> 1810 {CompList,Rest1} = parse_ComponentTypeList(Tokens,[]), 1811 parse_ComponentTypeLists(Rest1,Clist++CompList); 1812parse_ComponentTypeLists([{'COMPONENTS',_},{'OF',_}|_]=Tokens,Clist) -> 1813 {CompList,Rest1} = parse_ComponentTypeList(Tokens, []), 1814 parse_ComponentTypeLists(Rest1, Clist++CompList); 1815parse_ComponentTypeLists([{',',L1},{'...',_},{'!',_}|Rest02],Clist0) when Clist0 =/= []-> 1816 {_,Rest03} = parse_ExceptionIdentification(Rest02), 1817 %% Exception info is currently thrown away 1818 parse_ComponentTypeLists2(Rest03,Clist0++[#'EXTENSIONMARK'{pos=L1}]); 1819parse_ComponentTypeLists([{',',_},{'...',L1}|Rest02],Clist0) when Clist0 =/= []-> 1820 parse_ComponentTypeLists2(Rest02,Clist0++[#'EXTENSIONMARK'{pos=L1}]); 1821parse_ComponentTypeLists([{'...',L1}|Rest02],Clist0) -> 1822 parse_ComponentTypeLists2(Rest02,Clist0++[#'EXTENSIONMARK'{pos=L1}]); 1823parse_ComponentTypeLists(Tokens = [{'}',_L1}|_Rest02],Clist0) -> 1824 {Clist0,Tokens}; 1825parse_ComponentTypeLists(Tokens, _) -> 1826 parse_error(Tokens). 1827 1828parse_ComponentTypeLists2(Tokens,Clist) -> 1829 {ExtAdd,Rest} = parse_ExtensionAdditions(Tokens,Clist), 1830 {Clist2,Rest2} = parse_OptionalExtensionMarker(Rest,lists:flatten(ExtAdd)), 1831 case Rest2 of 1832 [{',',_}|Rest3] -> 1833 {CompList,Rest4} = parse_ComponentTypeList(Rest3,[]), 1834 {Clist2 ++ CompList,Rest4}; 1835 _ -> 1836 {Clist2,Rest2} 1837 end. 1838 1839parse_OptionalExtensionMarker([{',',_},{'...',L1}|Rest],Clist)-> 1840 {Clist++[#'EXTENSIONMARK'{pos=L1}],Rest}; 1841parse_OptionalExtensionMarker(Tokens,Clist) -> 1842 {Clist,Tokens}. 1843 1844 1845parse_ComponentTypeList([{',',_}|[#identifier{}|_]=Tokens0], Acc) when Acc =/= [] -> 1846 {ComponentType,Tokens} = parse_ComponentType(Tokens0), 1847 parse_ComponentTypeList(Tokens, [ComponentType|Acc]); 1848parse_ComponentTypeList([{',',_}|[{'COMPONENTS',_},{'OF',_}|_]=Tokens0], Acc) when Acc =/= [] -> 1849 {ComponentType,Tokens} = parse_ComponentType(Tokens0), 1850 parse_ComponentTypeList(Tokens, [ComponentType|Acc]); 1851parse_ComponentTypeList(Tokens = [{'}',_}|_],Acc) -> 1852 {lists:reverse(Acc),Tokens}; 1853parse_ComponentTypeList(Tokens = [{']',_},{']',_}|_],Acc) -> 1854 {lists:reverse(Acc),Tokens}; 1855parse_ComponentTypeList(Tokens = [{',',_},{'...',_}|_],Acc) -> 1856 {lists:reverse(Acc),Tokens}; 1857parse_ComponentTypeList(Tokens,[]) -> 1858 {ComponentType,Rest} = parse_ComponentType(Tokens), 1859 parse_ComponentTypeList(Rest,[ComponentType]); 1860parse_ComponentTypeList(Tokens,_) -> 1861 parse_error(Tokens). 1862 1863parse_ExtensionAdditions(Tokens=[{',',_}|_],Clist) -> 1864 {ExtAddList,Rest2} = parse_ExtensionAdditionList(Tokens,[]), 1865 {Clist++ExtAddList,Rest2}; 1866parse_ExtensionAdditions(Tokens,Clist) -> 1867 %% Empty 1868 {Clist,Tokens}. 1869 1870parse_ExtensionAdditionList([{',',_}|[#identifier{}|_]=Tokens0], Acc) -> 1871 {ComponentType,Tokens} = parse_ComponentType(Tokens0), 1872 parse_ExtensionAdditionList(Tokens, [ComponentType|Acc]); 1873parse_ExtensionAdditionList([{',',_}|[{'COMPONENTS',_},{'OF',_}|_]=Tokens0], Acc) -> 1874 {ComponentType,Tokens} = parse_ComponentType(Tokens0), 1875 parse_ExtensionAdditionList(Tokens, [ComponentType|Acc]); 1876parse_ExtensionAdditionList([{',',_},{'[',_},{'[',_}|Tokens], Acc) -> 1877 {ExtAddGroup,Rest2} = parse_ExtensionAdditionGroup(Tokens), 1878 parse_ExtensionAdditionList(Rest2,[ExtAddGroup|Acc]); 1879parse_ExtensionAdditionList([{'}',_}|_]=Tokens, Acc) -> 1880 {lists:reverse(Acc),Tokens}; 1881parse_ExtensionAdditionList([{',',_},{'...',_}|_]=Tokens, Acc) -> 1882 {lists:reverse(Acc),Tokens}; 1883parse_ExtensionAdditionList(Tokens, _) -> 1884 parse_error(Tokens). 1885 1886 1887parse_ExtensionAdditionGroup([{number,_,Num},{':',_}|Tokens]) -> 1888 parse_ExtensionAdditionGroup2(Tokens, Num); 1889parse_ExtensionAdditionGroup(Tokens) -> 1890 parse_ExtensionAdditionGroup2(Tokens, undefined). 1891 1892parse_ExtensionAdditionGroup2(Tokens, Num) -> 1893 {CompTypeList,Rest} = parse_ComponentTypeList(Tokens,[]), 1894 case Rest of 1895 [{']',_},{']',_}|Rest2] -> 1896 {[{'ExtensionAdditionGroup',Num}|CompTypeList] ++ 1897 ['ExtensionAdditionGroupEnd'],Rest2}; 1898 _ -> 1899 parse_error(Rest) 1900 end. 1901 1902 1903parse_ComponentType([{'COMPONENTS',_},{'OF',_}|Rest]) -> 1904 {Type,Rest2} = parse_Type(Rest), 1905 {{'COMPONENTS OF',Type},Rest2}; 1906parse_ComponentType(Tokens) -> 1907 Result = {NamedType,Rest} = parse_NamedType(Tokens), 1908 case Rest of 1909 [{'OPTIONAL',_}|Rest2] -> 1910 {NamedType#'ComponentType'{prop='OPTIONAL'},Rest2}; 1911 [{'DEFAULT',_}|Rest2] -> 1912 {Value,Rest21} = parse_Value(Rest2), 1913 {NamedType#'ComponentType'{prop={'DEFAULT',Value}},Rest21}; 1914 _ -> 1915 Result 1916 end. 1917 1918%%% 1919%%% Parse ENUMERATED. 1920%%% 1921 1922parse_Enumerations(Tokens0) -> 1923 {Root,Tokens1} = parse_Enumeration(Tokens0), 1924 case Tokens1 of 1925 [{',',_},{'...',_},{',',_}|Tokens2] -> 1926 {Ext,Tokens} = parse_Enumeration(Tokens2), 1927 {Root++['EXTENSIONMARK'|Ext],Tokens}; 1928 [{',',_},{'...',_}|Tokens] -> 1929 {Root++['EXTENSIONMARK'],Tokens}; 1930 _ -> 1931 case get(extensiondefault) of 1932 'IMPLIED' -> 1933 {Root++['EXTENSIONMARK'],Tokens1}; 1934 _ -> 1935 {Root,Tokens1} 1936 end 1937 end. 1938 1939parse_Enumeration(Tokens0) -> 1940 {Item,Tokens} = parse_EnumerationItem(Tokens0), 1941 parse_Enumeration_1(Tokens, [Item]). 1942 1943parse_Enumeration_1([{',',_}|Tokens1]=Tokens0, Acc) -> 1944 try parse_EnumerationItem(Tokens1) of 1945 {Item,Tokens} -> 1946 parse_Enumeration_1(Tokens, [Item|Acc]) 1947 catch 1948 throw:{asn1_error,_} -> 1949 {lists:reverse(Acc),Tokens0} 1950 end; 1951parse_Enumeration_1(Tokens, Acc) -> 1952 {lists:reverse(Acc),Tokens}. 1953 1954parse_EnumerationItem([#identifier{},{'(',_}|_]=Tokens) -> 1955 parse_NamedNumber(Tokens); 1956parse_EnumerationItem([#identifier{val=Id}|Tokens]) -> 1957 {Id,Tokens}; 1958parse_EnumerationItem(Tokens) -> 1959 parse_error(Tokens). 1960 1961%%% 1962%%% End of parsing of ENUMERATED. 1963%%% 1964 1965parse_NamedNumberList(Tokens) -> 1966 parse_NamedNumberList(Tokens, []). 1967 1968parse_NamedNumberList(Tokens, Acc) -> 1969 {NamedNum,Rest} = parse_NamedNumber(Tokens), 1970 case Rest of 1971 [{',',_}|Rest2] -> 1972 parse_NamedNumberList(Rest2,[NamedNum|Acc]); 1973 _ -> 1974 {lists:reverse(Acc, [NamedNum]),Rest} 1975 end. 1976 1977parse_NamedNumber([#identifier{val=Name},{'(',_}|Rest]) -> 1978 Flist = [fun parse_SignedNumber/1, 1979 fun parse_DefinedValue/1], 1980 case parse_or(Rest, Flist) of 1981 {NamedNum,[{')',_}|Rest2]} -> 1982 {{'NamedNumber',Name,NamedNum},Rest2}; 1983 _ -> 1984 parse_error(Rest) 1985 end; 1986parse_NamedNumber(Tokens) -> 1987 parse_error(Tokens). 1988 1989parse_SignedNumber([{number,_,Value}|Rest]) -> 1990 {Value,Rest}; 1991parse_SignedNumber(Tokens) -> 1992 parse_error(Tokens). 1993 1994parse_Tag([{'[',_}|Rest]) -> 1995 {Class,Rest2} = parse_Class(Rest), 1996 {ClassNumber,Rest3} = 1997 case Rest2 of 1998 [{number,_,Num}|Rest21] -> 1999 {Num,Rest21}; 2000 _ -> 2001 parse_DefinedValue(Rest2) 2002 end, 2003 case Rest3 of 2004 [{']',_}|Rest4] -> 2005 {#tag{class=Class,number=ClassNumber},Rest4}; 2006 _ -> 2007 parse_error(Rest3) 2008 end. 2009 2010parse_Class([{'UNIVERSAL',_}|Rest]) -> 2011 {'UNIVERSAL',Rest}; 2012parse_Class([{'APPLICATION',_}|Rest]) -> 2013 {'APPLICATION',Rest}; 2014parse_Class([{'PRIVATE',_}|Rest]) -> 2015 {'PRIVATE',Rest}; 2016parse_Class(Tokens) -> 2017 {'CONTEXT',Tokens}. 2018 2019%% parse_Value(Tokens) -> Ret 2020%% Tokens = [Tok] 2021%% Tok = tuple() 2022%% Ret = term() 2023parse_Value(Tokens) -> 2024 Flist = [fun parse_BuiltinValue/1, 2025 fun parse_ValueFromObject/1, 2026 fun parse_DefinedValue/1], 2027 parse_or(Tokens, Flist). 2028 2029parse_BuiltinValue([{bstring,_,Bstr}|Rest]) -> 2030 {{bstring,Bstr},Rest}; 2031parse_BuiltinValue([{hstring,_,Hstr}|Rest]) -> 2032 {{hstring,Hstr},Rest}; 2033parse_BuiltinValue([{'{',_},{'}',_}|Rest]) -> 2034 {[],Rest}; 2035parse_BuiltinValue(Tokens = [{'{',_}|_Rest]) -> 2036 Flist = [ 2037 fun parse_SequenceOfValue/1, 2038 fun parse_SequenceValue/1, 2039 fun parse_ObjectIdentifierValue/1], 2040 parse_or(Tokens, Flist); 2041parse_BuiltinValue([#identifier{val=IdName},{':',_}|Rest]) -> 2042 {Value,Rest2} = parse_Value(Rest), 2043 {{'CHOICE',{IdName,Value}},Rest2}; 2044parse_BuiltinValue([{'NULL',_},{':',_}|_]=Tokens) -> 2045 parse_ObjectClassFieldValue(Tokens); 2046parse_BuiltinValue([{'NULL',_}|Rest]) -> 2047 {'NULL',Rest}; 2048parse_BuiltinValue([{'TRUE',_}|Rest]) -> 2049 {true,Rest}; 2050parse_BuiltinValue([{'FALSE',_}|Rest]) -> 2051 {false,Rest}; 2052parse_BuiltinValue([{'PLUS-INFINITY',_}|Rest]) -> 2053 {'PLUS-INFINITY',Rest}; 2054parse_BuiltinValue([{'MINUS-INFINITY',_}|Rest]) -> 2055 {'MINUS-INFINITY',Rest}; 2056parse_BuiltinValue([{cstring,_,Cstr}|Rest]) -> 2057 {Cstr,Rest}; 2058parse_BuiltinValue([{number,_,Num}|Rest]) -> 2059 {Num,Rest}; 2060parse_BuiltinValue(Tokens) -> 2061 parse_ObjectClassFieldValue(Tokens). 2062 2063parse_DefinedValue(Tokens) -> 2064 Flist = [fun parse_ParameterizedValue/1, 2065 fun parse_DefinedValue2/1], 2066 parse_or(Tokens, Flist). 2067 2068parse_DefinedValue2([{typereference,L1,Tname}, 2069 {'.',_}, 2070 #identifier{val=Idname}|Rest]) -> 2071 {#'Externalvaluereference'{pos=L1,module=Tname,value=Idname},Rest}; 2072%% valuereference 2073parse_DefinedValue2([#identifier{}=Id|Rest]) -> 2074 {identifier2Extvalueref(Id),Rest}; 2075parse_DefinedValue2(Tokens) -> 2076 parse_error(Tokens). 2077 2078 2079parse_SequenceValue([{'{',_}|Tokens]) -> 2080 parse_SequenceValue(Tokens, []). 2081 2082parse_SequenceValue([#identifier{pos=Pos,val=IdName}|Rest],Acc) -> 2083 {Value,Rest2} = parse_Value(Rest), 2084 SeqTag = #seqtag{pos=Pos,module=get(asn1_module),val=IdName}, 2085 case Rest2 of 2086 [{',',_}|Rest3] -> 2087 parse_SequenceValue(Rest3, [{SeqTag,Value}|Acc]); 2088 [{'}',_}|Rest3] -> 2089 {lists:reverse(Acc, [{SeqTag,Value}]),Rest3}; 2090 _ -> 2091 parse_error(Rest2) 2092 end; 2093parse_SequenceValue(Tokens,_Acc) -> 2094 parse_error(Tokens). 2095 2096parse_SequenceOfValue([{'{',_}|Tokens]) -> 2097 parse_SequenceOfValue(Tokens, []). 2098 2099parse_SequenceOfValue(Tokens,Acc) -> 2100 {Value,Rest2} = parse_Value(Tokens), 2101 case Rest2 of 2102 [{',',_}|Rest3] -> 2103 parse_SequenceOfValue(Rest3,[Value|Acc]); 2104 [{'}',_}|Rest3] -> 2105 {lists:reverse(Acc, [Value]),Rest3}; 2106 _ -> 2107 parse_error(Rest2) 2108 end. 2109 2110parse_ValueSetTypeAssignment([{typereference,L1,Name}|Rest]) -> 2111 {Type,Rest2} = parse_Type(Rest), 2112 case Rest2 of 2113 [{'::=',_}|Rest3] -> 2114 {ValueSet,Rest4} = parse_ValueSet(Rest3), 2115 {#valuedef{pos=L1,name=Name,type=Type,value=ValueSet, 2116 module=get(asn1_module)},Rest4}; 2117 _ -> 2118 parse_error(Rest2) 2119 end. 2120 2121parse_ValueSet([{'{',_}|Rest]) -> 2122 {Elems,Rest2} = parse_ElementSetSpecs(Rest), 2123 case Rest2 of 2124 [{'}',_}|Rest3] -> 2125 {{valueset,Elems},Rest3}; 2126 _ -> 2127 parse_error(Rest2) 2128 end; 2129parse_ValueSet(Tokens) -> 2130 parse_error(Tokens). 2131 2132parse_ValueAssignment([#identifier{pos=L1,val=IdName}|Rest]) -> 2133 {Type,Rest2} = parse_Type(Rest), 2134 case Rest2 of 2135 [{'::=',_}|Rest3] -> 2136 {Value,Rest4} = parse_Value(Rest3), 2137 {#valuedef{pos=L1,name=IdName,type=Type,value=Value, 2138 module=get(asn1_module)},Rest4}; 2139 _ -> 2140 parse_error(Rest2) 2141 end. 2142 2143%% SizeConstraint 2144parse_SubtypeElements([{'SIZE',_}|Tokens]) -> 2145 {Constraint,Rest} = parse_Constraint(Tokens), 2146 {{'SizeConstraint',Constraint#constraint.c},Rest}; 2147%% PermittedAlphabet 2148parse_SubtypeElements([{'FROM',_}|Tokens]) -> 2149 {Constraint,Rest} = parse_Constraint(Tokens), 2150 {{'PermittedAlphabet',Constraint#constraint.c},Rest}; 2151%% InnerTypeConstraints 2152parse_SubtypeElements([{'WITH',_},{'COMPONENT',_}|Tokens]) -> 2153 {Constraint,Rest} = parse_Constraint(Tokens), 2154 {{'WITH COMPONENT',Constraint},Rest}; 2155parse_SubtypeElements([{'WITH',_},{'COMPONENTS',_},{'{',_},{'...',_},{',',_}|Tokens]) -> 2156 {Constraint,Rest} = parse_TypeConstraints(Tokens), 2157 case Rest of 2158 [{'}',_}|Rest2] -> 2159 {{'WITH COMPONENTS',{'PartialSpecification',Constraint}},Rest2}; 2160 _ -> 2161 parse_error(Rest) 2162 end; 2163parse_SubtypeElements([{'WITH',_},{'COMPONENTS',_},{'{',_}|Tokens]) -> 2164 {Constraint,Rest} = parse_TypeConstraints(Tokens), 2165 case Rest of 2166 [{'}',_}|Rest2] -> 2167 {{'WITH COMPONENTS',{'FullSpecification',Constraint}},Rest2}; 2168 _ -> 2169 parse_error(Rest) 2170 end; 2171parse_SubtypeElements([{'PATTERN',_}|Tokens]) -> 2172 {Value,Rest} = parse_Value(Tokens), 2173 {{pattern,Value},Rest}; 2174parse_SubtypeElements(Tokens) -> 2175 Flist = [fun parse_ContainedSubtype/1, 2176 fun parse_Value/1, 2177 fun parse_MIN/1, 2178 fun parse_Type/1], 2179 case parse_or(Tokens, Flist) of 2180 {#type{},_}=Result -> 2181 Result; 2182 {Lower,[{'..',_}|Rest]} -> 2183 {Upper,Rest2} = parse_UpperEndpoint(Rest), 2184 {{'ValueRange',{Lower,Upper}},Rest2}; 2185 {Lower,[{'<',_},{'..',_}|Rest]} -> 2186 {Upper,Rest2} = parse_UpperEndpoint(Rest), 2187 {{'ValueRange',{{gt,Lower},Upper}},Rest2}; 2188 {Res={'ContainedSubtype',_Type},Rest} -> 2189 {Res,Rest}; 2190 {Value,Rest} -> 2191 {{'SingleValue',Value},Rest} 2192 end. 2193 2194parse_ContainedSubtype([{'INCLUDES',_}|Rest]) -> 2195 {Type,Rest2} = parse_Type(Rest), 2196 {{'ContainedSubtype',Type},Rest2}; 2197parse_ContainedSubtype(Tokens) -> 2198 parse_error(Tokens). 2199 2200parse_UpperEndpoint([{'<',_}|Rest]) -> 2201 parse_UpperEndpoint(lt,Rest); 2202parse_UpperEndpoint(Tokens) -> 2203 parse_UpperEndpoint(false,Tokens). 2204 2205parse_UpperEndpoint(Lt,Tokens) -> 2206 Flist = [fun parse_MAX/1, 2207 fun parse_Value/1], 2208 case parse_or(Tokens, Flist) of 2209 {Value,Rest2} when Lt =:= lt -> 2210 {{lt,Value},Rest2}; 2211 {Value,Rest2} -> 2212 {Value,Rest2} 2213 end. 2214 2215parse_MIN([{'MIN',_}|T]) -> 2216 {'MIN',T}; 2217parse_MIN(Tokens) -> 2218 parse_error(Tokens). 2219 2220parse_MAX([{'MAX',_}|T]) -> 2221 {'MAX',T}; 2222parse_MAX(Tokens) -> 2223 parse_error(Tokens). 2224 2225parse_TypeConstraints(Tokens) -> 2226 parse_TypeConstraints(Tokens, []). 2227 2228parse_TypeConstraints([#identifier{}|Rest], Acc) -> 2229 {ComponentConstraint,Rest2} = parse_ComponentConstraint(Rest), 2230 case Rest2 of 2231 [{',',_}|Rest3] -> 2232 parse_TypeConstraints(Rest3, [ComponentConstraint|Acc]); 2233 _ -> 2234 {lists:reverse(Acc, [ComponentConstraint]),Rest2} 2235 end; 2236parse_TypeConstraints(Tokens, _) -> 2237 parse_error(Tokens). 2238 2239parse_ComponentConstraint(Tokens = [{'(',_}|_Rest]) -> 2240 {ValueConstraint,Rest2} = parse_Constraint(Tokens), 2241 {PresenceConstraint,Rest3} = parse_PresenceConstraint(Rest2), 2242 {{ValueConstraint,PresenceConstraint},Rest3}; 2243parse_ComponentConstraint(Tokens) -> 2244 {PresenceConstraint,Rest} = parse_PresenceConstraint(Tokens), 2245 {{asn1_empty,PresenceConstraint},Rest}. 2246 2247parse_PresenceConstraint([{'PRESENT',_}|Rest]) -> 2248 {'PRESENT',Rest}; 2249parse_PresenceConstraint([{'ABSENT',_}|Rest]) -> 2250 {'ABSENT',Rest}; 2251parse_PresenceConstraint([{'OPTIONAL',_}|Rest]) -> 2252 {'OPTIONAL',Rest}; 2253parse_PresenceConstraint(Tokens) -> 2254 {asn1_empty,Tokens}. 2255 2256 2257merge_constraints(Clist) -> 2258 merge_constraints(Clist, [], []). 2259 2260merge_constraints([#constraint{c=C,e=E}|T], Cacc0, Eacc0) -> 2261 Eacc = case E of 2262 undefined -> Eacc0; 2263 E -> [E|Eacc0] 2264 end, 2265 Cacc = [C|Cacc0], 2266 merge_constraints(T, Cacc, Eacc); 2267merge_constraints([], Cacc, []) -> 2268 lists:reverse(Cacc); 2269merge_constraints([], Cacc, Eacc) -> 2270 lists:reverse(Cacc) ++ [{element_set,{'Errors',Eacc},none}]. 2271 2272get_line({Token,Pos,_}) when is_integer(Pos), is_atom(Token) -> 2273 Pos; 2274get_line({Token,Pos}) when is_integer(Pos),is_atom(Token) -> 2275 Pos. 2276 2277get_token({valuefieldreference,_,FieldName}) -> 2278 list_to_atom([$&|atom_to_list(FieldName)]); 2279get_token({typefieldreference,_,FieldName}) -> 2280 list_to_atom([$&|atom_to_list(FieldName)]); 2281get_token({Token,Pos,Value}) when is_integer(Pos), is_atom(Token) -> 2282 Value; 2283get_token({'$end',Pos}) when is_integer(Pos) -> 2284 'END-OF-FILE'; 2285get_token({Token,Pos}) when is_integer(Pos),is_atom(Token) -> 2286 Token. 2287 2288tref2Exttref(#typereference{pos=Pos,val=Name}) -> 2289 #'Externaltypereference'{pos=Pos, 2290 module=resolve_module(Name), 2291 type=Name}. 2292 2293tref2Exttref(Pos,Name) -> 2294 #'Externaltypereference'{pos=Pos, 2295 module=resolve_module(Name), 2296 type=Name}. 2297 2298identifier2Extvalueref(#identifier{pos=Pos,val=Name}) -> 2299 #'Externalvaluereference'{pos=Pos, 2300 module=resolve_module(Name), 2301 value=Name}. 2302 2303parse_error(Tokens) -> 2304 throw({asn1_error,{parse_error,Tokens}}). 2305