-
Notifications
You must be signed in to change notification settings - Fork 82
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add structured annotations to P4 grammar. Issue #789 #796
Add structured annotations to P4 grammar. Issue #789 #796
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks good.
I have a few questions:
Probably some of these questions have multiple reasonable answers, but they should probably all be answered before integrating this into the spec. |
@stefanheule In response to your question: "It appears that string literals are allowed, but integer expressions as long as they evaluate to a constant at compile time. Why the discrepancy?" Is your question "Why aren't expressions whose results is a string allowed, as well as expressions whose result is an integer?" If so, I believe one answer would be: "P4 has no expressions whose result is a string, except string literals". i.e. no string concatenation operations, substrings, etc. So one way to think of it is that as far as P4_16 is defined now, it does allow arbitrary expressions whose result is a string, but those currently always look like string literals. |
Makes sense, I didn't think about that. I would prefer a phrasing that treats all constants the same, even if right now there is no functional difference. But obviously this is a very minor point. |
It does seem reasonable to say that there could be arbitrary expressions that at compile time can be evaluated, and result in one of the acceptable types, e.g. if boolean is added to the list, then the result of the expression could be any value of type string, int, or boolean. |
@stefanheule @jafingerhut Thanks for the comments, I agree any allowable types should require the same requirement for compile-time evaluation. |
@stefanheule regarding integer precision, I'll copy here what I posted to the p4-api mailing list
|
@stefanheule Thanks for the insightful comments and questions.
Agreed, all types should be evaluate to compile-time constants and I should update the wording (but bear in mind P4 treats strings very simply at this point in time).
As @antoninbas said, the language should allow infinite-precision but P4Runtime or any other consumer may impose restrictions e.g. 64-bit.
That seems to be the popular consensus, I'll revise accordingly
I was trying to keep it simple for the language and grammar. I'll leave this as-is and see how it goes in the LDWG with the other changes/clarifications. I'm not sure many use-cases need free mixing of the kv's and expressions, but let's see what others think. One of the suggestions in the API WG was to keep it simple and sufficient for known use-cases.
Should be an error, I'll clarify that. |
…ir duplicates, etc.
We proposed removing from the spec the request for annotations to be merged. |
During today's discussion, there was a question of whether it's useful to disambiguate empty lists, empty kv-lists, and empty unstructured annotations for annotation consumers. |
Another thing that was suggested was to allow P4 lists as a value in addition to int, bool and string. |
- 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.
- 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
Right now the spec says
It is not clear what kind of nested expressions are allowed, and it is also not clear if nested expressions can themselves be nested. Is Another question I had was if there is any kind of type checking? Can list elements be of different types? |
@stefanheule Please see answers to your questions below. Do you still feel the spec requires clarification?
This is actually specified quite precisely in the grammar portion of the spec. An expression can be of the form {expression, expression..} i.e. a nested expression.
Yes! (I added an example to p4lang/p4runtime#265 which prompted this discussion.)
Not according to the grammar for an expression. This looks more like an assignment statement.
According to the grammar, each element in an expression list can be a different type. Bear in mind P4Runtime will impose its own constraints on Structured Annotations and it is a policy to not specify those constraints in the P4 language spec itself. So you could write something in "legal p4-16" which would throw an error in the P4Info generator (generating P4Info is a |
The spec does not say what is and is not a compile-time constant, this needs to explicitly defined in my opinion. Compile-time constant probably makes sense for base types like int, but it less clear for nested types. Can we just explicitly list and say what is allowed? To give a few examples of why this is necessary:
I don't think this is a great idea. If we want to restrict what is and isn't valid, lets be clear about that and put it in the spec. There can be exceptions, of course, like requiring ints to fit in a certain bit-width, but we should not have a completely different set of expressions be valid in P4 and P4Info. What's the advantage of allowing nested kvPairs in the spec but not P4Info? Isn't P4Info the main use-case for this? Finally, a last question: Are we going to be able to implement this spec easily in the compiler? Does the compiler have code to constant-fold nested expressions? |
Here is the relevant section of the specification. Happy to see it improved if you see things that are missing or confusing. |
Ah, thank you Nate, I missed that. That answers most of my concerns then, but maybe it needs to be improved a bit. Is And maybe Chris can comment on why there is a discrepancy in the allowed expressions in P4 vs P4Info if there still is any (other than max bit width). |
@stefanheule Regarding your comment:
Your objection to having the language spec allow more complexity of expressions than P4Runtime is understandable. In fact, at one time I'd added content to p4-16 spec which was more specifically-tailored to P4Info on an earlier version of structured annotations: a special case of kv-pairs inside
It's a convenience that structured annotations are capitalizing on existing grammar for expressions, and thereby also benefits from the implementation which parses, checks and reduces expressions. This doesn't mean we have to support every permutation for P4Info. There was a sentiment expressed in some earlier P4-API WG meetings to start out with simple support of structured annotations for known use-cases. There was concern that making it too complex would only delay implementation and multiply the work enormously (imagine all the test-cases we'd have to create). Since nobody made a case for arbitrarily-nested kv-lists of kv-lists of expression-lists (a contrived example), those cases aren't supported. We just stuck with something simple and immediately useful. |
To me that sentiment extends to the P4 spec as well, though. Otherwise, if you take the P4Info doesn't have to support everything that P4 supports to the extreme, then there is no need for a new kind of annotations at all, and you can just use the new unconstrained annotations, but have P4Info only support what further parses into whatever format we want to support. If we want to disallow nested kv-lists (which seems like a reasonable idea), then we should say so in the P4 spec. If we want to allow it, we should allow it in P4Info, too. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Other than my small suggestions looks great, thank you.
@liujed Regarding #796 (comment) and the following text in the PR:
The P4-API WG is proposing we remove this statement from the spec. The current PR p4lang/p4c#2227 doesn't really do this (empy anno body results in empty kvLists and expressionLists in the IR) and P4Info would be burdened with generating an empty expressionList to remain consistent with spec clause above. Any objections/concerns from a language/grammar point of view? |
This seems fine to me. I can't immediately think of any cases where it's worth distinguishing between the two kinds of empty lists. |
What happens if we have something like:
This appears permitted by the spec, since it's not explicitly forbidden. Seems odd to permit this, while forbidding multiple structured annotations with the same name. |
The spec and the implementation do not make this clear. |
@mbudiu-vmw I'm not sure what isn't clear; here is the spec text:
|
Regarding #796 (comment) I made a mistake reading it.
This is legal because the two annotations are distinct types of annotations. @liujed wrote:
There was a lot of discussion in the LDWG about what to do if we allowed duplicate uses of a structured annotation - do you merge the newer (parsed contents thereof) with the older, throw an error, or replace? We decided to disallow duplication as the simplest solution. |
I remember that discussion. But I don't think it touched on whether it made sense to mix structured and unstructured instances of an annotation. Naïvely, I'd expect an annotation to be structured or unstructured; having both seems to be a programmer error. Absent any |
@liujed-intel thanks for the comments. @mbudiu-vmw Can you comment on #796 (comment)? I'm OK with disallowing using the same name for unstructured and structured annotations. How does the implementation deal with this, or does it? |
I implemented both versions at some point. Currently we only reject structured duplicates. |
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.
…d another example to demonstrate illegal reuse of name in both structured and unstructured annotation.
I pushed commits to hopefully resolve the above conversations, thanks for all the detailed reviews and feedback. @liujed please review, @mbudiu-vmw this will require a change to |
p4-16/spec/P4-16-spec.mdk
Outdated
; | ||
|
||
kvPair | ||
: name '=' expressionList |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This could probably be just name = expression
Because expression can be a list expression, which is { expressionList }
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree, this should definitely be expression. We don't actually allow a list in this position.
@@ -7078,17 +7084,18 @@ annotations | |||
annotation | |||
: '@' name | |||
| '@' name '(' annotationBody ')' | |||
| '@' name '[' structuredAnnotationBody ']' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Perhaps you can use the grammar from the compiler implementation ; it essentially inlines the structuredAnnotationBody in this rule.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If this suggestion is taken, be sure to patch up those places where the text refers to structuredAnnotationBody
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is the advantage of inlining here? I think I like that we have a name for structured annotation bodies.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The spec grammar is almost identical to the bison grammar, because then we know it works. If we deviate it may actually not be implementable. Bison is very peculiar.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We seem to have lost the text that specified that a program element can't have multiple structured annotations with the same name.
p4-16/spec/P4-16-spec.mdk
Outdated
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. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This sounds like it might forbid the following, but it's not clear whether that is the intent. We should clarify and ensure that the implementation matches.
@my_anno(1) table T { ... }
@my_anno[2] table U { ... }
@liujed-intel re: #796 (comment) thanks for pointing this out, it is an ambiguity. The spec should read: This is legal:
This is illegal:
Does this make sense? |
@liujed-intel re:
I propose to add the following paragraph: Multiple unstructured annotations using the same |
@mbudiu-vmw @stefanheule re: #796 (comment): The latest PR contains the following and has for awhile, unless I'm mistaken:
|
@mbudiu-vmw re: #796 (comment) I'm not confident interpreting this suggestion; this grammar has been in my PR for a while. Perhaps we can merge my PR and someone else can propose restating the grammar. |
Re: #796 (comment) Yes, makes total sense, and this was also my thinking. But now that the question is being raised, I wonder whether it makes sense to do the stricter thing instead. At least, that would seem to be more consistent with the restriction that you can't mix structured and unstructured for the same name on a single program element. If you consider all annotations with the same name as expressions of the same concept, then I'd expect consistency with structured vs. unstructured in their usage. Thoughts? |
@liujed-intel re: #796 (comment) I know what you mean, but I'd err on the side of letting the author write confusing code. It's no different than letting them apply the same unstructured annotation but imply a different meaning from place to place. Scoping ensures correct compilation but we can't always prevent people from writing bad code. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks fine. I'd let the question here simmer for a bit, in case there are other opinions out there.
I also share Mihai's concern about keeping the spec and implementation grammars in sync. I think it may be easier to just change the implementation grammar to match, rather than re-plumb the text in the spec.
No description provided.