aboutsummaryrefslogtreecommitdiffstats
path: root/lib/diameter/src/compiler/diameter_dict_parser.yrl
diff options
context:
space:
mode:
authorAnders Svensson <[email protected]>2011-12-07 16:51:46 +0100
committerAnders Svensson <[email protected]>2011-12-07 16:51:46 +0100
commit24f0d3ee266d56cc83435401230a8bb85a0464d3 (patch)
treeecb3a5e9d8539e87efb5677494894f3ced97a2cb /lib/diameter/src/compiler/diameter_dict_parser.yrl
parent977f7510818925d9293361c14788fdb872614ac1 (diff)
parentf2a4059d06f8b76d2c1da14197f170deebd64f45 (diff)
downloadotp-24f0d3ee266d56cc83435401230a8bb85a0464d3.tar.gz
otp-24f0d3ee266d56cc83435401230a8bb85a0464d3.tar.bz2
otp-24f0d3ee266d56cc83435401230a8bb85a0464d3.zip
Merge branch 'anders/diameter/dict_error_identification/OTP-9639'
* anders/diameter/dict_error_identification/OTP-9639: (27 commits) Update documentation Improve base_rfc3588.dia formatting Make typo fix backwards compatible Fix base_rfc3588.dia typo Check compiler dependencies in app suite Move type definitions into diameter.erl Fix interpretation of vendor id in @grouped Add range checks on dictionary integers Don't explicitly load inherited modules Tweak diameter_make interface Add format testcase to compiler suite Add diameter_dict_util:format/1 for reconstructing a dictionary file Make diameter_types usable with @codecs Minor codegen tweaks Remove unnecessary includes Add compiler suite Update app suite Update codec suite Vendor id fixes No longer inherit common dictionary in relay dictionary ...
Diffstat (limited to 'lib/diameter/src/compiler/diameter_dict_parser.yrl')
-rw-r--r--lib/diameter/src/compiler/diameter_dict_parser.yrl324
1 files changed, 324 insertions, 0 deletions
diff --git a/lib/diameter/src/compiler/diameter_dict_parser.yrl b/lib/diameter/src/compiler/diameter_dict_parser.yrl
new file mode 100644
index 0000000000..6fd4cedd23
--- /dev/null
+++ b/lib/diameter/src/compiler/diameter_dict_parser.yrl
@@ -0,0 +1,324 @@
+%% -*- erlang -*-
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2010-2011. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+
+%%
+%% A grammar for dictionary specification.
+%%
+
+Nonterminals
+ application_id avp avp_code avp_def avp_defs avp_flags avp_header
+ avp_header_tok avp_name avp_names avp_ref avp_spec avp_type
+ avp_vendor avps bit bits command_def command_id diameter_name
+ dictionary enum_def enum_defs group_def group_defs header header_tok
+ ident idents message_defs module qual section sections.
+
+Terminals
+ avp_types avp_vendor_id codecs custom_types define enum grouped
+ id inherits messages name prefix vendor
+ number word
+ '{' '}' '<' '>' '[' ']' '*' '::=' ':' ',' '-'
+ code
+ 'answer-message'
+ 'AVP' 'AVP-Header'
+ 'Diameter' 'Diameter-Header' 'Header'
+ 'REQ' 'PXY' 'ERR'.
+
+Rootsymbol dictionary.
+
+Endsymbol '$end'.
+
+%% ===========================================================================
+
+dictionary -> sections : '$1'.
+
+sections -> '$empty' : [].
+sections -> section sections : ['$1' | '$2'].
+
+section -> name ident : ['$1', '$2'].
+section -> prefix ident : ['$1', '$2'].
+section -> id number : ['$1', '$2'].
+section -> vendor number ident : ['$1', '$2', '$3'].
+section -> inherits module avp_names : ['$1', '$2' | '$3'].
+section -> avp_types avp_defs : ['$1' | '$2'].
+section -> avp_vendor_id number avp_names : ['$1', '$2' | '$3'].
+section -> custom_types module avp_names : ['$1', '$2' | '$3'].
+section -> codecs module avp_names : ['$1', '$2' | '$3'].
+section -> messages message_defs : ['$1' | '$2'].
+section -> grouped group_defs : ['$1' | '$2'].
+section -> enum ident enum_defs : ['$1', '$2' | '$3'].
+section -> define ident enum_defs : ['$1', '$2' | '$3'].
+
+%% =====================================
+
+module -> ident : '$1'.
+
+avp_names -> idents : '$1'. %% Note: not 'AVP'
+
+avp_defs -> '$empty' : [].
+avp_defs -> avp_def avp_defs : ['$1' | '$2'].
+
+avp_def -> ident number avp_type avp_flags : ['$1', '$2', '$3', '$4'].
+
+avp_type -> ident : '$1'.
+
+idents -> '$empty' : [].
+idents -> ident idents : ['$1' | '$2'].
+
+avp_flags -> '-' :
+ {_, Lineno} = '$1',
+ {word, Lineno, ""}.
+avp_flags -> ident :
+ '$1'.
+%% Could support lowercase here if there's a use for distinguishing
+%% between Must and Should in the future in deciding whether or not
+%% to set a flag.
+
+ident -> word : '$1'.
+
+%% Don't bother mapping reserved words to make these usable in this
+%% context. That an AVP can't be named Diameter-Header is probably no
+%% great loss, and that it can't be named AVP may even save someone
+%% from themselves. (Temporarily at least.)
+
+group_defs -> '$empty' : [].
+group_defs -> group_def group_defs : ['$1' | '$2'].
+
+message_defs -> '$empty' : [].
+message_defs -> command_def message_defs : ['$1' | '$2'].
+
+enum_defs -> '$empty' : [].
+enum_defs -> enum_def enum_defs : ['$1' | '$2'].
+
+enum_def -> ident number : ['$1', '$2'].
+
+%% =====================================
+%% 3.2. Command Code ABNF specification
+%%
+%% Every Command Code defined MUST include a corresponding ABNF
+%% specification, which is used to define the AVPs that MUST or MAY be
+%% present when sending the message. The following format is used in
+%% the definition:
+
+%% command-def = <command-name> "::=" diameter-message
+%%
+%% command-name = diameter-name
+%%
+%% diameter-name = ALPHA *(ALPHA / DIGIT / "-")
+%%
+%% diameter-message = header [ *fixed] [ *required] [ *optional]
+
+%% answer-message is a special case.
+command_def -> 'answer-message' '::=' '<' header_tok ':' code
+ ',' 'ERR' '[' 'PXY' ']' '>'
+ avps
+ : ['$1', false | '$13'].
+
+command_def -> diameter_name '::=' header avps
+ : ['$1', '$3' | '$4'].
+%% Ensure the order fixed/required/optional by semantic checks rather
+%% than grammatically since the latter requires more lookahead: don't
+%% know until after a leading qual which of the three it is that's
+%% being parsed.
+
+diameter_name -> ident : '$1'.
+
+%% header = "<" "Diameter Header:" command-id
+%% [r-bit] [p-bit] [e-bit] [application-id] ">"
+%%
+%% command-id = 1*DIGIT
+%% ; The Command Code assigned to the command
+%%
+%% r-bit = ", REQ"
+%% ; If present, the 'R' bit in the Command
+%% ; Flags is set, indicating that the message
+%% ; is a request, as opposed to an answer.
+%%
+%% p-bit = ", PXY"
+%% ; If present, the 'P' bit in the Command
+%% ; Flags is set, indicating that the message
+%% ; is proxiable.
+%%
+%% e-bit = ", ERR"
+%% ; If present, the 'E' bit in the Command
+%% ; Flags is set, indicating that the answer
+%% ; message contains a Result-Code AVP in
+%% ; the "protocol error" class.
+%%
+%% application-id = 1*DIGIT
+
+header -> '<' header_tok ':' command_id bits application_id '>'
+ : ['$4', '$5', '$6'].
+
+command_id -> number : '$1'.
+
+%% Accept both the form of the base definition and the typo (fixed in
+%% 3588bis) of the grammar.
+header_tok -> 'Diameter' 'Header'.
+header_tok -> 'Diameter-Header'.
+
+bits -> '$empty' : [].
+bits -> ',' bit bits : ['$2' | '$3'].
+
+%% ERR only makes sense for answer-message so don't allow it here
+%% (despite 3588).
+bit -> 'REQ' : '$1'.
+bit -> 'PXY' : '$1'.
+
+application_id -> '$empty' : false.
+application_id -> number : '$1'.
+
+%% fixed = [qual] "<" avp-spec ">"
+%% ; Defines the fixed position of an AVP
+%%
+%% required = [qual] "{" avp-spec "}"
+%% ; The AVP MUST be present and can appear
+%% ; anywhere in the message.
+%%
+%% optional = [qual] "[" avp-name "]"
+%% ; The avp-name in the 'optional' rule cannot
+%% ; evaluate to any AVP Name which is included
+%% ; in a fixed or required rule. The AVP can
+%% ; appear anywhere in the message.
+%% ;
+%% ; NOTE: "[" and "]" have a slightly different
+%% ; meaning than in ABNF (RFC 5234]). These braces
+%% ; cannot be used to express optional fixed rules
+%% ; (such as an optional ICV at the end). To do this,
+%% ; the convention is '0*1fixed'.
+
+avps -> '$empty' : [].
+avps -> avp avps : ['$1' | '$2'].
+
+avp -> avp_ref : [false | '$1'].
+avp -> qual avp_ref : ['$1' | '$2'].
+
+avp_ref -> '<' avp_spec '>' : [$<, '$2'].
+avp_ref -> '{' avp_name '}' : [${, '$2'].
+avp_ref -> '[' avp_name ']' : [$[, '$2'].
+%% Note that required can be an avp_name, not just avp_spec. 'AVP'
+%% is specified as required by Failed-AVP for example.
+
+%% qual = [min] "*" [max]
+%% ; See ABNF conventions, RFC 5234 Section 4.
+%% ; The absence of any qualifiers depends on
+%% ; whether it precedes a fixed, required, or
+%% ; optional rule. If a fixed or required rule has
+%% ; no qualifier, then exactly one such AVP MUST
+%% ; be present. If an optional rule has no
+%% ; qualifier, then 0 or 1 such AVP may be
+%% ; present. If an optional rule has a qualifier,
+%% ; then the value of min MUST be 0 if present.
+%%
+%% min = 1*DIGIT
+%% ; The minimum number of times the element may
+%% ; be present. If absent, the default value is zero
+%% ; for fixed and optional rules and one for required
+%% ; rules. The value MUST be at least one for for
+%% ; required rules.
+%%
+%% max = 1*DIGIT
+%% ; The maximum number of times the element may
+%% ; be present. If absent, the default value is
+%% ; infinity. A value of zero implies the AVP MUST
+%% ; NOT be present.
+
+qual -> number '*' number : {'$1', '$3'}.
+qual -> number '*' : {'$1', true}.
+qual -> '*' number : {true, '$2'}.
+qual -> '*' : true.
+
+%% avp-spec = diameter-name
+%% ; The avp-spec has to be an AVP Name, defined
+%% ; in the base or extended Diameter
+%% ; specifications.
+
+avp_spec -> diameter_name : '$1'.
+
+%% avp-name = avp-spec / "AVP"
+%% ; The string "AVP" stands for *any* arbitrary AVP
+%% ; Name, not otherwise listed in that command code
+%% ; definition. Addition this AVP is recommended for
+%% ; all command ABNFs to allow for extensibility.
+
+avp_name -> 'AVP' : '$1'.
+avp_name -> avp_spec : '$1'.
+
+%% The following is a definition of a fictitious command code:
+%%
+%% Example-Request ::= < Diameter Header: 9999999, REQ, PXY >
+%% { User-Name }
+%% * { Origin-Host }
+%% * [ AVP ]
+
+%% =====================================
+%% 4.4. Grouped AVP Values
+%%
+%% The Diameter protocol allows AVP values of type 'Grouped'. This
+%% implies that the Data field is actually a sequence of AVPs. It is
+%% possible to include an AVP with a Grouped type within a Grouped type,
+%% that is, to nest them. AVPs within an AVP of type Grouped have the
+%% same padding requirements as non-Grouped AVPs, as defined in Section
+%% 4.
+%%
+%% The AVP Code numbering space of all AVPs included in a Grouped AVP is
+%% the same as for non-grouped AVPs. Receivers of a Grouped AVP that
+%% does not have the 'M' (mandatory) bit set and one or more of the
+%% encapsulated AVPs within the group has the 'M' (mandatory) bit set
+%% MAY simply be ignored if the Grouped AVP itself is unrecognized. The
+%% rule applies even if the encapsulated AVP with its 'M' (mandatory)
+%% bit set is further encapsulated within other sub-groups; i.e. other
+%% Grouped AVPs embedded within the Grouped AVP.
+%%
+%% Every Grouped AVP defined MUST include a corresponding grammar, using
+%% ABNF [RFC5234] (with modifications), as defined below.
+
+%% grouped-avp-def = <name> "::=" avp
+%%
+%% name-fmt = ALPHA *(ALPHA / DIGIT / "-")
+%%
+%% name = name-fmt
+%% ; The name has to be the name of an AVP,
+%% ; defined in the base or extended Diameter
+%% ; specifications.
+%%
+%% avp = header [ *fixed] [ *required] [ *optional]
+
+group_def -> ident '::=' avp_header avps : ['$1', '$3' | '$4'].
+
+%% header = "<" "AVP-Header:" avpcode [vendor] ">"
+%%
+%% avpcode = 1*DIGIT
+%% ; The AVP Code assigned to the Grouped AVP
+%%
+%% vendor = 1*DIGIT
+%% ; The Vendor-ID assigned to the Grouped AVP.
+%% ; If absent, the default value of zero is
+%% ; used.
+
+avp_header -> '<' avp_header_tok ':' avp_code avp_vendor '>'
+ : ['$4', '$5'].
+
+avp_header_tok -> 'AVP-Header'.
+avp_header_tok -> 'AVP' 'Header'.
+
+avp_code -> number : '$1'.
+
+avp_vendor -> '$empty' : false.
+avp_vendor -> number : '$1'.