diff --git a/tree-sitter-p4/grammar.js b/tree-sitter-p4/grammar.js index c1b6665..be0d491 100644 --- a/tree-sitter-p4/grammar.js +++ b/tree-sitter-p4/grammar.js @@ -29,17 +29,23 @@ export default grammar({ // Common - Parsers parserType: $ => seq(optional($.annotations), $.parser, field('parser_name', $.identifier), optional($.typeParameters), '(', optional($.parameterList), ')'), - parserLocalElements: $ => choice(seq($.parserLocalElements, $.parserLocalElement)), - parserStates: $ => choice($.parserState, seq($.parserStates, $.parserState)), - parserState: $ => seq(optional($.annotations), $.state, $.identifier, '{', optional($.parserStatements), $.parserTransitionStatement, $.semicolon, '}'), - parserLocalElement: $ => choice($.todo), + + // Mark with higher precedence so that the local states are preferred when parsing! + // TODO: Test! + parserLocalElements: $ => prec(2, repeat1(seq($.parserLocalElement, $.semicolon))), + + parserStates: $ => repeat1($.parserState), + parserState: $ => seq(optional($.annotations), $.state, $.identifier, '{', optional($.parserLocalElements), optional($.parserStatements), $.parserTransitionStatement, $.semicolon, '}'), + + parserLocalElement: $ => choice($.variableDeclaration, $.todo), + selectBody: $ => repeat1(seq($.selectCase, $.semicolon)), selectCase: $ => seq($.keysetExpression, $.colon, $.identifier), - annotations: $ => choice($.annotation, seq($.annotations, $.annotation)), + annotations: $ => repeat1($.annotation), //annotation: $ => choice(seq('@', "[a-z]+"), seq('@', "[a-z]+", '(', $.annotationBody, ')'), seq('@', "[a-z]+", '[', $.structuredAnnotationBody, ']')), - annotation: $ => choice(seq('@', "[a-z]+"), seq('@', "[a-z]+", '(', /* empty for now*/ ')'), seq('@', "[a-z]+", '[', /* empty for now */ ']')), + annotation: $ => choice(seq('@', "[a-z]+")),// seq('@', "[a-z]+", '(', /* empty for now*/ ')'), seq('@', "[a-z]+", '[', /* empty for now */ ']')), // Declarations @@ -47,7 +53,9 @@ export default grammar({ // 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), '(', optional($.parameterList), ')'), - parserDeclaration: $ => seq($.parserType, optional($.constructorParameters), '{', seq(optional($.parserLocalElements), $.parserStates), '}'), + parserDeclaration: $ => seq($.parserType, optional($.constructorParameters), '{', optional($.parserLocalElements), $.parserStates, '}'), + + variableDeclaration: $ => seq(optional($.annotations), $.typeRef, field('variable_name', $.identifier), optional(seq('=', $.expression))), // Statements diff --git a/tree-sitter-p4/test/corpus/declarations.txt b/tree-sitter-p4/test/corpus/declarations.txt new file mode 100644 index 0000000..05f34bc --- /dev/null +++ b/tree-sitter-p4/test/corpus/declarations.txt @@ -0,0 +1,49 @@ +========================= +Simple Declaration +========================= +parser simple() { + state start { + bool l; + transition accept; + } +}; + +--- +(p4program + (declaration + (parserDeclaration + (parserType + (parser) + (identifier) + ) + (parserStates + (parserState + (state) + (identifier) + (parserLocalElements + (parserLocalElement + (variableDeclaration + (typeRef + (baseType + (bool) + ) + ) + (identifier) + ) + ) + (semicolon) + ) + (parserTransitionStatement + (transition) + (transitionSelectionExpression + (identifier) + ) + ) + (semicolon) + ) + ) + ) + (semicolon) + ) +) +