Added support for free-form annotations (#1614)
This adds support for free-form annotations, wherein annotation bodies may be any sequence of tokens containing balanced parentheses. At the same time, this introduces annotation checking, to ensure predefined annotations are used correctly. Backwards compatibility with P4₁₄-style pragmas is also added as an experimental feature.
On the initial parsing pass, annotation bodies are parsed as a sequence of tokens in a new field, `Annotation::body`. After the initial parse, `Annotation::expr` and `Annotation::kv` are empty. P4₁₄-style pragmas are translated by the parser into P4₁₆ annotations: `@pragma name body` is translated into `@name(body)`.
Early in the front end, a rewriting pass parses the bodies of spec-defined annotations, converting them into an expression list (which populates `Annotation::expr`) or a key-value list (`Annotation::kv`). This has the new side-effect of rejecting annotations with mismatched bodies. For instance, having an expression list where a key-value list is expected, or having a no-argument annotation with a non-empty body.
As of v1.0.0-draft of the spec, annotations are as follows:
* `@optional` with an empty body (§18.2.1)
* `@tableonly` with an empty body (§18.2.2)
* `@defaultonly` with an empty body (§18.2.2)
* `@name` with a string literal (§18.2.3)
* `@hidden` with an empty body (§18.2.3)
* `@atomic` with an empty body (§18.2.4)
* `@pkginfo` with a key-value list (§18.3)
The front end also supports some annotations used by the tests, but not mentioned in the spec:
* `@length` takes an expression, and
* `@deprecated` takes a string literal; this is a candidate language feature: p4lang/p4-spec#655.
Unrecognized annotations are left untouched. For any target-specific annotations, back ends may do a similar rewriting pass as needed. For instance, the BMv2 back end additionally supports the following annotations:
* `@metadata` has no body,
* `@alias` takes a string literal,
* `@priority` takes an integer constant.
The P4 Runtime serializer uses a `@controller_header` annotation that takes a string literal and an `@id` annotation that takes an integer constant. The GTest uses `@diagnostic` (takes an expression list) and `@my_anno` (takes a string literal).