Skip to content

Instantly share code, notes, and snippets.

@sfkeller
Created September 15, 2024 19:14
Show Gist options
  • Save sfkeller/43800cd64014d17c55e40fa5e877fd6a to your computer and use it in GitHub Desktop.
Save sfkeller/43800cd64014d17c55e40fa5e877fd6a to your computer and use it in GitHub Desktop.
Overpass QL EBNF Grammar, Version 0.2, by Stefan Keller and with the help of ChatGPT.
(* Overpass QL EBNF Grammar *)
(* Query *)
query ::= ( global_option )* ( statement )+ ( output_statement )*
(* Global Options *)
global_option ::= '[' option ( ';' option )* ']'
option ::= 'out:' format
| 'timeout:' number
| 'maxsize:' number
| 'bbox:' bbox
| 'date:' date
| 'diff:' date ',' date
| 'resolve-aliases:' boolean
| 'force:' boolean
boolean ::= 'true' | 'false'
(* Statements *)
statement ::= fetch_statement
| area_statement
| assignment_statement
| union_statement
| difference_statement
| intersection_statement
| recurse_statement
| foreach_statement
| if_statement
| print_statement
| make_statement
| count_statement
(* Fetch Statement *)
fetch_statement ::= element_type ( filter )* ( search_area )? ( ';' | '{' ( statement )+ '}' )
element_type ::= 'node' | 'way' | 'relation' | 'nwr'
(* Filters *)
filter ::= '[' attribute_filter ']'
| '[' attribute_regexp_filter ']'
| '[' attribute_negation_filter ']'
| '(' bounding_clause ')'
| '[if:' condition ']'
attribute_filter ::= key operator value
attribute_regexp_filter::= key operator_regex regex_value
attribute_negation_filter ::= '!' key
operator ::= '=' | '!='
operator_regex ::= '~' | '!~'
regex_value ::= '"' regex_pattern '"'
(* Bounding Clause *)
bounding_clause ::= bbox
| 'around' ':' radius ( ',' lat ',' lon )?
| 'poly' ':' '"' coordinates '"'
(* Search Area *)
search_area ::= '(' area_selector ')'
area_selector ::= 'area' ( '.' variable )?
| 'area' '(' query ')'
(* Assignment Statement *)
assignment_statement ::= variable '=' expression ';'
expression ::= fetch_statement
| union_statement
| difference_statement
| intersection_statement
| recurse_statement
| '(' statement_list ')'
(* Union Statement *)
union_statement ::= '(' statement_list ')'
statement_list ::= statement ( ';' statement )* ( ';' )?
(* Difference Statement *)
difference_statement ::= '(' statement ';' '-' statement ( ';' )? ')'
(* Intersection Statement *)
intersection_statement ::= '(' statement ';' statement ( ';' )? ')'
(* Recurse Statement *)
recurse_statement ::= ( variable ':' )? element_type recurse_operator ';'
recurse_operator ::= '>' | '<' | '<<' | '>>' | '>' letter
(* Foreach Statement *)
foreach_statement ::= 'foreach' '(' variable ')' '{' ( statement )+ '}'
(* If Statement *)
if_statement ::= 'if' '(' condition ')' '{' ( statement )+ '}'
(* Print Statement *)
print_statement ::= 'print' ( variable )? ( output_modifiers )* ';'
(* Make Statement *)
make_statement ::= 'make' 'area' '(' statement ')' '->' variable ';'
(* Count Statement *)
count_statement ::= 'count' '(' element_type ')' ';'
(* Area Statement *)
area_statement ::= 'area' area_filter '->' variable ';'
area_filter ::= '[' attribute_filter ']'
(* Output Statement *)
output_statement ::= 'out' output_modifiers* ';'
output_modifiers ::= 'body' | 'skel' | 'tags' | 'meta' | 'geom' | 'center' | 'ids' | 'qt' | 'count' | 'bb'
(* Variable *)
variable ::= '.' identifier
(* Identifier *)
identifier ::= letter ( letter | digit | '_' )*
(* Key and Value *)
key ::= '"' identifier '"'
value ::= '"' string '"'
(* Condition *)
condition ::= logical_expression
logical_expression ::= logical_term ( ( 'and' | 'or' ) logical_term )*
logical_term ::= '(' logical_expression ')'
| comparison
comparison ::= expression comparison_operator expression
comparison_operator ::= '=' | '!=' | '>' | '<' | '>=' | '<='
(* Expressions *)
expression ::= variable
| function_call
| value
| number
function_call ::= function_name '(' ( expression ( ',' expression )* )? ')'
function_name ::= identifier
(* Numbers and Strings *)
number ::= digit+ ( '.' digit+ )?
digit ::= '0'..'9'
letter ::= 'a'..'z' | 'A'..'Z'
string ::= character*
character ::= any character except '"'
regex_pattern ::= character*
(* Bounding Box and Coordinates *)
bbox ::= number ',' number ',' number ',' number
radius ::= number
lat ::= number
lon ::= number
coordinates ::= number ( ' ' number )+ ( ',' number ( ' ' number )+ )*
(* Date *)
date ::= '"' iso8601_date '"'
iso8601_date ::= year '-' month '-' day 'T' hour ':' minute ':' second 'Z'
year ::= digit digit digit digit
month ::= digit digit
day ::= digit digit
hour ::= digit digit
minute ::= digit digit
second ::= digit digit
(* Format *)
format ::= 'json' | 'xml' | 'csv' | 'popup'
(* Terminals *)
character ::= any character except '"'
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment