Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
154 changes: 154 additions & 0 deletions pfftt.bnf
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
; A grammar for the Procedure interchange Format For Transferring Techniques.
; This format is carefully defined to simplify parsing. Whitespace only
; appears when defined.
;
; This is written in the style of a Backus–Naur Form with a few augmentations.
; When specified, character classes are in the style of those accepted by
; regular expressions, such as [a-z]. Explicitly required characters such as
; spaces are marked with [ ]; a [.] represents a period and not any character.
; Otherwise special characters in regular expressions are not shown escaped.
;
; The convention adopted here is that names that represent actual types in the
; parser are in Proper Case whereas other definitions (often
; representing variants in enumerations in the implementation) are written in
; snake_case.

NEWLINE := "\n" | "\r\n"

; A single space character is the separator between fields
SPACE := " "

; Specially defined as any characters but matching lazily, such that whatever
; token or pattern that follows is excluded.
ANY

; A PFFTT file is a series of record lines.

File := Record*

Record :=
Timestamp
SPACE
RunId
SPACE
Path
SPACE
State
NEWLINE

; ISO 8601 timestamp
Timestamp := year '-' month '-' day 'T' hour ':' minute ':' second ('.' fraction)? 'Z'

year := [12][0-9][0-9][0-9]
month := [0-1][0-9]
day := [0-9][0-9]

hour := [0-2][0-9]
minute := [0-5][0-9]
second := [0-5][0-9]

; Optional fractions of a second can be to arbitrary precision, but in
; practice this is either milliseconds (three digits) or nanoseconds (nine
; digits).
fraction := [0-9]*

Identifier := [a-z][a-z0-9_]*

uri := ("https://" | "file:///") [a-zA-Z0-9.,?&#%=:/+-~_]+

; the "fully qualified" path of a step. There are implicit nodes (when no
; top-level procedure is defined, for example, and for the case where actions
; are defined in the description of a procedure). The following are all valid
; paths:
;
; /
; /2
; /2/a/-1
; /local_network:
; /local_network:2
; /local_network:2/a/-1

Path := "/" procedure? ( component ( "/" component )* )?

procedure := Identifier ":"

component := section | step | substep | subsubstep | attribute

section := [IVX]+

step := dependent_step | parallel_step
dependent_step := [1-9][0-9]*
parallel_step := [-]([0-9]|[1-9][0-9])

substep := dependent_substep | parallel_substep
dependent_substep := [a-hj-km-uwyz]
parallel_substep := [-]([0-9]|[1-9][0-9])

subsubstep := dependent_subsubstep | parallel_subsubstep
dependent_subsubstep := [ivxl]+
parallel_subsubstep := [-]([0-9]|[1-9][0-9])

attribute := role_attribute | place_attribute
role_attribute := "@" Identifier | "@*"
place_attribute := "^" Identifier | "^*"

; Activity verbs and payloads, collectively the event being observed. Done is
; the most important, recording an outcome of a step. Begin marks the start
; of work on a step (paired with the eventual Done/Skip/Fail); duration is
; derived from the pair. Invoke marks dispatch from the current procedure
; into another (the return is implicit — the next event's Path reveals the
; resumed procedure). Execute records a function call out to the host
; environment.

State :=
"Start" SPACE uri |
"Stop" |
"Resume" |
"Finish" |
"Invoke" SPACE invocable |
"Execute" SPACE executable |
"Return" SPACE Value |
"Input" SPACE supplied |
"Begin" |
"Done" SPACE Value |
"Skip" |
"Fail" (SPACE Value)?

RunId := [0-9]+

invocable := procedure | uri

executable := Identifier "()"

; The values supplied to a procedure as parameters. Each value is shown
; bound to its parameter name with `~` if one was declared, otherwise is
; left bare when the parameter is unnamed.
supplied := "(" ( " " binding ( ", " binding )* " " )? ")"
binding := Value ( " ~ " Identifier )?

Value := unit | literal | numeric | list | tuple | tablet

unit := "()"

; A string literal — the form a chosen response or any text value records as.
; Backslash escapes keep a value on a single record line: \" for a quote, \\
; for a backslash, and \n / \r for the line breaks of a multi-line value.
literal := "\"" literal_char* "\""
literal_char := [^"\\] | "\\" ("\"" | "\\" | "n" | "r")

; An integer or a Quantity, written exactly as the Technique language number
; literal it came from (integral and Quantity are defined in technique.bnf).
numeric := integral | Quantity

; An inline, comma-separated list of values. The empty list is "[]".
list := "[]" | "[ " Value ( ", " Value )* " ]"

; An inline, comma-separated tuple of values.
tuple := "( " Value ( ", " Value )* " )"

; A tablet: a series of "label" = value pairs, matching the Technique language
; (the label is quoted). The empty tablet is "[=]", which distinguishes it from
; the empty list. A bracketed value is a tablet when it carries a top-level
; " = " and a list otherwise. Tablets, lists, and their values nest arbitrarily.
tablet := "[=]" | "[ " pair ( ", " pair )* " ]"
pair := "\"" literal_char* "\"" " = " Value
2 changes: 1 addition & 1 deletion technique.bnf
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ Invocation := "<" invocation_target ">" ("(" arguments? ")")?

invocation_target := local_target | external_target
local_target := Identifier
external_target := "https://" [a-zA-Z0-9.,?&#%=:/-_]+
external_target := ("https" | "http" | "file") ":" [a-zA-Z0-9.,?&#%=:/-_]+

; A function call, usually to a built-in.
Application := function_name "(" arguments? ")"
Expand Down