From bb007682591a1b02186f3a11af682c6eef4cbd35 Mon Sep 17 00:00:00 2001 From: Andrew Cowie Date: Wed, 20 May 2026 13:22:02 +1000 Subject: [PATCH 01/10] Initial definition of PFFTT format --- pfftt.bnf | 110 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 110 insertions(+) create mode 100644 pfftt.bnf diff --git a/pfftt.bnf b/pfftt.bnf new file mode 100644 index 0000000..3b80e8c --- /dev/null +++ b/pfftt.bnf @@ -0,0 +1,110 @@ +; 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 +; abstract syntax tree 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 + 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.,?&#%=:/+-~_]+ + +Path := + absolute + relative + +absolute := "/" + +relative := procedure? component ( "/" component )* + +component := section | step | substep | subsubstep | attribute | invocation | execution + +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 | "^*" + +invocation := procedure | uri +procedure := Identifier ":" + +execution := Identifier "()" + +; Activity verbs and payloads, collectively the event being observed. Done is +; the most important, recording an outcome of a step. + +State := + "Start" SPACE uri run_id | + "Pause" | + "Resume" SPACE run_id | + "Done" SPACE Value | + "Skip" | + "Fail" (SPACE Value)? + +run_id := ":" [0-9]+ + +Value := unit | tablet + +unit := "()" + +; The Tablet data structure in Technique can nest arbitrarily but this runs +; to end of line so any content here is acceptable. + +tablet := "[" ANY "]" From 72e58868322f1e4ffa0d3ea7256d006e6e24a715 Mon Sep 17 00:00:00 2001 From: Andrew Cowie Date: Wed, 20 May 2026 21:18:57 +1000 Subject: [PATCH 02/10] Include RunId on all lines --- pfftt.bnf | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/pfftt.bnf b/pfftt.bnf index 3b80e8c..38a6e70 100644 --- a/pfftt.bnf +++ b/pfftt.bnf @@ -9,7 +9,7 @@ ; Otherwise special characters in regular expressions are not shown escaped. ; ; The convention adopted here is that names that represent actual types in the -; abstract syntax tree are in Proper Case whereas other definitions (often +; parser are in Proper Case whereas other definitions (often ; representing variants in enumerations in the implementation) are written in ; snake_case. @@ -29,6 +29,8 @@ File := Record* Record := Timestamp SPACE + RunId + SPACE Path SPACE State @@ -91,14 +93,14 @@ execution := Identifier "()" ; the most important, recording an outcome of a step. State := - "Start" SPACE uri run_id | + "Start" SPACE uri | "Pause" | - "Resume" SPACE run_id | + "Resume" | "Done" SPACE Value | "Skip" | "Fail" (SPACE Value)? -run_id := ":" [0-9]+ +RunId := [0-9]+ Value := unit | tablet From 8637f93e938c6bf3e226cf9db3372b899de75725 Mon Sep 17 00:00:00 2001 From: Andrew Cowie Date: Wed, 20 May 2026 21:19:28 +1000 Subject: [PATCH 03/10] Refine fully qualifed path notation --- pfftt.bnf | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/pfftt.bnf b/pfftt.bnf index 38a6e70..f848a30 100644 --- a/pfftt.bnf +++ b/pfftt.bnf @@ -56,11 +56,19 @@ Identifier := [a-z][a-z0-9_]* uri := ("https://" | "file:///") [a-zA-Z0-9.,?&#%=:/+-~_]+ -Path := - absolute - relative - -absolute := "/" +; 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 )* )? relative := procedure? component ( "/" component )* From aa9a812fa9f3474bec5b1a333b296c37e41926e0 Mon Sep 17 00:00:00 2001 From: Andrew Cowie Date: Wed, 20 May 2026 21:19:49 +1000 Subject: [PATCH 04/10] Add records for invocation and execution --- pfftt.bnf | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/pfftt.bnf b/pfftt.bnf index f848a30..d6838c7 100644 --- a/pfftt.bnf +++ b/pfftt.bnf @@ -70,9 +70,9 @@ uri := ("https://" | "file:///") [a-zA-Z0-9.,?&#%=:/+-~_]+ Path := "/" procedure? ( component ( "/" component )* )? -relative := procedure? component ( "/" component )* +procedure := Identifier ":" -component := section | step | substep | subsubstep | attribute | invocation | execution +component := section | step | substep | subsubstep | attribute section := [IVX]+ @@ -92,24 +92,28 @@ attribute := role_attribute | place_attribute role_attribute := "@" Identifier | "@*" place_attribute := "^" Identifier | "^*" -invocation := procedure | uri -procedure := Identifier ":" - -execution := Identifier "()" - ; Activity verbs and payloads, collectively the event being observed. Done is -; the most important, recording an outcome of a step. +; the most important, recording an outcome of a step. 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 | "Pause" | "Resume" | + "Invoke" SPACE invocable | + "Execute" SPACE executable | "Done" SPACE Value | "Skip" | "Fail" (SPACE Value)? RunId := [0-9]+ +invocable := procedure | uri + +executable := Identifier "()" + Value := unit | tablet unit := "()" From 4e29a5be64da5d715c733721eda658120f3f35a7 Mon Sep 17 00:00:00 2001 From: Andrew Cowie Date: Wed, 20 May 2026 21:43:28 +1000 Subject: [PATCH 05/10] Record beginning time of steps --- pfftt.bnf | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/pfftt.bnf b/pfftt.bnf index d6838c7..3a01edf 100644 --- a/pfftt.bnf +++ b/pfftt.bnf @@ -93,10 +93,12 @@ 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. 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. +; 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 | @@ -104,6 +106,7 @@ State := "Resume" | "Invoke" SPACE invocable | "Execute" SPACE executable | + "Begin" | "Done" SPACE Value | "Skip" | "Fail" (SPACE Value)? From c9e86aeecda671376d5bfe9ad6eba929d09b3d57 Mon Sep 17 00:00:00 2001 From: Andrew Cowie Date: Sat, 20 Jun 2026 18:06:52 +1000 Subject: [PATCH 06/10] Document Input state line --- pfftt.bnf | 33 +++++++++++++++++++++++++++++---- 1 file changed, 29 insertions(+), 4 deletions(-) diff --git a/pfftt.bnf b/pfftt.bnf index 3a01edf..b99443b 100644 --- a/pfftt.bnf +++ b/pfftt.bnf @@ -106,6 +106,7 @@ State := "Resume" | "Invoke" SPACE invocable | "Execute" SPACE executable | + "Input" SPACE supplied | "Begin" | "Done" SPACE Value | "Skip" | @@ -117,11 +118,35 @@ invocable := procedure | uri executable := Identifier "()" -Value := unit | tablet +; 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 := "()" -; The Tablet data structure in Technique can nest arbitrarily but this runs -; to end of line so any content here is acceptable. +; 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 )* " )" -tablet := "[" ANY "]" +; 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 From 42627b8481b1223ec62bbb7e2eea15bd0f4b9039 Mon Sep 17 00:00:00 2001 From: Andrew Cowie Date: Sat, 20 Jun 2026 21:48:56 +1000 Subject: [PATCH 07/10] Fix state name --- pfftt.bnf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pfftt.bnf b/pfftt.bnf index b99443b..651bdee 100644 --- a/pfftt.bnf +++ b/pfftt.bnf @@ -102,7 +102,7 @@ place_attribute := "^" Identifier | "^*" State := "Start" SPACE uri | - "Pause" | + "Stop" | "Resume" | "Invoke" SPACE invocable | "Execute" SPACE executable | From df51d3ff56140cc292dbfb5a7ad044b037894395 Mon Sep 17 00:00:00 2001 From: Andrew Cowie Date: Sun, 21 Jun 2026 23:26:05 +1000 Subject: [PATCH 08/10] Add Return state --- pfftt.bnf | 1 + 1 file changed, 1 insertion(+) diff --git a/pfftt.bnf b/pfftt.bnf index 651bdee..a9a2cde 100644 --- a/pfftt.bnf +++ b/pfftt.bnf @@ -106,6 +106,7 @@ State := "Resume" | "Invoke" SPACE invocable | "Execute" SPACE executable | + "Return" SPACE Value | "Input" SPACE supplied | "Begin" | "Done" SPACE Value | From b90cfa93f357e5fff0a3a2c73766c685db3c567a Mon Sep 17 00:00:00 2001 From: Andrew Cowie Date: Wed, 24 Jun 2026 08:39:46 +1000 Subject: [PATCH 09/10] Add Finish state --- pfftt.bnf | 1 + 1 file changed, 1 insertion(+) diff --git a/pfftt.bnf b/pfftt.bnf index a9a2cde..a349ccf 100644 --- a/pfftt.bnf +++ b/pfftt.bnf @@ -104,6 +104,7 @@ State := "Start" SPACE uri | "Stop" | "Resume" | + "Finish" | "Invoke" SPACE invocable | "Execute" SPACE executable | "Return" SPACE Value | From 414773f645c843a7f8043d5ca239d5f8f1ea54a9 Mon Sep 17 00:00:00 2001 From: Andrew Cowie Date: Wed, 24 Jun 2026 12:28:33 +1000 Subject: [PATCH 10/10] Admit file:// URLs --- technique.bnf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/technique.bnf b/technique.bnf index da95e4f..133f7f0 100644 --- a/technique.bnf +++ b/technique.bnf @@ -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? ")"