d33066c543
Centralize the execution of statements and evaluation of expressions so that the user can specify a debugging "callback" after every execution/evaluation. The callback can be used for myriad things, but it seems likely that it will be useful for implementing: 1. Testing 2. Debugger Signed-off-by: Will Hawkins <hawkinsw@obs.cr>
1096 lines
27 KiB
JavaScript
1096 lines
27 KiB
JavaScript
// p4rse, Copyright 2026, Will Hawkins
|
|
//
|
|
// This file is part of p4rse.
|
|
|
|
// This file is free software: you can redistribute it and/or modify
|
|
// it under the terms of the GNU General Public License as published by
|
|
// the Free Software Foundation, either version 3 of the License, or
|
|
// (at your option) any later version.
|
|
//
|
|
// This program is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
// GNU General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU General Public License
|
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
|
|
/// <reference types="tree-sitter-cli/dsl" />
|
|
// @ts-check
|
|
|
|
export default grammar({
|
|
name: 'p4',
|
|
rules: {
|
|
// Start symbol
|
|
p4program: $ => optional(repeat(seq(choice($.declaration, $.instantiation), $._semicolon))),
|
|
|
|
// Common
|
|
|
|
// Common - Parameters
|
|
typeParameters: $ => seq('<', $.typeParameterList, '>'),
|
|
typeParameterList: $ => choice("[a-z]+", seq($.typeParameterList, ',', "[a-z]+")),
|
|
parameter_list: $ => choice(seq($.parameter_list, ',', $.parameter), $.parameter),
|
|
parameter: $ => choice(seq(optional($.annotations), optional($.direction), $.typeRef, $.identifier), seq(optional($.annotations), optional($.direction), $.typeRef, $.identifier, '=', $.expression)),
|
|
direction: $ => choice($.in, $.out, $.inout),
|
|
parameters: $=> seq('(', optional($.parameter_list), ')'),
|
|
|
|
argument_list: $ => choice($.argument, seq($.argument_list, ',', $.argument)),
|
|
argument: $ => $.expression,
|
|
arguments: $=> seq('(', optional($.argument_list), ')'),
|
|
|
|
// Common - Types
|
|
typeRef: $ => choice($.baseType, $.type_identifier),
|
|
baseType: $ => choice($.bool, $.error, $.string, $.int, $.bit /* omitting "templated" types" */),
|
|
constructor_parameters: $ => seq('(', optional($.parameter_list), ')'),
|
|
|
|
// Common - Parsers
|
|
parserType: $ => seq(optional($.annotations), $.parser, field('parser_name', $.identifier), optional($.typeParameters), $.parameters),
|
|
|
|
// Mark with higher precedence so that the local states are preferred when parsing!
|
|
// TODO: Test!
|
|
parserLocalElements: $ => prec(2, repeat1($.parserLocalElement)),
|
|
|
|
parserStates: $ => repeat1($.parserState),
|
|
parserState: $ => seq(optional($.annotations), $.state, $.identifier, '{', optional($.parserStatements), $.parserTransitionStatement, '}'),
|
|
|
|
parserLocalElement: $ => choice($.variableDeclaration, $.todo),
|
|
|
|
selectBody: $ => repeat1(seq($.selectCase, $._semicolon)),
|
|
selectCase: $ => seq($.keysetExpression, $.colon, $.identifier),
|
|
|
|
annotations: $ => repeat1($.annotation),
|
|
|
|
//annotation: $ => choice(seq('@', "[a-z]+"), seq('@', "[a-z]+", '(', $.annotationBody, ')'), seq('@', "[a-z]+", '[', $.structuredAnnotationBody, ']')),
|
|
annotation: $ => choice($.annotation_literal), // seq('@', "[a-z]+", '(', /* empty for now*/ ')'), seq('@', "[a-z]+", '[', /* empty for now */ ']')),
|
|
|
|
|
|
// Instantiation
|
|
instantiation: $ => seq($.typeRef, '(', optional($.parameter_list), ')', $.identifier),
|
|
|
|
// Declarations
|
|
declaration: $ => seq(choice($.parserDeclaration, $.parserTypeDeclaration, $.type_declaration, $.function_declaration, $.control_declaration)),
|
|
|
|
type_declaration: $=> choice($.struct_declaration),
|
|
struct_declaration: $ => seq($.struct, $.identifier, '{', optional($.struct_declaration_fields), '}'),
|
|
struct_declaration_fields: $=> repeat1(seq($.variableDeclaration)),
|
|
|
|
function_declaration: $=> seq($.typeRef, $.identifier, $.parameters, $.statement),
|
|
|
|
// Make separate productions for the parser type and the parser type declaration because the latter can have type parameters.
|
|
parserTypeDeclaration: $ => seq(optional($.annotations), $.parser, field('parser_name', $.identifier), optional($.typeParameters), $.parameters),
|
|
parserDeclaration: $ => seq($.parserType, '{', optional($.parserLocalElements), $.parserStates, '}'),
|
|
|
|
variableDeclaration: $ => seq(optional($.annotations), $.typeRef, field('variable_name', $.identifier), optional(seq($.assignment, $.expression)), $._semicolon),
|
|
|
|
// Control declarations
|
|
control_declaration: $ => seq($.control, $.identifier, $.parameters, '{', repeat(choice($.table_declaration, $.action_declaration)), $.apply_statement, '}'),
|
|
action_declaration: $ => seq($.action, $.identifier, $.parameters, $.blockStatement),
|
|
table_declaration: $ => seq($.table, $.identifier, '{', optional($.table_property_list), '}'),
|
|
|
|
// Table property list
|
|
table_property_list: $ => repeat1(choice($.table_keys, $.table_actions)),
|
|
table_keys: $=> seq($.key, '=', '{', repeat($.table_key_entry), '}'),
|
|
table_key_entry: $=> seq($.keysetExpression, ':', $.table_key_match_type, $._semicolon),
|
|
table_actions: $=> seq($.actions, '=', '{', optional(repeat1($.identifier)), '}'),
|
|
|
|
// match types
|
|
table_key_match_type: $ => choice($.exact), // support exact only for now.
|
|
|
|
// Statements
|
|
|
|
// General statements
|
|
statements: $ => repeat1($.statement),
|
|
statement: $ => choice($.conditionalStatement, $.blockStatement, $.expressionStatement, $.assignmentStatement, $.variableDeclaration, $.return_statement, $.exit_statement),// Limited, so far.
|
|
blockStatement: $ => seq(optional($.annotations), '{', optional($.statements), '}'),
|
|
conditionalStatement: $ => choice(prec(1, seq($.if, '(', $.expression, ')', $.statement)), prec(2, seq($.if, '(', $.expression, ')', $.statement, $.else, $.statement))),
|
|
expressionStatement: $=> seq($.expression, $._semicolon),
|
|
assignmentStatement: $=> seq($.expression, $.assignment, $.expression, $._semicolon),
|
|
return_statement: $=> seq($._return, $.expression, $._semicolon),
|
|
exit_statement: $=> seq($._exit, $._semicolon),
|
|
apply_statement: $=> seq($.apply, $.blockStatement),
|
|
|
|
// Parser statements
|
|
parserStatements: $ => repeat1($.parserStatement),
|
|
parserStatement: $ => choice($.conditionalStatement, $.expressionStatement, $.assignmentStatement, $.variableDeclaration), // Limited, so far.
|
|
parserTransitionStatement: $ => seq($.transition, $.transitionSelectionExpression, $._semicolon),
|
|
|
|
// Expressions
|
|
expression: $ => choice($.grouped_expression, $.simple_expression),
|
|
grouped_expression: $ => seq('(', $.expression, ')'),
|
|
simple_expression: $ => choice($.identifier, $.integer, $.booleanLiteralExpression, $.string_literal, $.binaryOperatorExpression, $.arrayAccessExpression, $.fieldAccessExpression, $.function_call), // Very limited.
|
|
booleanLiteralExpression: $ => choice($.true, $.false),
|
|
selectExpression: $ => seq($.select, '(', $.expression, ')', '{', $.selectBody, '}'), // TODO: Should be expression list and not just a single expression
|
|
transitionSelectionExpression: $ => choice($.identifier, $.selectExpression),
|
|
keysetExpression: $ => choice($.expression, $.default_keyset),
|
|
binaryOperatorExpression: $ => choice($.binaryEqualOperatorExpression,
|
|
$.binaryLessThanOperatorExpression,
|
|
$.binaryLessThanEqualOperatorExpression,
|
|
$.binaryGreaterThanOperatorExpression,
|
|
$.binaryGreaterThanEqualOperatorExpression,
|
|
$.binaryAndOperatorExpression,
|
|
$.binaryOrOperatorExpression,
|
|
$.binaryAddOperatorExpression,
|
|
$.binarySubtractOperatorExpression,
|
|
$.binaryMultiplyOperatorExpression,
|
|
$.binaryDivideOperatorExpression,
|
|
),
|
|
arrayAccessExpression: $ => seq($.expression, $.open_bracket, $.expression, $.close_bracket),
|
|
fieldAccessExpression: $=> prec.left(2, seq($.expression, $.field_access, $.identifier)),
|
|
|
|
// Function call
|
|
|
|
function_call: $=> seq($.identifier, $.arguments),
|
|
|
|
// Binary Operations
|
|
binaryEqualOperatorExpression: $ => prec.left(2, seq($.expression, $.double_equal, $.expression)),
|
|
binaryLessThanOperatorExpression: $ => prec.left(2, seq($.expression, $.less_than, $.expression)),
|
|
binaryLessThanEqualOperatorExpression: $ => prec.left(2, seq($.expression, $.less_than_equal, $.expression)),
|
|
binaryGreaterThanOperatorExpression: $ => prec.left(2, seq($.expression, $.greater_than, $.expression)),
|
|
binaryGreaterThanEqualOperatorExpression: $ => prec.left(2, seq($.expression, $.greater_than_equal, $.expression)),
|
|
binaryAndOperatorExpression: $ => prec.left(2, seq($.expression, $.and, $.expression)),
|
|
binaryOrOperatorExpression: $ => prec.left(2, seq($.expression, $.or, $.expression)),
|
|
|
|
binaryAddOperatorExpression: $ => prec.left(2, seq($.expression, $.add, $.expression)),
|
|
binarySubtractOperatorExpression: $ => prec.left(2, seq($.expression, $.subtract, $.expression)),
|
|
binaryMultiplyOperatorExpression: $ => prec.left(2, seq($.expression, $.multiply, $.expression)),
|
|
binaryDivideOperatorExpression: $ => prec.left(2, seq($.expression, $.divide, $.expression)),
|
|
|
|
// Tokens
|
|
_semicolon: $ => ";",
|
|
colon: $ => ":",
|
|
assignment: $ => "=",
|
|
todo: $ => "todo",
|
|
abstract: $ => "abstract",
|
|
action: $ => "action",
|
|
actions: $ => "actions",
|
|
apply: $ => "apply",
|
|
bool: $ => "bool",
|
|
bit: $ => "bit",
|
|
const: $ => "const",
|
|
control: $ => "control",
|
|
default: $ => "default",
|
|
else: $ => "else",
|
|
entries: $ => "entries",
|
|
enum: $ => "enum",
|
|
error: $ => "error",
|
|
_exit: $ => "exit",
|
|
exact: $ => "exact",
|
|
extern: $ => "extern",
|
|
false: $ => "false",
|
|
header: $ => "header",
|
|
header_union: $ => "header_union",
|
|
if: $ => "if",
|
|
in: $ => "in",
|
|
inout: $ => "inout",
|
|
int: $ => "int",
|
|
key: $ => "key",
|
|
match_kind: $ => "match_kind",
|
|
type: $ => "type",
|
|
out: $ => "out",
|
|
parser: $ => "parser",
|
|
package: $ => "package",
|
|
pragma: $ => "pragma",
|
|
_return: $ => "return",
|
|
select: $ => "select",
|
|
state: $ => "state",
|
|
string: $ => "string",
|
|
struct: $ => "struct",
|
|
switch: $ => "switch",
|
|
table: $ => "table",
|
|
transition: $ => "transition",
|
|
true: $ => "true",
|
|
tuple: $ => "tuple",
|
|
typedef: $ => "typedef",
|
|
varbit: $ => "varbit",
|
|
valueset: $ => "valueset",
|
|
void: $ => "void",
|
|
identifier: $ => /[A-Za-z_]+/,
|
|
type_identifier: $ => /[A-Za-z_]+/,
|
|
string_literal: $ => /"[^"]*"/,
|
|
integer: $ => /[0-9]+/,
|
|
annotation_literal: $ => /@[A-Za-z_]+/,
|
|
default_keyset: $=> '_',
|
|
|
|
double_equal: $=> '==',
|
|
less_than: $=> '<',
|
|
less_than_equal: $=> '<=',
|
|
greater_than: $=> '>',
|
|
greater_than_equal: $=> '>=',
|
|
|
|
and: $=> "&&",
|
|
or: $=> "||",
|
|
|
|
add: $=> '+',
|
|
subtract: $=> '-',
|
|
multiply: $=> '*',
|
|
divide: $=> '/',
|
|
|
|
open_bracket: $=> '[',
|
|
close_bracket: $=> ']',
|
|
field_access: $=> '.',
|
|
},
|
|
}
|
|
);
|
|
|
|
/*
|
|
p4program
|
|
: // empty
|
|
| p4program declaration
|
|
| p4program ';' // empty declaration
|
|
;
|
|
|
|
declaration
|
|
: constantDeclaration
|
|
| externDeclaration
|
|
| actionDeclaration
|
|
| parserDeclaration
|
|
| typeDeclaration
|
|
| controlDeclaration
|
|
| instantiation
|
|
| errorDeclaration
|
|
| matchKindDeclaration
|
|
| functionDeclaration
|
|
;
|
|
|
|
nonTypeName
|
|
: IDENTIFIER
|
|
| APPLY
|
|
| KEY
|
|
| ACTIONS
|
|
| STATE
|
|
| ENTRIES
|
|
| TYPE
|
|
;
|
|
|
|
name
|
|
: nonTypeName
|
|
| TYPE_IDENTIFIER
|
|
;
|
|
|
|
nonTableKwName
|
|
: IDENTIFIER
|
|
| TYPE_IDENTIFIER
|
|
| APPLY
|
|
| STATE
|
|
| TYPE
|
|
;
|
|
|
|
optAnnotations
|
|
: // empty
|
|
| annotations
|
|
;
|
|
|
|
annotations
|
|
: annotation
|
|
| annotations annotation
|
|
;
|
|
|
|
annotation
|
|
: '@' name
|
|
| '@' name '(' annotationBody ')'
|
|
| '@' name '[' structuredAnnotationBody ']'
|
|
;
|
|
|
|
parameterList
|
|
: // empty
|
|
| nonEmptyParameterList
|
|
;
|
|
|
|
nonEmptyParameterList
|
|
: parameter
|
|
| nonEmptyParameterList ',' parameter
|
|
;
|
|
|
|
parameter
|
|
: optAnnotations direction typeRef name
|
|
| optAnnotations direction typeRef name '=' expression
|
|
;
|
|
|
|
direction
|
|
: IN
|
|
| OUT
|
|
| INOUT
|
|
| // empty
|
|
;
|
|
|
|
packageTypeDeclaration
|
|
: optAnnotations PACKAGE name optTypeParameters
|
|
'(' parameterList ')'
|
|
;
|
|
|
|
instantiation
|
|
: typeRef '(' argumentList ')' name ';'
|
|
| annotations typeRef '(' argumentList ')' name ';'
|
|
| annotations typeRef '(' argumentList ')' name '=' objInitializer ';'
|
|
| typeRef '(' argumentList ')' name '=' objInitializer ';'
|
|
;
|
|
|
|
objInitializer
|
|
: '{' objDeclarations '}'
|
|
;
|
|
|
|
objDeclarations
|
|
: // empty
|
|
| objDeclarations objDeclaration
|
|
;
|
|
|
|
objDeclaration
|
|
: functionDeclaration
|
|
| instantiation
|
|
;
|
|
|
|
optConstructorParameters
|
|
: // empty
|
|
| '(' parameterList ')'
|
|
;
|
|
|
|
dotPrefix
|
|
: '.'
|
|
;
|
|
|
|
// PARSER
|
|
|
|
parserDeclaration
|
|
: parserTypeDeclaration optConstructorParameters
|
|
// no type parameters allowed in the parserTypeDeclaration
|
|
'{' parserLocalElements parserStates '}'
|
|
;
|
|
|
|
parserLocalElements
|
|
: // empty
|
|
| parserLocalElements parserLocalElement
|
|
;
|
|
|
|
parserLocalElement
|
|
: constantDeclaration
|
|
| variableDeclaration
|
|
| instantiation
|
|
| valueSetDeclaration
|
|
;
|
|
|
|
parserTypeDeclaration
|
|
: optAnnotations PARSER name optTypeParameters '(' parameterList ')'
|
|
;
|
|
|
|
parserStates
|
|
: parserState
|
|
| parserStates parserState
|
|
;
|
|
|
|
parserState
|
|
: optAnnotations STATE name '{' parserStatements transitionStatement '}'
|
|
;
|
|
|
|
parserStatements
|
|
: // empty
|
|
| parserStatements parserStatement
|
|
;
|
|
|
|
parserStatement
|
|
: assignmentOrMethodCallStatement
|
|
| directApplication
|
|
| parserBlockStatement
|
|
| constantDeclaration
|
|
| variableDeclaration
|
|
| emptyStatement
|
|
| conditionalStatement
|
|
;
|
|
|
|
parserBlockStatement
|
|
: optAnnotations '{' parserStatements '}'
|
|
;
|
|
|
|
transitionStatement
|
|
: // empty
|
|
| TRANSITION stateExpression
|
|
;
|
|
|
|
stateExpression
|
|
: name ';'
|
|
| selectExpression
|
|
;
|
|
|
|
selectExpression
|
|
: SELECT '(' expressionList ')' '{' selectCaseList '}'
|
|
;
|
|
|
|
selectCaseList
|
|
: // empty
|
|
| selectCaseList selectCase
|
|
;
|
|
|
|
selectCase
|
|
: keysetExpression ':' name ';'
|
|
;
|
|
|
|
keysetExpression
|
|
: tupleKeysetExpression
|
|
| simpleKeysetExpression
|
|
;
|
|
|
|
tupleKeysetExpression
|
|
: "(" simpleKeysetExpression "," simpleExpressionList ")"
|
|
| "(" reducedSimpleKeysetExpression ")"
|
|
;
|
|
|
|
simpleExpressionList
|
|
: simpleKeysetExpression
|
|
| simpleExpressionList ',' simpleKeysetExpression
|
|
;
|
|
|
|
reducedSimpleKeysetExpression
|
|
: expression "&&&" expression
|
|
| expression ".." expression
|
|
| DEFAULT
|
|
| "_"
|
|
;
|
|
|
|
simpleKeysetExpression
|
|
: expression
|
|
| DEFAULT
|
|
| DONTCARE
|
|
| expression MASK expression
|
|
| expression RANGE expression
|
|
;
|
|
|
|
valueSetDeclaration
|
|
: optAnnotations
|
|
VALUESET '<' baseType '>' '(' expression ')' name ';'
|
|
| optAnnotations
|
|
VALUESET '<' tupleType '>' '(' expression ')' name ';'
|
|
| optAnnotations
|
|
VALUESET '<' typeName '>' '(' expression ')' name ';'
|
|
;
|
|
|
|
// CONTROL
|
|
|
|
controlDeclaration
|
|
: controlTypeDeclaration optConstructorParameters
|
|
// no type parameters allowed in controlTypeDeclaration
|
|
'{' controlLocalDeclarations APPLY controlBody '}'
|
|
;
|
|
|
|
controlTypeDeclaration
|
|
: optAnnotations CONTROL name optTypeParameters
|
|
'(' parameterList ')'
|
|
;
|
|
|
|
controlLocalDeclarations
|
|
: // empty
|
|
| controlLocalDeclarations controlLocalDeclaration
|
|
;
|
|
|
|
controlLocalDeclaration
|
|
: constantDeclaration
|
|
| actionDeclaration
|
|
| tableDeclaration
|
|
| instantiation
|
|
| variableDeclaration
|
|
;
|
|
|
|
controlBody
|
|
: blockStatement
|
|
;
|
|
|
|
// Extern
|
|
|
|
externDeclaration
|
|
: optAnnotations EXTERN nonTypeName optTypeParameters '{' methodPrototypes '}'
|
|
| optAnnotations EXTERN functionPrototype ';'
|
|
;
|
|
|
|
methodPrototypes
|
|
: // empty
|
|
| methodPrototypes methodPrototype
|
|
;
|
|
|
|
functionPrototype
|
|
: typeOrVoid name optTypeParameters '(' parameterList ')'
|
|
;
|
|
|
|
methodPrototype
|
|
: optAnnotations functionPrototype ';'
|
|
| optAnnotations TYPE_IDENTIFIER '(' parameterList ')' ';'
|
|
;
|
|
|
|
// TYPES
|
|
|
|
typeRef
|
|
: baseType
|
|
| typeName
|
|
| specializedType
|
|
| headerStackType
|
|
| tupleType
|
|
;
|
|
|
|
namedType
|
|
: typeName
|
|
| specializedType
|
|
;
|
|
|
|
prefixedType
|
|
: TYPE_IDENTIFIER
|
|
| dotPrefix TYPE_IDENTIFIER
|
|
;
|
|
|
|
typeName
|
|
: prefixedType
|
|
;
|
|
|
|
tupleType
|
|
: TUPLE '<' typeArgumentList '>'
|
|
;
|
|
|
|
headerStackType
|
|
: typeName '[' expression ']'
|
|
| specializedType '[' expression ']'
|
|
;
|
|
|
|
specializedType
|
|
: prefixedType '<' typeArgumentList '>'
|
|
;
|
|
|
|
baseType
|
|
: BOOL
|
|
| ERROR
|
|
| STRING
|
|
| INT
|
|
| BIT
|
|
| BIT '<' INTEGER '>'
|
|
| INT '<' INTEGER '>'
|
|
| VARBIT '<' INTEGER '>'
|
|
| BIT '<' '(' expression ')' '>'
|
|
| INT '<' '(' expression ')' '>'
|
|
| VARBIT '<' '(' expression ')' '>'
|
|
;
|
|
|
|
typeOrVoid
|
|
: typeRef
|
|
| VOID
|
|
| IDENTIFIER // may be a type variable
|
|
;
|
|
|
|
optTypeParameters
|
|
: // empty
|
|
| typeParameters
|
|
;
|
|
|
|
typeParameters
|
|
: '<' typeParameterList '>'
|
|
;
|
|
|
|
typeParameterList
|
|
: name
|
|
| typeParameterList ',' name
|
|
;
|
|
|
|
realTypeArg
|
|
: DONTCARE
|
|
| typeRef
|
|
| VOID
|
|
;
|
|
|
|
typeArg
|
|
: DONTCARE
|
|
| typeRef
|
|
| nonTypeName
|
|
| VOID
|
|
;
|
|
|
|
realTypeArgumentList
|
|
: realTypeArg
|
|
| realTypeArgumentList COMMA typeArg
|
|
;
|
|
|
|
typeArgumentList
|
|
: // empty
|
|
| typeArg
|
|
| typeArgumentList ',' typeArg
|
|
;
|
|
|
|
typeDeclaration
|
|
: derivedTypeDeclaration
|
|
| typedefDeclaration
|
|
| parserTypeDeclaration ';'
|
|
| controlTypeDeclaration ';'
|
|
| packageTypeDeclaration ';'
|
|
;
|
|
|
|
derivedTypeDeclaration
|
|
: headerTypeDeclaration
|
|
| headerUnionDeclaration
|
|
| structTypeDeclaration
|
|
| enumDeclaration
|
|
;
|
|
|
|
headerTypeDeclaration
|
|
: optAnnotations HEADER name optTypeParameters '{' structFieldList '}'
|
|
;
|
|
|
|
headerUnionDeclaration
|
|
: optAnnotations HEADER_UNION name optTypeParameters '{' structFieldList '}'
|
|
;
|
|
|
|
structTypeDeclaration
|
|
: optAnnotations STRUCT name optTypeParameters '{' structFieldList '}'
|
|
;
|
|
|
|
structFieldList
|
|
: // empty
|
|
| structFieldList structField
|
|
;
|
|
|
|
structField
|
|
: optAnnotations typeRef name ';'
|
|
;
|
|
|
|
enumDeclaration
|
|
: optAnnotations ENUM name '{' identifierList '}'
|
|
| optAnnotations ENUM typeRef name '{' specifiedIdentifierList '}'
|
|
;
|
|
|
|
errorDeclaration
|
|
: ERROR '{' identifierList '}'
|
|
;
|
|
|
|
matchKindDeclaration
|
|
: MATCH_KIND '{' identifierList '}'
|
|
;
|
|
|
|
identifierList
|
|
: name
|
|
| identifierList ',' name
|
|
;
|
|
|
|
specifiedIdentifierList
|
|
: specifiedIdentifier
|
|
| specifiedIdentifierList ',' specifiedIdentifier
|
|
;
|
|
|
|
specifiedIdentifier
|
|
: name '=' initializer
|
|
;
|
|
|
|
typedefDeclaration
|
|
: optAnnotations TYPEDEF typeRef name ';'
|
|
| optAnnotations TYPEDEF derivedTypeDeclaration name ';'
|
|
| optAnnotations TYPE typeRef name ';'
|
|
| optAnnotations TYPE derivedTypeDeclaration name ';'
|
|
;
|
|
|
|
// Statements
|
|
|
|
assignmentOrMethodCallStatement
|
|
: lvalue '(' argumentList ')' ';'
|
|
| lvalue '<' typeArgumentList '>' '(' argumentList ')' ';'
|
|
| lvalue '=' expression ';'
|
|
;
|
|
|
|
emptyStatement
|
|
: ';'
|
|
;
|
|
|
|
returnStatement
|
|
: RETURN ';'
|
|
| RETURN expression ';'
|
|
;
|
|
|
|
exitStatement
|
|
: EXIT ';'
|
|
;
|
|
|
|
conditionalStatement
|
|
: IF '(' expression ')' statement
|
|
| IF '(' expression ')' statement ELSE statement
|
|
;
|
|
|
|
// To support direct invocation of a control or parser without instantiation
|
|
directApplication
|
|
: typeName '.' APPLY '(' argumentList ')' ';'
|
|
;
|
|
|
|
statement
|
|
: assignmentOrMethodCallStatement
|
|
| directApplication
|
|
| conditionalStatement
|
|
| emptyStatement
|
|
| blockStatement
|
|
| exitStatement
|
|
| returnStatement
|
|
| switchStatement
|
|
;
|
|
|
|
blockStatement
|
|
: optAnnotations '{' statOrDeclList '}'
|
|
;
|
|
|
|
statOrDeclList
|
|
: // empty
|
|
| statOrDeclList statementOrDeclaration
|
|
;
|
|
|
|
switchStatement
|
|
: SWITCH '(' expression ')' '{' switchCases '}'
|
|
;
|
|
|
|
switchCases
|
|
: // empty
|
|
| switchCases switchCase
|
|
;
|
|
|
|
switchCase
|
|
: switchLabel ':' blockStatement
|
|
| switchLabel ':'
|
|
;
|
|
|
|
switchLabel
|
|
: DEFAULT
|
|
| nonBraceExpression
|
|
;
|
|
|
|
statementOrDeclaration
|
|
: variableDeclaration
|
|
| constantDeclaration
|
|
| statement
|
|
| instantiation
|
|
;
|
|
|
|
// Tables
|
|
tableDeclaration
|
|
: optAnnotations TABLE name '{' tablePropertyList '}'
|
|
;
|
|
|
|
tablePropertyList
|
|
: tableProperty
|
|
| tablePropertyList tableProperty
|
|
;
|
|
|
|
tableProperty
|
|
: KEY '=' '{' keyElementList '}'
|
|
| ACTIONS '=' '{' actionList '}'
|
|
| optAnnotations CONST ENTRIES '=' '{' entriesList '}' // immutable entries
|
|
| optAnnotations CONST nonTableKwName '=' initializer ';'
|
|
| optAnnotations nonTableKwName '=' initializer ';'
|
|
;
|
|
|
|
keyElementList
|
|
: // empty
|
|
| keyElementList keyElement
|
|
;
|
|
|
|
keyElement
|
|
: expression ':' name optAnnotations ';'
|
|
;
|
|
|
|
actionList
|
|
: // empty
|
|
| actionList optAnnotations actionRef ';'
|
|
;
|
|
|
|
actionRef
|
|
: prefixedNonTypeName
|
|
| prefixedNonTypeName '(' argumentList ')'
|
|
;
|
|
|
|
entriesList
|
|
: entry
|
|
| entriesList entry
|
|
;
|
|
|
|
entry
|
|
: keysetExpression ':' actionRef optAnnotations ';'
|
|
;
|
|
|
|
// Action
|
|
|
|
actionDeclaration
|
|
: optAnnotations ACTION name '(' parameterList ')' blockStatement
|
|
;
|
|
|
|
// Variables
|
|
|
|
variableDeclaration
|
|
: annotations typeRef name optInitializer ';'
|
|
| typeRef name optInitializer ';'
|
|
;
|
|
|
|
constantDeclaration
|
|
: optAnnotations CONST typeRef name '=' initializer ';'
|
|
;
|
|
|
|
optInitializer
|
|
: // empty
|
|
| '=' initializer
|
|
;
|
|
|
|
initializer
|
|
: expression
|
|
;
|
|
|
|
// Expressions
|
|
|
|
functionDeclaration
|
|
: functionPrototype blockStatement
|
|
;
|
|
|
|
argumentList
|
|
: // empty
|
|
| nonEmptyArgList
|
|
;
|
|
|
|
nonEmptyArgList
|
|
: argument
|
|
| nonEmptyArgList ',' argument
|
|
;
|
|
|
|
argument
|
|
: expression
|
|
| name '=' expression
|
|
| DONTCARE
|
|
;
|
|
|
|
kvList
|
|
: kvPair
|
|
| kvList ',' kvPair
|
|
;
|
|
|
|
kvPair
|
|
: name '=' expression
|
|
;
|
|
|
|
expressionList
|
|
: // empty
|
|
| expression
|
|
| expressionList ',' expression
|
|
;
|
|
|
|
|
|
annotationBody
|
|
: // empty
|
|
| annotationBody '(' annotationBody ')'
|
|
| annotationBody annotationToken
|
|
;
|
|
|
|
structuredAnnotationBody
|
|
: expressionList
|
|
| kvList
|
|
;
|
|
|
|
annotationToken
|
|
: ABSTRACT
|
|
| ACTION
|
|
| ACTIONS
|
|
| APPLY
|
|
| BOOL
|
|
| BIT
|
|
| CONST
|
|
| CONTROL
|
|
| DEFAULT
|
|
| ELSE
|
|
| ENTRIES
|
|
| ENUM
|
|
| ERROR
|
|
| EXIT
|
|
| EXTERN
|
|
| FALSE
|
|
| HEADER
|
|
| HEADER_UNION
|
|
| IF
|
|
| IN
|
|
| INOUT
|
|
| INT
|
|
| KEY
|
|
| MATCH_KIND
|
|
| TYPE
|
|
| OUT
|
|
| PARSER
|
|
| PACKAGE
|
|
| PRAGMA
|
|
| RETURN
|
|
| SELECT
|
|
| STATE
|
|
| STRING
|
|
| STRUCT
|
|
| SWITCH
|
|
| TABLE
|
|
| TRANSITION
|
|
| TRUE
|
|
| TUPLE
|
|
| TYPEDEF
|
|
| VARBIT
|
|
| VALUESET
|
|
| VOID
|
|
| "_"
|
|
| IDENTIFIER
|
|
| TYPE_IDENTIFIER
|
|
| STRING_LITERAL
|
|
| INTEGER
|
|
| "&&&"
|
|
| ".."
|
|
| "<<"
|
|
| "&&"
|
|
| "||"
|
|
| "=="
|
|
| "!="
|
|
| ">="
|
|
| "<="
|
|
| "++"
|
|
| "+"
|
|
| "|+|"
|
|
| "-"
|
|
| "|-|"
|
|
| "*"
|
|
| "/"
|
|
| "%"
|
|
| "|"
|
|
| "&"
|
|
| "^"
|
|
| "~"
|
|
| "["
|
|
| "]"
|
|
| "{"
|
|
| "}"
|
|
| "<"
|
|
| ">"
|
|
| "!"
|
|
| ":"
|
|
| ","
|
|
| "?"
|
|
| "."
|
|
| "="
|
|
| ";"
|
|
| "@"
|
|
| UNKNOWN_TOKEN
|
|
;
|
|
|
|
member
|
|
: name
|
|
;
|
|
|
|
prefixedNonTypeName
|
|
: nonTypeName
|
|
| dotPrefix nonTypeName
|
|
;
|
|
|
|
lvalue
|
|
: prefixedNonTypeName
|
|
| THIS
|
|
| lvalue '.' member
|
|
| lvalue '[' expression ']'
|
|
| lvalue '[' expression ':' expression ']'
|
|
;
|
|
|
|
%left ','
|
|
%nonassoc '?'
|
|
%nonassoc ':'
|
|
%left '||'
|
|
%left '&&'
|
|
%left '==' '!='
|
|
%left '<' '>' '<=' '>='
|
|
%left '|'
|
|
%left '^'
|
|
%left '&'
|
|
%left '<<' '>>'
|
|
%left '++' '+' '-' '|+|' '|-|'
|
|
%left '*' '/' '%'
|
|
%right PREFIX
|
|
%nonassoc ']' '(' '['
|
|
%left '.'
|
|
|
|
// Additional precedences need to be specified
|
|
|
|
expression
|
|
: INTEGER
|
|
| TRUE
|
|
| FALSE
|
|
| THIS
|
|
| STRING_LITERAL
|
|
| nonTypeName
|
|
| dotPrefix nonTypeName
|
|
| expression '[' expression ']'
|
|
| expression '[' expression ':' expression ']'
|
|
| '{' expressionList '}'
|
|
| '{' kvList '}'
|
|
| '(' expression ')'
|
|
| '!' expression %prec PREFIX
|
|
| '~' expression %prec PREFIX
|
|
| '-' expression %prec PREFIX
|
|
| '+' expression %prec PREFIX
|
|
| typeName '.' member
|
|
| ERROR '.' member
|
|
| expression '.' member
|
|
| expression '*' expression
|
|
| expression '/' expression
|
|
| expression '%' expression
|
|
| expression '+' expression
|
|
| expression '-' expression
|
|
| expression '|+|' expression
|
|
| expression '|-|' expression
|
|
| expression '<<' expression
|
|
| expression '>>' expression
|
|
| expression '<=' expression
|
|
| expression '>=' expression
|
|
| expression '<' expression
|
|
| expression '>' expression
|
|
| expression '!=' expression
|
|
| expression '==' expression
|
|
| expression '&' expression
|
|
| expression '^' expression
|
|
| expression '|' expression
|
|
| expression '++' expression
|
|
| expression '&&' expression
|
|
| expression '||' expression
|
|
| expression '?' expression ':' expression
|
|
| expression '<' realTypeArgumentList '>' '(' argumentList ')'
|
|
| expression '(' argumentList ')'
|
|
| namedType '(' argumentList ')'
|
|
| '(' typeRef ')' expression
|
|
;
|
|
|
|
nonBraceExpression
|
|
: INTEGER
|
|
| STRING_LITERAL
|
|
| TRUE
|
|
| FALSE
|
|
| THIS
|
|
| nonTypeName
|
|
| dotPrefix nonTypeName
|
|
| nonBraceExpression '[' expression ']'
|
|
| nonBraceExpression '[' expression ':' expression ']'
|
|
| '(' expression ')'
|
|
| '!' expression %prec PREFIX
|
|
| '~' expression %prec PREFIX
|
|
| '-' expression %prec PREFIX
|
|
| '+' expression %prec PREFIX
|
|
| typeName '.' member
|
|
| ERROR '.' member
|
|
| nonBraceExpression '.' member
|
|
| nonBraceExpression '*' expression
|
|
| nonBraceExpression '/' expression
|
|
| nonBraceExpression '%' expression
|
|
| nonBraceExpression '+' expression
|
|
| nonBraceExpression '-' expression
|
|
| nonBraceExpression '|+|' expression
|
|
| nonBraceExpression '|-|' expression
|
|
| nonBraceExpression '<<' expression
|
|
| nonBraceExpression '>>' expression
|
|
| nonBraceExpression '<=' expression
|
|
| nonBraceExpression '>=' expression
|
|
| nonBraceExpression '<' expression
|
|
| nonBraceExpression '>' expression
|
|
| nonBraceExpression '!=' expression
|
|
| nonBraceExpression '==' expression
|
|
| nonBraceExpression '&' expression
|
|
| nonBraceExpression '^' expression
|
|
| nonBraceExpression '|' expression
|
|
| nonBraceExpression '++' expression
|
|
| nonBraceExpression '&&' expression
|
|
| nonBraceExpression '||' expression
|
|
| nonBraceExpression '?' expression ':' expression
|
|
| nonBraceExpression '<' realTypeArgumentList '>' '(' argumentList ')'
|
|
| nonBraceExpression '(' argumentList ')'
|
|
| namedType '(' argumentList ')'
|
|
| '(' typeRef ')' expression
|
|
;
|
|
*/
|