diff --git a/grammar.js b/grammar.js index 414a63c..4abeab6 100644 --- a/grammar.js +++ b/grammar.js @@ -26,7 +26,12 @@ module.exports = grammar({ translation_entity: ($) => choice($.declaration, $.function_definition), function_definition: ($) => - seq("function", $.identifier, $.function_signature, $.statement_block), + seq( + "function", + field("name", $.identifier), + field("signature", $.function_signature), + field("body", $.statement_block), + ), // ------------------------------------------------------------------------ // Comments @@ -129,17 +134,21 @@ module.exports = grammar({ // ------------------------------------------------------------------------ base_expression: ($) => - choice($.identifier, $.constant, seq("(", $.expression, ")")), + choice( + $.identifier, + $.constant, + seq("(", field("expression", $.expression), ")"), + ), // postfix_expression (Bison: left-recursive) -> base_expression plus a // sequence of postfix operations. postfix_expression: ($) => seq( - $.base_expression, + field("base", $.base_expression), repeat( choice( - seq("[", $.expression, "]"), // subscript - seq("(", optional($.argument_expression_list), ")"), // call + seq("[", field("index", $.expression), "]"), // subscript + seq("(", optional(field("arguments", $.argument_expression_list)), ")"), // call "++", // post-inc "--", // post-dec ), @@ -153,38 +162,46 @@ module.exports = grammar({ unary_expression: ($) => choice( $.postfix_expression, - seq("++", $.unary_expression), - seq("--", $.unary_expression), - seq("+", $.unary_expression), - seq("-", $.unary_expression), - seq("!", $.unary_expression), + seq("++", field("operand", $.unary_expression)), + seq("--", field("operand", $.unary_expression)), + seq("+", field("operand", $.unary_expression)), + seq("-", field("operand", $.unary_expression)), + seq("!", field("operand", $.unary_expression)), ), cast_expression: ($) => choice( $.unary_expression, - seq("(", $.type_specifier_qualifier, ")", $.cast_expression), + seq( + "(", + field("type", $.type_specifier_qualifier), + ")", + field("value", $.cast_expression), + ), ), // multiplicative_expression: cast_expression (( * | / ) cast_expression)* multiplicative_expression: ($) => - seq($.cast_expression, repeat(seq(choice("*", "/"), $.cast_expression))), + seq( + field("left", $.cast_expression), + repeat(seq(choice("*", "/"), field("right", $.cast_expression))), + ), // additive_expression: multiplicative_expression (( + | - ) multiplicative_expression)* additive_expression: ($) => seq( - $.multiplicative_expression, - repeat(seq(choice("+", "-"), $.multiplicative_expression)), + field("left", $.multiplicative_expression), + repeat(seq(choice("+", "-"), field("right", $.multiplicative_expression))), ), // relational_expression: additive_expression ( (< | > | <= | =< | >= | => ) additive_expression )* relational_expression: ($) => seq( - $.additive_expression, + field("left", $.additive_expression), repeat( seq( choice("<", ">", $.leq_operator, $.geq_operator), - $.additive_expression, + field("right", $.additive_expression), ), ), ), @@ -192,15 +209,15 @@ module.exports = grammar({ // equality_expression: relational_expression ( (== | !=) relational_expression )* equality_expression: ($) => seq( - $.relational_expression, - repeat(seq(choice("==", "!="), $.relational_expression)), + field("left", $.relational_expression), + repeat(seq(choice("==", "!="), field("right", $.relational_expression))), ), // logical_expression: equality_expression ( (&& ||) equality_expression )* logical_expression: ($) => seq( - $.equality_expression, - repeat(seq(choice("&&", "||"), $.equality_expression)), + field("left", $.equality_expression), + repeat(seq(choice("&&", "||"), field("right", $.equality_expression))), ), // assignment_expression: @@ -210,9 +227,9 @@ module.exports = grammar({ choice( $.logical_expression, seq( - $.unary_expression, - choice("=", "+=", "-=", "*=", "/="), - $.assignment_expression, + field("left", $.unary_expression), + field("operator", choice("=", "+=", "-=", "*=", "/=")), + field("right", $.assignment_expression), ), ), @@ -224,7 +241,12 @@ module.exports = grammar({ // Types / declarations (port of Bison decl/type rules) // ------------------------------------------------------------------------ - declaration: ($) => seq($.declaration_specifier, $.init_declarator, ";"), + declaration: ($) => + seq( + field("type", $.declaration_specifier), + field("declarator", $.init_declarator), + ";", + ), declaration_specifier: ($) => $.type_specifier_qualifier, @@ -271,14 +293,22 @@ module.exports = grammar({ ), array_specifier: ($) => - seq($.type_specifier, "[", $.constant_expression, "]"), + seq( + field("element", $.type_specifier), + "[", + field("size", $.constant_expression), + "]", + ), type_qualifier_list: ($) => seq($.type_qualifier, repeat($.type_qualifier)), type_qualifier: ($) => choice("const", "mut"), init_declarator: ($) => - seq($.identifier, optional(seq("=", $.initializer))), + seq( + field("name", $.identifier), + optional(seq("=", field("value", $.initializer))), + ), braced_initializer: ($) => choice(seq("{", "}"), seq("{", $.initializer_list, "}")), @@ -291,11 +321,17 @@ module.exports = grammar({ function_signature: ($) => choice( // (params) -> returns - seq("(", $.parameter_list, ")", "->", $.return_list), + seq( + "(", + field("parameters", $.parameter_list), + ")", + "->", + field("return_type", $.return_list), + ), // () -> returns - seq("(", ")", "->", $.return_list), + seq("(", ")", "->", field("return_type", $.return_list)), // (params) (implicit void) - seq("(", $.parameter_list, ")"), + seq("(", field("parameters", $.parameter_list), ")"), // () (implicit void) seq("(", ")"), ), @@ -303,7 +339,8 @@ module.exports = grammar({ parameter_list: ($) => seq($.parameter_declaration, repeat(seq(",", $.parameter_declaration))), - parameter_declaration: ($) => seq($.declaration_specifier, $.identifier), + parameter_declaration: ($) => + seq(field("type", $.declaration_specifier), field("name", $.identifier)), return_list: ($) => $.declaration_specifier, @@ -319,7 +356,8 @@ module.exports = grammar({ $.print_statement, ), - expression_statement: ($) => seq(optional($.expression), ";"), + expression_statement: ($) => + seq(optional(field("expression", $.expression)), ";"), primary_block: ($) => choice($.statement_block, $.selection_statement, $.iteration_statement), @@ -340,15 +378,18 @@ module.exports = grammar({ seq( "if", "(", - $.expression, + field("condition", $.expression), ")", - $.statement_block, + field("consequence", $.statement_block), optional( seq( "else", - choice( - $.statement_block, - $.selection_statement, // else-if chain + field( + "alternative", + choice( + $.statement_block, + $.selection_statement, // else-if chain + ), ), ), ), @@ -358,31 +399,37 @@ module.exports = grammar({ iteration_statement: ($) => choice( // while (expr) statement - seq("while", "(", $.expression, ")", $.secondary_block), + seq( + "while", + "(", + field("condition", $.expression), + ")", + field("body", $.secondary_block), + ), // for (opt_expr ; opt_expr ; opt_expr) statement seq( "for", "(", - optional($.expression), + optional(field("initializer", $.expression)), ";", - optional($.expression), + optional(field("condition", $.expression)), ";", - optional($.expression), + optional(field("update", $.expression)), ")", - $.secondary_block, + field("body", $.secondary_block), ), // for (declaration opt_expr ; opt_expr) statement seq( "for", "(", - $.declaration, - optional($.expression), + field("initializer", $.declaration), + optional(field("condition", $.expression)), ";", - optional($.expression), + optional(field("update", $.expression)), ")", - $.secondary_block, + field("body", $.secondary_block), ), ), @@ -391,9 +438,10 @@ module.exports = grammar({ seq("continue", ";"), seq("break", ";"), seq("return", ";"), - seq("return", $.expression, ";"), + seq("return", field("value", $.expression), ";"), ), - print_statement: ($) => seq("print", "(", $.expression, ")", ";"), + print_statement: ($) => + seq("print", "(", field("value", $.expression), ")", ";"), }, });