From d0093c2d7c7a28507c3ff6c44a28e97e83481f64 Mon Sep 17 00:00:00 2001 From: Chris Sommers Date: Wed, 4 Dec 2019 10:14:54 -0800 Subject: [PATCH 01/10] Add structured annotations to P4 grammar. --- p4-16/spec/P4-16-spec.mdk | 95 +++++++++++++++++++++++++++++++++------ p4-16/spec/grammar.mdk | 11 +++++ 2 files changed, 93 insertions(+), 13 deletions(-) diff --git a/p4-16/spec/P4-16-spec.mdk b/p4-16/spec/P4-16-spec.mdk index a46995972f..8a2fe33523 100644 --- a/p4-16/spec/P4-16-spec.mdk +++ b/p4-16/spec/P4-16-spec.mdk @@ -7062,7 +7062,8 @@ Annotations are similar to C# attributes and Java annotations. They are a simple mechanism for extending the P4 language to some limited degree without changing the grammar. To some degree they subsume C `#pragma`s. Annotations are attached to types, fields, variables, etc. using the `@` -syntax (as shown explicitly in the P4 grammar), and have an optional body: +syntax (as shown explicitly in the P4 grammar). Unstructured annotations, +or just "annotations," have an optional body; structured annotations have a mandatory body. ~ Begin P4Grammar optAnnotations @@ -7078,17 +7079,18 @@ annotations annotation : '@' name | '@' name '(' annotationBody ')' + | '@' name '[' structuredAnnotationBody ']' ; ~ End P4Grammar -## Bodies of annotations +## Bodies of Unstructured Annotations -The flexibility of P4 annotations comes from the minimal structure mandated by -the P4 grammar: annotation bodies may contain any sequence of terminals, so -long as parentheses are balanced. In the following grammar fragment, the -`annotationToken` non-terminal represents any terminal produced by the lexer, -including keywords, identifiers, string and integer literals, and symbols, but -excluding parentheses. +The flexibility of P4 unstructured annotations comes from the minimal structure +mandated by the P4 grammar: unstructured annotation bodies may contain any +sequence of terminals, so long as parentheses are balanced. In the following +grammar fragment, the `annotationToken` non-terminal represents any terminal +produced by the lexer, including keywords, identifiers, string and integer +literals, and symbols, but excluding parentheses. ~ Begin P4Grammar annotationBody @@ -7097,16 +7099,83 @@ annotationBody | annotationBody annotationToken ~ End P4Grammar -Annotations may impose additional structure on their bodies, and are not -confined to the P4 language. For example, the P4Runtime specification defines a -`@pkginfo` annotation that takes key-value pairs, which are not found in the -main P4 language. +Unstructured annotations may impose additional structure on their bodies, and +are not confined to the P4 language. For example, the P4Runtime specification +defines a `@pkginfo` annotation that takes key-value pairs, which are not found +in the main P4 language. + +## Bodies of Structured Annotations +Structured annotations have a specific format and are used declare metadata, +consisting of expressions and key-value pairs. The `expression`s within the +`nonEmptyExpressionList`, as well as within the `kvList`, must be either string +literals, or evaluate at compile-time to integers. + +~ Begin P4Grammar +stucturedAnnotationBody + : nonEmptyExpressionList + | kvList + ; +... +nonEmptyExpressionList + : expression + | expressionList ',' expression + ; +... +kvList + : kvPair + | kvList ',' kvPair + ; + +kvPair + : name '=' expression + ; + +~ End P4Grammar + +For example, to assign two "labels" to a P4 table (which ostensibly could be +used to render a GUI): + +~ Begin P4Example +@Labels[short="Short Label", hover="My Longer Table Label to appear in hover-help"] +table t { + actions = { + a + } + ... +} +~ End P4Example + +Structured annotations use square brackets `[..]` instead of parentheses to +enclose the mandatory body. The body can consist of an expression list or a +key-value pair list. The different forms cannot be mixed in the same annotation. +You can have multiple, heterogenous annotations for an allowed P4 token; the +expressions and/or kv-pairs are cumulative and the body types can be freely +combined. + +~ Begin P4Example +@MyStructuredAnno[1,"hello"] +@MyStructuredAnno[10-8] +@MyStructuredAnno[k1=3*4,k2="apple"] +@MyStructuredAnno[k3=42] +@MyUnstructuredAnno(Some random content) +@MyUnstructuredAnno(Some more random content) +// table t effectively has: +// @MyStructuredAnno[1, 'hello', 2, k1=12, k2="apple"", k3=42] +// as well as two instances of @MyUnstructuredAnno() +table t { + actions = { + a + } + ... +} +~ End P4Example ## Predefined annotations Annotation names that start with lowercase letters are reserved for the standard library and architecture. This document pre-defines a -set of "standard" annotations in Appendix [#sec-p4-reserved-annotations]. We expect that this list will grow. +set of "standard" annotations in Appendix [#sec-p4-reserved-annotations]. +We expect that this list will grow. We encourage custom architectures to define annotations starting with a manufacturer prefix: e.g., an organization named X would use annotations named like `@X_annotation` diff --git a/p4-16/spec/grammar.mdk b/p4-16/spec/grammar.mdk index 3b4efed811..84ca895e1a 100644 --- a/p4-16/spec/grammar.mdk +++ b/p4-16/spec/grammar.mdk @@ -54,6 +54,7 @@ annotations annotation : '@' name | '@' name '(' annotationBody ')' + | '@' name '[' structuredAnnotationBody ']' ; parameterList @@ -595,11 +596,21 @@ expressionList | expressionList ',' expression ; +nonEmptyExpressionList + : expression + | expressionList ',' expression + ; + annotationBody : /* empty */ | annotationBody '(' annotationBody ')' | annotationBody annotationToken +stucturedAnnotationBody + : nonEmptyExpressionList + | kvList + ; + annotationToken : ABSTRACT | ACTION From 8725872261f25a2fb4708059262013a130f23eb3 Mon Sep 17 00:00:00 2001 From: Chris Sommers Date: Thu, 12 Dec 2019 20:04:41 -0800 Subject: [PATCH 02/10] Incorporate reviewer feedback: clarify unstructured data types, kv-pair duplicates, etc. --- p4-16/spec/P4-16-spec.mdk | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/p4-16/spec/P4-16-spec.mdk b/p4-16/spec/P4-16-spec.mdk index 8a2fe33523..15f60993dc 100644 --- a/p4-16/spec/P4-16-spec.mdk +++ b/p4-16/spec/P4-16-spec.mdk @@ -7107,8 +7107,11 @@ in the main P4 language. ## Bodies of Structured Annotations Structured annotations have a specific format and are used declare metadata, consisting of expressions and key-value pairs. The `expression`s within the -`nonEmptyExpressionList`, as well as within the `kvList`, must be either string -literals, or evaluate at compile-time to integers. +`nonEmptyExpressionList`, as well as within the `kvList`, must +evaluate at compile-time to string literals, infinite-precision integers, or booleans. + +Note that P4Runtime information (P4Info) may stipulate additional restrictions. For example, +an integer expression might be limited to 64-bit values. ~ Begin P4Grammar stucturedAnnotationBody @@ -7150,7 +7153,7 @@ enclose the mandatory body. The body can consist of an expression list or a key-value pair list. The different forms cannot be mixed in the same annotation. You can have multiple, heterogenous annotations for an allowed P4 token; the expressions and/or kv-pairs are cumulative and the body types can be freely -combined. +combined. It is an error to declare a duplicate key. ~ Begin P4Example @MyStructuredAnno[1,"hello"] From 6249bea5f223d3be65407d92116aa9ba9db0628b Mon Sep 17 00:00:00 2001 From: Chris Sommers Date: Sun, 29 Dec 2019 18:03:07 -0800 Subject: [PATCH 03/10] Revise Structured Annotations per LDWG meetings and github feedback: - No merging of multiple annotations - No mixing of kvPair and expressionLists - Allow empty expressionLists; empty body is disambiguated to empty list - kvPair value may be expressionList, including empty list - Cite illegal cases - Provide more exammples. --- p4-16/spec/P4-16-spec.mdk | 137 +++++++++++++++++++++++++++++--------- p4-16/spec/grammar.mdk | 8 +-- 2 files changed, 106 insertions(+), 39 deletions(-) diff --git a/p4-16/spec/P4-16-spec.mdk b/p4-16/spec/P4-16-spec.mdk index 15f60993dc..f90b40cc44 100644 --- a/p4-16/spec/P4-16-spec.mdk +++ b/p4-16/spec/P4-16-spec.mdk @@ -7105,22 +7105,37 @@ defines a `@pkginfo` annotation that takes key-value pairs, which are not found in the main P4 language. ## Bodies of Structured Annotations -Structured annotations have a specific format and are used declare metadata, -consisting of expressions and key-value pairs. The `expression`s within the -`nonEmptyExpressionList`, as well as within the `kvList`, must -evaluate at compile-time to string literals, infinite-precision integers, or booleans. -Note that P4Runtime information (P4Info) may stipulate additional restrictions. For example, -an integer expression might be limited to 64-bit values. +Unlike unstructured annotations, structured annotations use square brackets +`[...]` and have a specific format. They are commonly used to declare custom +metadata, consisting of expression lists or key-value lists but not both (except +that the value of a `kvPair` may itelf be an `expressionList`). An +`expressionList` may be empty or contain a comma-separated list of members. A +`kvList` consists of one or more `kvPair`s, each consisting of a key and a +value; the value is an `expressionList`. + +To avoid ambiguity, an empty `stucturedAnnotationBody` is by definition +considered to contain an empty `expressionList`. Furthermore, the value of a `kvPair` may +be the empty `expressionList`, in which case the pair is considered to +contain a key without a value. + +The `expression`s within an `expressionList` must evaluate at compile-time to +string literals, infinite-precision integers or booleans. Note that P4Runtime +information (P4Info) may stipulate additional restrictions. For example, an +integer expression might be limited to 64-bit values. + +It is illegal to duplicate a key within an annotation. It is illegal to use the +same annotation `name` on a given `annotationToken`. ~ Begin P4Grammar stucturedAnnotationBody - : nonEmptyExpressionList + : expressionList | kvList ; ... -nonEmptyExpressionList - : expression +expressionList + : /* empty */ + | expression | expressionList ',' expression ; ... @@ -7130,45 +7145,101 @@ kvList ; kvPair - : name '=' expression + : name '=' expressionList ; ~ End P4Grammar -For example, to assign two "labels" to a P4 table (which ostensibly could be -used to render a GUI): +### Structured Annotation Examples + +#### Empty Expression List + +The following example produces the empty `expressionList`. + +~ Begin P4Example +@Empty[] +table t { + ... +} +~ End P4Example + + +#### Mixed Expression List + +The following example will produce an effective expression list of +`[1,"hello",true, false, 11]` + +~ Begin P4Example +#define TEXT_CONST "hello" +#define NUM_CONST 6 +@MixedExprList[1,TEXT_CONST,true,1==2,5+NUM_CONST] +table t { + ... +} +~ End P4Example + +#### kvList of Strings ~ Begin P4Example @Labels[short="Short Label", hover="My Longer Table Label to appear in hover-help"] table t { - actions = { - a - } ... } ~ End P4Example -Structured annotations use square brackets `[..]` instead of parentheses to -enclose the mandatory body. The body can consist of an expression list or a -key-value pair list. The different forms cannot be mixed in the same annotation. -You can have multiple, heterogenous annotations for an allowed P4 token; the -expressions and/or kv-pairs are cumulative and the body types can be freely -combined. It is an error to declare a duplicate key. +#### kvList of Mixed Expressions + +The following example will produce a kvPair list as follows. Note one of the +`kvPair`s has a value which is an `expressionList`. + +``` +label=text, my_bool=true, expr_list=[1,"hello",true, false, 11], empty_key=, +int_val=6 +``` + +~ Begin P4Example +#define TEXT_CONST "hello" +#define NUM_CONST 6 +@MixedKV[label="text", my_bool=true, expr_list=1,TEXT_CONST,true,1==2,5+NUM_CONST,\ + empty_key=, int_val=2*3] +table t { + ... +} +~ End P4Example + +#### Illegal Mixing of `kvPair` and `expressionList` + +The following example is invalid because the body contains both a `kvPair` and +an `expression`: ~ Begin P4Example -@MyStructuredAnno[1,"hello"] -@MyStructuredAnno[10-8] -@MyStructuredAnno[k1=3*4,k2="apple"] -@MyStructuredAnno[k3=42] -@MyUnstructuredAnno(Some random content) -@MyUnstructuredAnno(Some more random content) -// table t effectively has: -// @MyStructuredAnno[1, 'hello', 2, k1=12, k2="apple"", k3=42] -// as well as two instances of @MyUnstructuredAnno() +@IllegalMixing[key=4, 5] // illegal mixing +table t { + ... +} +~ End P4Example + +#### Illegal Duplicate Key + +The following example is invalid because the same key occurs more than once: + +~ Begin P4Example +@DupKey[k1=4,k1=5] // illegal duplicate key +table t { + ... +} +~ End P4Example + + +#### Illegal Duplicate Annotation + +The following example is invalid because the annotation `name` occurs more +than once on the same token, e.g. `table t`: + +~ Begin P4Example +@DupAnno[k1=4] +@DupAnno[k2=5] // illegal duplicate name table t { - actions = { - a - } ... } ~ End P4Example diff --git a/p4-16/spec/grammar.mdk b/p4-16/spec/grammar.mdk index 84ca895e1a..a1d540ff53 100644 --- a/p4-16/spec/grammar.mdk +++ b/p4-16/spec/grammar.mdk @@ -587,7 +587,7 @@ kvList ; kvPair - : name '=' expression + : name '=' expressionList ; expressionList @@ -596,10 +596,6 @@ expressionList | expressionList ',' expression ; -nonEmptyExpressionList - : expression - | expressionList ',' expression - ; annotationBody : /* empty */ @@ -607,7 +603,7 @@ annotationBody | annotationBody annotationToken stucturedAnnotationBody - : nonEmptyExpressionList + : expressionList | kvList ; From 694a254d23b26c8fdd4a92fa2a760bd73f833d0e Mon Sep 17 00:00:00 2001 From: Chris Sommers Date: Tue, 7 Jan 2020 10:51:17 -0800 Subject: [PATCH 04/10] Updated per LDWG meetings and GitHub feedback: - kvPairs have a value type of expression instead of expressionList; note expression itself can contain lists inside {}. - No valueless keys - Clarified descriptions - Updated examples, removed section headings from them --- p4-16/spec/P4-16-spec.mdk | 72 +++++++++++++++++++-------------------- p4-16/spec/grammar.mdk | 2 +- 2 files changed, 36 insertions(+), 38 deletions(-) diff --git a/p4-16/spec/P4-16-spec.mdk b/p4-16/spec/P4-16-spec.mdk index f90b40cc44..7769797473 100644 --- a/p4-16/spec/P4-16-spec.mdk +++ b/p4-16/spec/P4-16-spec.mdk @@ -7058,12 +7058,13 @@ diagnostics. # Annotations { #sec-annotations } -Annotations are similar to C# attributes and Java annotations. They -are a simple mechanism for extending the P4 language to some limited -degree without changing the grammar. To some degree they subsume C `#pragma`s. -Annotations are attached to types, fields, variables, etc. using the `@` -syntax (as shown explicitly in the P4 grammar). Unstructured annotations, -or just "annotations," have an optional body; structured annotations have a mandatory body. +Annotations are similar to C# attributes and Java annotations. They are a simple +mechanism for extending the P4 language to some limited degree without changing +the grammar. To some degree they subsume C `#pragma`s. Annotations are attached +to types, fields, variables, etc. using the `@` syntax (as shown explicitly in +the P4 grammar). Unstructured annotations, or just "annotations," have an +optional body; structured annotations have a mandatory body, containing at least +a pair of square brackets `[]`. ~ Begin P4Grammar optAnnotations @@ -7107,22 +7108,21 @@ in the main P4 language. ## Bodies of Structured Annotations Unlike unstructured annotations, structured annotations use square brackets -`[...]` and have a specific format. They are commonly used to declare custom -metadata, consisting of expression lists or key-value lists but not both (except -that the value of a `kvPair` may itelf be an `expressionList`). An -`expressionList` may be empty or contain a comma-separated list of members. A -`kvList` consists of one or more `kvPair`s, each consisting of a key and a -value; the value is an `expressionList`. +`[...]` and have a restricted format. They are commonly used to declare custom +metadata, consisting of expression lists or key-value lists but not both. An +`expressionList` may be empty or contain a comma-separated list of member +`expression`s. A `kvList` consists of one or more `kvPair`s, each consisting of +a key and a value `expression`. Note the syntax for `expression` is rich, see +Appendix [#sec-grammar] for details. To avoid ambiguity, an empty `stucturedAnnotationBody` is by definition -considered to contain an empty `expressionList`. Furthermore, the value of a `kvPair` may -be the empty `expressionList`, in which case the pair is considered to -contain a key without a value. +considered to contain an empty `expressionList`. -The `expression`s within an `expressionList` must evaluate at compile-time to -string literals, infinite-precision integers or booleans. Note that P4Runtime -information (P4Info) may stipulate additional restrictions. For example, an -integer expression might be limited to 64-bit values. +All `expression`s (and nested expressions) within a `stucturedAnnotationBody` +must evaluate at compile-time to string literals, infinite-precision integers or +booleans. Note that P4Runtime information (P4Info) may stipulate additional +restrictions. For example, an integer expression might be limited to 64-bit +values. It is illegal to duplicate a key within an annotation. It is illegal to use the same annotation `name` on a given `annotationToken`. @@ -7145,14 +7145,14 @@ kvList ; kvPair - : name '=' expressionList + : name '=' expression ; ~ End P4Grammar ### Structured Annotation Examples -#### Empty Expression List +**Empty Expression List** The following example produces the empty `expressionList`. @@ -7164,10 +7164,12 @@ table t { ~ End P4Example -#### Mixed Expression List +**Mixed Expression List** -The following example will produce an effective expression list of -`[1,"hello",true, false, 11]` +The following example will produce an effective expression list as follows: +``` +[1,"hello",true, false, 11] +``` ~ Begin P4Example #define TEXT_CONST "hello" @@ -7178,7 +7180,7 @@ table t { } ~ End P4Example -#### kvList of Strings +**kvList of Strings** ~ Begin P4Example @Labels[short="Short Label", hover="My Longer Table Label to appear in hover-help"] @@ -7187,27 +7189,23 @@ table t { } ~ End P4Example -#### kvList of Mixed Expressions +**kvList of Mixed Expressions** -The following example will produce a kvPair list as follows. Note one of the -`kvPair`s has a value which is an `expressionList`. +The following example will produce an effective kvList as follows. Note one of +the `kvPair`s has a value which is an `{expressionList}`. ``` -label=text, my_bool=true, expr_list=[1,"hello",true, false, 11], empty_key=, -int_val=6 +[label="text", my_bool=true, list_key={"a", 11, false}, int_val=6] ``` ~ Begin P4Example -#define TEXT_CONST "hello" -#define NUM_CONST 6 -@MixedKV[label="text", my_bool=true, expr_list=1,TEXT_CONST,true,1==2,5+NUM_CONST,\ - empty_key=, int_val=2*3] +@MixedKV[label="text", my_bool=true, list_key={"a", 5+6, 1==2}, int_val=2*3] table t { ... } ~ End P4Example -#### Illegal Mixing of `kvPair` and `expressionList` +**Illegal Mixing of `kvPair` and `expressionList`** The following example is invalid because the body contains both a `kvPair` and an `expression`: @@ -7219,7 +7217,7 @@ table t { } ~ End P4Example -#### Illegal Duplicate Key +**Illegal Duplicate Key** The following example is invalid because the same key occurs more than once: @@ -7231,7 +7229,7 @@ table t { ~ End P4Example -#### Illegal Duplicate Annotation +**Illegal Duplicate Annotation** The following example is invalid because the annotation `name` occurs more than once on the same token, e.g. `table t`: diff --git a/p4-16/spec/grammar.mdk b/p4-16/spec/grammar.mdk index a1d540ff53..24ed379413 100644 --- a/p4-16/spec/grammar.mdk +++ b/p4-16/spec/grammar.mdk @@ -587,7 +587,7 @@ kvList ; kvPair - : name '=' expressionList + : name '=' expression ; expressionList From 38a60a6e0d3704c4918ac803f21845ac3cde1d08 Mon Sep 17 00:00:00 2001 From: Chris Sommers Date: Sun, 1 Mar 2020 12:40:55 -0800 Subject: [PATCH 05/10] Simplify expressions within StructureAnnotations to base types (no nesting). --- p4-16/spec/P4-16-spec.mdk | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/p4-16/spec/P4-16-spec.mdk b/p4-16/spec/P4-16-spec.mdk index 7769797473..fda070e08b 100644 --- a/p4-16/spec/P4-16-spec.mdk +++ b/p4-16/spec/P4-16-spec.mdk @@ -7118,9 +7118,11 @@ Appendix [#sec-grammar] for details. To avoid ambiguity, an empty `stucturedAnnotationBody` is by definition considered to contain an empty `expressionList`. -All `expression`s (and nested expressions) within a `stucturedAnnotationBody` -must evaluate at compile-time to string literals, infinite-precision integers or -booleans. Note that P4Runtime information (P4Info) may stipulate additional +All `expression`s within a `stucturedAnnotationBody` must evaluate at +compile-time to one of the following base types: string literals, +infinite-precision integers or booleans. Nested `expression`s (e.g. an +`expression` containing an `expressionList`, a `kvList`, etc.) are not +allowed. Note that P4Runtime information (`P4Info`) may stipulate additional restrictions. For example, an integer expression might be limited to 64-bit values. @@ -7191,15 +7193,14 @@ table t { **kvList of Mixed Expressions** -The following example will produce an effective kvList as follows. Note one of -the `kvPair`s has a value which is an `{expressionList}`. +The following example will produce an effective kvList as follows. ``` -[label="text", my_bool=true, list_key={"a", 11, false}, int_val=6] +[label="text", my_bool=true, int_val=6] ``` ~ Begin P4Example -@MixedKV[label="text", my_bool=true, list_key={"a", 5+6, 1==2}, int_val=2*3] +@MixedKV[label="text", my_bool=true, int_val=2*3] table t { ... } From 49cd5d70931df97cebefff8ac1773a5115803135 Mon Sep 17 00:00:00 2001 From: Chris Sommers Date: Mon, 2 Mar 2020 10:20:48 -0800 Subject: [PATCH 06/10] Clarified language on Structured Annotations per reviewer feedback. --- p4-16/spec/P4-16-spec.mdk | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/p4-16/spec/P4-16-spec.mdk b/p4-16/spec/P4-16-spec.mdk index fda070e08b..28b753d66b 100644 --- a/p4-16/spec/P4-16-spec.mdk +++ b/p4-16/spec/P4-16-spec.mdk @@ -7118,16 +7118,18 @@ Appendix [#sec-grammar] for details. To avoid ambiguity, an empty `stucturedAnnotationBody` is by definition considered to contain an empty `expressionList`. -All `expression`s within a `stucturedAnnotationBody` must evaluate at -compile-time to one of the following base types: string literals, -infinite-precision integers or booleans. Nested `expression`s (e.g. an +All `expression`s within a `stucturedAnnotationBody` must be compile-time +known values, either literals or expressions requiring compile-time +evaluation, with a result type that is one of: string literals, +infinite-precision integer, or boolean. Nested `expression`s (e.g. an `expression` containing an `expressionList`, a `kvList`, etc.) are not allowed. Note that P4Runtime information (`P4Info`) may stipulate additional restrictions. For example, an integer expression might be limited to 64-bit values. -It is illegal to duplicate a key within an annotation. It is illegal to use the -same annotation `name` on a given `annotationToken`. +It is illegal to duplicate a `key` within the `kvList` of a structured +annotation. It is illegal to use the same annotation `name` on a given +`annotationToken` for structured annotations. ~ Begin P4Grammar stucturedAnnotationBody From 8efc24704bdd91ef5fb90c6a4c3893e2f418ecf9 Mon Sep 17 00:00:00 2001 From: Chris Sommers Date: Mon, 2 Mar 2020 11:21:46 -0800 Subject: [PATCH 07/10] Typos s/stucture/structure/ --- p4-16/spec/P4-16-spec.mdk | 6 +++--- p4-16/spec/grammar.mdk | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/p4-16/spec/P4-16-spec.mdk b/p4-16/spec/P4-16-spec.mdk index 28b753d66b..296fdaecd1 100644 --- a/p4-16/spec/P4-16-spec.mdk +++ b/p4-16/spec/P4-16-spec.mdk @@ -7115,10 +7115,10 @@ metadata, consisting of expression lists or key-value lists but not both. An a key and a value `expression`. Note the syntax for `expression` is rich, see Appendix [#sec-grammar] for details. -To avoid ambiguity, an empty `stucturedAnnotationBody` is by definition +To avoid ambiguity, an empty `structuredAnnotationBody` is by definition considered to contain an empty `expressionList`. -All `expression`s within a `stucturedAnnotationBody` must be compile-time +All `expression`s within a `structuredAnnotationBody` must be compile-time known values, either literals or expressions requiring compile-time evaluation, with a result type that is one of: string literals, infinite-precision integer, or boolean. Nested `expression`s (e.g. an @@ -7132,7 +7132,7 @@ annotation. It is illegal to use the same annotation `name` on a given `annotationToken` for structured annotations. ~ Begin P4Grammar -stucturedAnnotationBody +structuredAnnotationBody : expressionList | kvList ; diff --git a/p4-16/spec/grammar.mdk b/p4-16/spec/grammar.mdk index 24ed379413..1789eedb38 100644 --- a/p4-16/spec/grammar.mdk +++ b/p4-16/spec/grammar.mdk @@ -602,7 +602,7 @@ annotationBody | annotationBody '(' annotationBody ')' | annotationBody annotationToken -stucturedAnnotationBody +structuredAnnotationBody : expressionList | kvList ; From 206f73e857e458ee34b07e271fbbc8c9cd72f1ae Mon Sep 17 00:00:00 2001 From: Chris Sommers Date: Wed, 25 Mar 2020 14:49:21 -0700 Subject: [PATCH 08/10] Unstructured and structured annotations may not use the same name; this is more restrictive than previous but deemed better. Empty structured annotations are not disambiguated to be empty expressionbLists, it seemed unnecessary. Clarified some other language around structured annotations. --- p4-16/spec/P4-16-spec.mdk | 28 +++++++++++++--------------- 1 file changed, 13 insertions(+), 15 deletions(-) diff --git a/p4-16/spec/P4-16-spec.mdk b/p4-16/spec/P4-16-spec.mdk index 296fdaecd1..5e19505dd0 100644 --- a/p4-16/spec/P4-16-spec.mdk +++ b/p4-16/spec/P4-16-spec.mdk @@ -7066,6 +7066,10 @@ the P4 grammar). Unstructured annotations, or just "annotations," have an optional body; structured annotations have a mandatory body, containing at least a pair of square brackets `[]`. +Structured annotations and unstructured annotations must not use the same +`name`. Thus, a given `name` can only be applied to one type of annotation or +the other. + ~ Begin P4Grammar optAnnotations : /* empty */ @@ -7102,8 +7106,7 @@ annotationBody Unstructured annotations may impose additional structure on their bodies, and are not confined to the P4 language. For example, the P4Runtime specification -defines a `@pkginfo` annotation that takes key-value pairs, which are not found -in the main P4 language. +defines a `@pkginfo` annotation that expects key-value pairs. ## Bodies of Structured Annotations @@ -7115,21 +7118,16 @@ metadata, consisting of expression lists or key-value lists but not both. An a key and a value `expression`. Note the syntax for `expression` is rich, see Appendix [#sec-grammar] for details. -To avoid ambiguity, an empty `structuredAnnotationBody` is by definition -considered to contain an empty `expressionList`. - -All `expression`s within a `structuredAnnotationBody` must be compile-time -known values, either literals or expressions requiring compile-time -evaluation, with a result type that is one of: string literals, -infinite-precision integer, or boolean. Nested `expression`s (e.g. an -`expression` containing an `expressionList`, a `kvList`, etc.) are not -allowed. Note that P4Runtime information (`P4Info`) may stipulate additional -restrictions. For example, an integer expression might be limited to 64-bit -values. +All `expression`s within a `structuredAnnotationBody` must be compile-time known +values, either literals or expressions requiring compile-time evaluation, with a +result type that is one of: string literals, infinite-precision integer, or +boolean. Structured `expression`s (e.g. an `expression` containing an +`expressionList`, a `kvList`, etc.) are not allowed. Note that P4Runtime +information (P4Info) may stipulate additional restrictions. For example, an +integer expression might be limited to 64-bit values. It is illegal to duplicate a `key` within the `kvList` of a structured -annotation. It is illegal to use the same annotation `name` on a given -`annotationToken` for structured annotations. +annotation. ~ Begin P4Grammar structuredAnnotationBody From 797491bbb11021972357ab684e53985a12a0d572 Mon Sep 17 00:00:00 2001 From: Chris Sommers Date: Wed, 25 Mar 2020 15:14:57 -0700 Subject: [PATCH 09/10] Fixed @Empty example - does not produce an empty expressionList. Added another example to demonstrate illegal reuse of name in both structured and unstructured annotation. --- p4-16/spec/P4-16-spec.mdk | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/p4-16/spec/P4-16-spec.mdk b/p4-16/spec/P4-16-spec.mdk index 5e19505dd0..2c628bc43c 100644 --- a/p4-16/spec/P4-16-spec.mdk +++ b/p4-16/spec/P4-16-spec.mdk @@ -7156,7 +7156,7 @@ kvPair **Empty Expression List** -The following example produces the empty `expressionList`. +The following example produces an empty annotation: ~ Begin P4Example @Empty[] @@ -7230,10 +7230,10 @@ table t { ~ End P4Example -**Illegal Duplicate Annotation** +**Illegal Duplicate Structured Annotation** The following example is invalid because the annotation `name` occurs more -than once on the same token, e.g. `table t`: +than once on the same element, e.g. `table t`: ~ Begin P4Example @DupAnno[k1=4] @@ -7243,6 +7243,19 @@ table t { } ~ End P4Example +**Illegal Simultaneous Use of Both Structured and Unstructured Annotation** + +The following example is invalid because the annotation `name` is used by both +an unstructured and structured annotation on the same element `table t`: + +~ Begin P4Example +@MixAnno("Anything") +@MixAnno[k2=5] // illegal use in both annotation types +table t { + ... +} +~ End P4Example + ## Predefined annotations Annotation names that start with lowercase letters are reserved for From f2ea5b5161eccadc68b32f4850b53cf5296a2f65 Mon Sep 17 00:00:00 2001 From: Chris Sommers Date: Thu, 26 Mar 2020 16:06:44 -0700 Subject: [PATCH 10/10] Clarifications and more examples of annotations. --- p4-16/spec/P4-16-spec.mdk | 42 +++++++++++++++++++++++++++++++++++---- 1 file changed, 38 insertions(+), 4 deletions(-) diff --git a/p4-16/spec/P4-16-spec.mdk b/p4-16/spec/P4-16-spec.mdk index 2c628bc43c..51c1d02d3c 100644 --- a/p4-16/spec/P4-16-spec.mdk +++ b/p4-16/spec/P4-16-spec.mdk @@ -7066,10 +7066,6 @@ the P4 grammar). Unstructured annotations, or just "annotations," have an optional body; structured annotations have a mandatory body, containing at least a pair of square brackets `[]`. -Structured annotations and unstructured annotations must not use the same -`name`. Thus, a given `name` can only be applied to one type of annotation or -the other. - ~ Begin P4Grammar optAnnotations : /* empty */ @@ -7088,6 +7084,44 @@ annotation ; ~ End P4Grammar +Structured annotations and unstructured annotations on any one element must not +use the same `name`. Thus, a given `name` can only be applied to one type of +annotation or the other for any one element. An annotation used on one element +does not affect the annotation on another because they have different scope. + +This is legal: + +~ Begin P4Example +@my_anno(1) table T { ... } +@my_anno[2] table U { ... } // OK - different scope than previous use of my_anno +~ End P4Example + +This is illegal: + +~ Begin P4Example +@my_anno(1) +@my_anno[2] table U { ... } // Error - changed type of anno on an element +~ End P4Example + +Multiple unstructured annotations using the same `name` can appear on a given +element; they are cumulative. Each one will be bound to that element. In +contrast, only one structured annotation using a given `name` may appear on an +element; multiple uses of the same `name` will produce an error. + +This is legal: + +~ Begin P4Example +@my_anno(1) +@my_anno(2) table U { ... } // OK - unstructured annos accumulate +~ End P4Example + +This is illegal: + +~ Begin P4Example +@my_anno[1] +@my_anno[2] table U { ... } // Error - reused the same structured anno on an element +~ End P4Example + ## Bodies of Unstructured Annotations The flexibility of P4 unstructured annotations comes from the minimal structure