aboutsummaryrefslogtreecommitdiffstats
path: root/src/dmarc_parser.yrl
diff options
context:
space:
mode:
Diffstat (limited to 'src/dmarc_parser.yrl')
-rw-r--r--src/dmarc_parser.yrl31
1 files changed, 26 insertions, 5 deletions
diff --git a/src/dmarc_parser.yrl b/src/dmarc_parser.yrl
index c1f4e1d..14c375b 100644
--- a/src/dmarc_parser.yrl
+++ b/src/dmarc_parser.yrl
@@ -1,12 +1,14 @@
Nonterminals
- record property_list property optional_semicolon value.
+ record property_list property optional_semicolon value invalid_property.
Terminals
key equals semicolon string comma colon mailto.
Rootsymbol record.
-record -> property_list optional_semicolon : '$1'.
+record -> property_list optional_semicolon :
+ {Valid, Invalid} = separate_properties('$1'),
+ #{valid => maps:from_list(Valid), invalid => maps:from_list(Invalid)}.
optional_semicolon -> semicolon : [].
optional_semicolon -> '$empty' : [].
@@ -14,8 +16,13 @@ optional_semicolon -> '$empty' : [].
property_list -> property : ['$1'].
property_list -> property property_list : ['$1' | '$2'].
-property -> key equals value semicolon : {value('$1'), process_value(value('$1'), value_to_list('$3'))}.
-property -> key equals value : {value('$1'), process_value(value('$1'), value_to_list('$3'))}.
+property -> key equals value semicolon : {valid, {value('$1'), process_value(value('$1'), value_to_list('$3'))}}.
+property -> key equals value : {valid, {value('$1'), process_value(value('$1'), value_to_list('$3'))}}.
+
+property -> invalid_property : {invalid, '$1'}.
+
+invalid_property -> string equals value semicolon : {value('$1'), value_to_list('$3')}.
+invalid_property -> string equals value : {value('$1'), value_to_list('$3')}.
value -> mailto : '$1'.
value -> mailto comma value : join_values('$1', '$3').
@@ -23,7 +30,7 @@ value -> mailto comma value : join_values('$1', '$3').
value -> string : '$1'.
value -> string colon value : join_values('$1', '$3').
-Expect 1.
+Expect 2.
Erlang code.
@@ -45,3 +52,17 @@ process_value(_Key, [Value]) ->
value(Value);
process_value(_Key, Values) ->
[value(V) || V <- Values].
+
+separate_properties(Properties) ->
+ separate_properties(Properties, [], []).
+
+separate_properties([], ValidAcc, InvalidAcc) ->
+ {lists:reverse(ValidAcc), lists:reverse(InvalidAcc)};
+separate_properties([{valid, Property} | Rest], ValidAcc, InvalidAcc) ->
+ separate_properties(Rest, [Property | ValidAcc], InvalidAcc);
+separate_properties([{invalid, {Key, Values}} | Rest], ValidAcc, InvalidAcc) ->
+ ProcessedValues = case Values of
+ [SingleValue] -> value(SingleValue);
+ MultipleValues -> [value(V) || V <- MultipleValues]
+ end,
+ separate_properties(Rest, ValidAcc, [{Key, ProcessedValues} | InvalidAcc]).