From 74fead1eba53fd3f486590877646bb7f292f51a0 Mon Sep 17 00:00:00 2001 From: Will Hawkins Date: Thu, 23 Apr 2026 06:01:31 -0400 Subject: [PATCH] grammar: Parse externs Signed-off-by: Will Hawkins --- tree-sitter-p4/grammar.js | 7 +- tree-sitter-p4/test/corpus/declarations.txt | 109 +++++++++++++++----- tree-sitter-p4/test/corpus/statements.txt | 16 ++- 3 files changed, 95 insertions(+), 37 deletions(-) diff --git a/tree-sitter-p4/grammar.js b/tree-sitter-p4/grammar.js index ba28e70..c1df9ac 100644 --- a/tree-sitter-p4/grammar.js +++ b/tree-sitter-p4/grammar.js @@ -68,13 +68,16 @@ export default grammar({ instantiation: $ => seq($.typeRef, '(', optional($.parameter_list), ')', $.identifier), // Declarations - declaration: $ => seq(choice($.parserDeclaration, $.parserTypeDeclaration, $.type_declaration, $.function_declaration, $.control_declaration)), + declaration: $ => seq(choice($.parserDeclaration, $.parserTypeDeclaration, $.type_declaration, $.function_declaration, $.control_declaration, $.extern_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), + extern_declaration: $=> seq($.extern, $.declaration), + + // The body is truly optional only in the extern case. This check is handled by the compiler. + function_declaration: $=> seq($.typeRef, $.identifier, $.parameters, optional($.blockStatement)), // 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), diff --git a/tree-sitter-p4/test/corpus/declarations.txt b/tree-sitter-p4/test/corpus/declarations.txt index 3e189af..9412c9c 100644 --- a/tree-sitter-p4/test/corpus/declarations.txt +++ b/tree-sitter-p4/test/corpus/declarations.txt @@ -282,18 +282,16 @@ bool functionb() { ) (identifier) (parameters) - (statement - (blockStatement - (statements - (statement - (variableDeclaration - (typeRef - (baseType - (string) - ) + (blockStatement + (statements + (statement + (variableDeclaration + (typeRef + (baseType + (string) ) - (identifier) ) + (identifier) ) ) ) @@ -340,18 +338,16 @@ bool functionb(bool a, int b) { ) ) ) - (statement - (blockStatement - (statements - (statement - (variableDeclaration - (typeRef - (baseType - (string) - ) + (blockStatement + (statements + (statement + (variableDeclaration + (typeRef + (baseType + (string) ) - (identifier) ) + (identifier) ) ) ) @@ -416,17 +412,78 @@ bool functionb(in bool a, out int b, inout string c) { ) ) ) - (statement - (blockStatement - (statements - (statement - (variableDeclaration + (blockStatement + (statements + (statement + (variableDeclaration + (typeRef + (baseType + (string) + ) + ) + (identifier) + ) + ) + ) + ) + ) + ) +) +========================= +Extern Function Declaration +========================= +extern bool functionb(in bool a, out int b, inout string c); +--- +(p4program + (declaration + (extern_declaration + (extern) + (declaration + (function_declaration + (typeRef + (baseType + (bool) + ) + ) + (identifier) + (parameters + (parameter_list + (parameter_list + (parameter_list + (parameter + (direction + (in) + ) + (typeRef + (baseType + (bool) + ) + ) + (identifier) + ) + ) + (parameter + (direction + (out) + ) + (typeRef + (baseType + (int) + ) + ) + (identifier) + ) + ) + (parameter + (direction + (inout) + ) (typeRef (baseType (string) ) ) - (identifier) + (identifier) ) ) ) diff --git a/tree-sitter-p4/test/corpus/statements.txt b/tree-sitter-p4/test/corpus/statements.txt index a1ce8a2..57d2a09 100644 --- a/tree-sitter-p4/test/corpus/statements.txt +++ b/tree-sitter-p4/test/corpus/statements.txt @@ -43,15 +43,13 @@ int fun() { ) (identifier) (parameters) - (statement - (blockStatement - (statements - (statement - (return_statement - (expression - (simple_expression - (integer) - ) + (blockStatement + (statements + (statement + (return_statement + (expression + (simple_expression + (integer) ) ) )