Permalink
Switch branches/tags
Nothing to show
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
123 lines (105 sloc) 2.74 KB
!!!
###
# These are some helper functions and macros used throughout the parser
###
require Logger
def get_val(token) do
case :lists.flatten(token) do
[] -> nil
r -> hd r
end
end
defmacro to_s() do
quote do
_ = var!(string_values)
_ = var!(values)
state = var!(state)
rule = var!(rule)
{:ok, state, to_string(rule)}
end
end
!!!
; This grammar is taken from
; https://en.wikipedia.org/wiki/Augmented_Backus%E2%80%93Naur_Form#Example
postal-address = name-part street zip-part !!!
_ = rule
_ = string_values
[name, street, zip] = values
{:ok, state, %{
name: get_val(name),
street: get_val(street),
zip: get_val(zip)
}}
!!!
name-part = personal-part SP *(personal-part SP) [suffix] CRLF !!!
_ = rule
_ = values
# Remove CRLF and get the name
[_|name] = Enum.reverse string_values
name = to_string Enum.reverse(name)
{:ok, state, name}
!!!
personal-part = first-name / (initial ".") !!! to_s() !!!
first-name = *ALPHA !!! to_s() !!!
initial = ALPHA !!! to_s() !!!
last-name = *ALPHA !!! to_s() !!!
suffix = ("Jr." / "Sr." / 1*("I" / "V" / "X")) !!! to_s() !!!
street = [apt SP] house-num SP street-name CRLF !!!
_ = rule
_ = string_values
[apt, house, _, street, _] = values
apt = get_val apt
house = get_val house
street = get_val street
{:ok, state, %{
apartment: apt,
house: house,
street: street
}}
!!!
apt = 1*4DIGIT !!!
_ = values
_ = string_values
{apt, ""} = Integer.parse to_string(rule)
{:ok, state, apt}
!!!
house-num = 1*8(DIGIT / ALPHA) !!! to_s() !!!
street-name = 1*VCHAR !!! to_s() !!!
zip-part = town-name "," SP state 1*2SP zip-code CRLF !!!
_ = rule
_ = string_values
[town, _, _, st, _, zip, _] = values
town = get_val town
st = get_val st
zip = get_val zip
{:ok, state, %{
town: town,
state: st,
zip: zip
}}
!!!
town-name = 1*(ALPHA / SP) !!! to_s() !!!
state = 2ALPHA !!! to_s() !!!
zip-code = 5DIGIT ["-" 4DIGIT] !!!
_ = rule
_ = values
[code, extended] = string_values
{code, ""} = Integer.parse to_string(code)
extended = case extended do
[] -> nil
[?-|extended] ->
{extended, ""} = Integer.parse to_string(extended)
extended
end
{:ok, state, %{
code: code,
extended: extended
}}
!!!
DIGIT = %x30-39 ; Decimal digits (0-9)
ALPHA = %x41-5A / %x61-7A ; Upper and lower case ASCII letters (A-Z, a-z)
VCHAR = %x21-7E ; visible (printing) characters
SP = %x20 ; space
CRLF = CR LF ; Internet standard newline
CR = %x0D ; carriage return
LF = %x0A ; linefeed