defmodule HL7.PathParser do import NimbleParsec numeric_index = integer(min: 1) index = choice([numeric_index, string("*")]) bracketed_num = ignore(string("[")) |> concat(index) |> ignore(string("]")) defaulted_num = choice([bracketed_num, empty()]) dot = ignore(string(".")) dash = ignore(string("-")) bang = string("!") |> replace(true) |> tag(:truncate) field = optional(dash) |> concat(index) |> tag(:field) alpha = ascii_string([?A..?Z], 1) alpha_num = choice([ascii_string([?0..?9], 1), alpha]) segment_id = alpha |> concat(alpha_num) |> concat(alpha_num) |> reduce({Enum, :join, [""]}) |> tag(:segment) segment_num = defaulted_num |> tag(:segment_number) segment_header = optional(segment_id |> concat(segment_num)) repeat_num = defaulted_num |> tag(:repetition) component = index |> tag(:component) subcomponent = index |> tag(:subcomponent) component_part = dot |> concat(component) |> optional(concat(dot, subcomponent)) defparsec( :parse, segment_header |> optional(field) |> optional(repeat_num) |> optional(component_part) |> optional(bang) |> eos() ) end