Skip to content

Instantly share code, notes, and snippets.

@azatoth
Last active April 25, 2023 14:22
Show Gist options
  • Save azatoth/786486ccf112f11dd407049ba8b81166 to your computer and use it in GitHub Desktop.
Save azatoth/786486ccf112f11dd407049ba8b81166 to your computer and use it in GitHub Desktop.
Nearly grammer for TFRs
@{%
const { DateTime } = require("luxon");
%}
@builtin "postprocessors.ne"
@builtin "whitespace.ne"
notam -> "!" prefix __
notam_id __
airspace __
part:? _
preamble __:+
bounded_by:? _
height _
effective_date:? _
postamble __
dates [^]:* {%
$({
prefix: 1,
id: 3,
airspace: 5,
preamble: 9,
bounds: 11,
height: 13,
effective_date: 15,
postamble: 17,
dates: 19,
})
%}
prefix -> [A-Z]:+ {% prefix %}
part -> "PART" __ ints __ "OF" __ ints {% $({current:2, total:6}) %}
end_part -> "END" __ "PART" __ [0-9]:+ __ "OF" __ [0-9]:+ {% $({current:1, total:3}) %}
notam_id -> [0-9]:+ "/" [0-9]:+ {% notam_id %}
airspace -> [A-Z]:+ {% airspace %}
preamble -> [A-Z0-9/.\s-;,]:+ {% preamble %}
bounded_by -> bounded_prefix _ (bound_radius | bound_list (_ to_point_of_origin):? ) {% bounded_by %}
bound_list -> delimited[coord_frd, __ "TO" __] ".":? {% bound_list %}
bound_radius -> xnm __ "RADIUS" __ "OF" __ coord_frd {% $({radius: 0, center: 6}) %}
xnm -> [0-9]:+ ".":? [0-9]:* "NM" {% xnm %}
coord_frd -> coord __:? frd:? {% $({coord: 0, frd: 2}) %}
frd -> "(" ([A-Z] [A-Z] [A-Z] [0-9] [0-9] [0-9] [0-9] [0-9] [0-9] ("." [0-9]):?) ")" {% frd %}
coord -> point "/":? point {% coord %}
point -> ([0-9]:+ [NEWS]) {% point %}
bounded_prefix -> "WI" "THIN":? __ "AN" __ ("AREA" __):? ( "BOUNDED" __ "BY" | "DEFINED" __ "AS" ) ".":? {% bounded_prefix %}
to_point_of_origin -> "TO" (__ "THE"):? __ "POINT" __ "OF" __ "ORIGIN" ".":? {% to_point_of_origin %}
effective_date -> "EFFECTIVE" __ date __ "UNTIL" __ date "." {% $({from: 2, to: 6}) %}
date -> utc_date __ "(" local_date ")" {% $({utc: 0, local: 3}) %}
utc_date -> (ii ii ii ii ii) __ "UTC" {% utc_date %}
local_date -> ii ii __ "LOCAL" __ ii "/" ii "/" ii {% local_date %}
ii -> [0-9] [0-9] {% d => d.join("") %}
height -> "SFC" "-" ( height_ft | height_unl | height_fl ) __ "MSL":? ".":? _ {% height %}
height_ft -> [0-9]:+ _ "FT" {% height_ft %}
height_unl -> "UNL" {% height_unl %}
height_fl -> "FL" _ [0-9]:+ {% height_fl %}
postamble -> ([A-Z0-9.\s/:,();-]):+ {% postamble %}
dates -> int10 "-" int10 {% dates %}
int10 -> [0-9] [0-9] [0-9] [0-9] [0-9] [0-9] [0-9] [0-9] [0-9] [0-9]
ints -> [0-9]:+ {% d => parseInt(d.join("")) %}
@{%
const parseDate = (str) => {
return DateTime.fromFormat(str, "yyMMddHHmm", { zone: "utc" }).toJSON();
};
const parseLocalDate = (str) => {
return DateTime.fromFormat(str, "HHmm MM/dd/yy", { zone: "America/Chicago" }).toJSON();
};
const prefix = (d) => d[0].join('');
const notam_id = (d) => d[0].join('') + "/" + d[2].join('');
const airspace = (d) => d[0].join('');
const preamble = (d,l,reject) => {
const str = d.flat().join("").replace(/\s+/gm, " ").trim()
if(/WI(THIN)?\sAN/.test(str) || /PART \d+ OF \d+/.test(str)) {
return reject;
}
return str
};
const bounded_by = (d) => {
const list = d[2];
if (d[3]) {
list.push(list[0]);
}
return list;
};
const bound_list = (d) => d[0].flat();
const point = (d) => d[0].flat().join("");
const frd = (d) => d[1].flat().join("");
const xnm = (d) => Number.parseFloat(d.slice(0,3).join(""), 10) + " " + d[3];
const coord = (d) => d[0] + "/" + d[2];
const bounded_prefix = (d) => d.join("");
const to_point_of_origin = () => true;
const height = (d) => d[2].join('');
const height_ft = (d) => d[0].join('') + "ft";
const height_fl = (d) => "fl" + d[2].join('');
const height_unl = () => "unlimited";
const postamble = (d,l,reject) => {
const str = d.flat().join("").replace(/\s+/g, " ").trim();
if(/\d{10}-\d{10}$/.test(d)) {
return reject;
}
return str;
};
const dates = (d) => ({
from: parseDate(d[0].join('')),
to: parseDate(d[2].join('')),
});
const utc_date = (d) => parseDate(d[0].join(""))
const local_date = (d) => parseLocalDate(`${d[0]}${d[1]} ${d[5]}/${d[7]}/${d[9]}`);
%}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment