// Symbols
file1_header_start = { "---" }
file2_header_start = { "+++" }
context_header_delimiter = { "@@" }
context_line_start = { SPACE_SEPARATOR }
deleted_line_start = { "-" }
inserted_line_start = { "+" }
path_timestamp_delimiter = { "\t" }
// Values
path = { (!"\t" ~ ANY)+ }
file1_l = { NUMBER+ }
file1_s = { NUMBER+ }
file2_l = { NUMBER+ }
file2_s = { NUMBER+ }
// Lines
line = { (!NEWLINE ~ ANY)* }
timestamp = { line }
line_context = { line }
line_deleted = { line }
line_inserted = { line }
// Headers
file1_header = { file1_header_start ~ SPACE_SEPARATOR ~ path ~ path_timestamp_delimiter ~ timestamp ~ NEWLINE }
file2_header = { file2_header_start ~ SPACE_SEPARATOR ~ path ~ path_timestamp_delimiter ~ timestamp ~ NEWLINE }
context_header = {
context_header_delimiter ~ SPACE_SEPARATOR ~
"-" ~ file1_l ~ "," ~ file1_s ~ SPACE_SEPARATOR ~
"+" ~ file2_l ~ "," ~ file2_s ~ SPACE_SEPARATOR ~
context_header_delimiter ~ SPACE_SEPARATOR? ~ line ~ NEWLINE
}
// Sections
context = {
context_header ~ (
(context_line_start ~ line_context ~ NEWLINE) |
(deleted_line_start ~ line_deleted ~ NEWLINE) |
(inserted_line_start ~ line_inserted ~ NEWLINE)
)+
}
patch = {
SOI ~
file1_header ~
file2_header ~
context+ ~
EOI
}