From bb228459b1942ef02f662eef9e7b655b173ee2cb Mon Sep 17 00:00:00 2001 From: MaelC001 <55336346+MaelC001@users.noreply.github.com> Date: Tue, 11 Jul 2023 11:24:48 -0400 Subject: [PATCH 01/19] update bug --- grammar.js | 818 +++++++++++++++++++++++++++++++++ src/metadata/ast/translator.rs | 741 ++++++++++++++++------------- src/metadata/ast/tree.rs | 1 + 3 files changed, 1233 insertions(+), 327 deletions(-) create mode 100644 grammar.js diff --git a/grammar.js b/grammar.js new file mode 100644 index 0000000..be21a2c --- /dev/null +++ b/grammar.js @@ -0,0 +1,818 @@ +module.exports = grammar({ + name: 'p4', + + extras: $ => [/\s/, $.line_comment, $.block_comment], + + externals: $ => [$.block_comment], + + conflicts: $ => [ + [$.type_or_void, $.type_identifier], + [$.non_type_name, $.type_identifier], + [$.annotation_token, $.type_identifier], + [$.non_table_kw_name, $.type_identifier], + [$.expression], + ], + + rules: { + source_file: $ => repeat( + seq($._declaration, /\s/), + ), + + _declaration: $ => choice( + $.constant_declaration, + $.extern_declaration, + $.action_declaration, + $.parser_declaration, + $.type_declaration, + $.control_declaration, + $.instantiation, + $.error_declaration, + $.match_kind_declaration, + $.function_declaration, + $.preproc_include_declaration, + $.preproc_define_declaration, + $.preproc_undef_declaration, + $.preproc_conditional_declaration + ), + + non_type_name: $ => choice( + $.identifier, + 'apply', + 'key', + 'actions', + 'state', + 'entries', + 'type', + ), + + comment: $ => choice( + $.line_comment, + $.block_comment + ), + + line_comment: $ => token(seq( + '//', /.*/ + )), + + + name: $ => choice( + $.non_type_name, + $.type_identifier, + ), + + preproc_include_declaration: $ => seq( + field("KeyWord", seq('#','include')), choice( + seq( + '<', + $.file_name, + '>' + ), + seq( + '"', + $.file_name, + '"' + ) + ) + ), + preproc_define_declaration: $ => seq( + field("KeyWord", seq('#','define')), + $.name, + $.expression + ), + + preproc_undef_declaration: $ => seq( + field("KeyWord", seq('#','undef')), + $.name + ), + preproc_conditional_declaration: $ => prec.left(seq( + '#', + field("KeyWord", choice('if', 'ifdef', 'ifndef')), + $.expression, + $._declaration, + repeat($.preproc_conditional_declaration_elif), + optional($.preproc_conditional_declaration_else), + '#', + field("KeyWordEnd", 'endif'))), + preproc_conditional_declaration_else: $ => prec.left(seq('#', field("KeyWord", 'else'), $._declaration)), + preproc_conditional_declaration_elif: $ => prec.left(seq('#', field("KeyWord", 'elif'), $.expression, $._declaration,)), + + file_name: $ => /[^\0]+/, + + non_table_kw_name: $ => choice( + $.identifier, + $.type_identifier, + 'apply', + 'state', + 'type', + ), + + annotation: $ => choice( + seq('@', field("name", $.name)), + seq('@', field("name", $.name), '(', field("body", optional($.annotation_body)), ')'), + seq('@', field("name", $.name), '[', field("struct", $.structured_annotation_body), ']'), + ), + annotation_list: $ => repeat1($.annotation), + annotation_body: $ => choice( + seq(field("body", optional($.annotation_body)), '(', field("body2", optional($.annotation_body)), ')'), + seq(field("body", optional($.annotation_body)), field("token", $.annotation_token)), + ), + + structured_annotation_body: $ => choice( + $.expression_list, + $.kv_list, + ), + + parameter_list: $ => seq( + repeat(seq($.parameter, ',')), $.parameter + ), + + parameter: $ => seq(field("annotation", optional($.annotation_list)), field("direction", optional($.direction)), field("type", $.type_ref), field("name", $.name), optional(seq('=', field("value", $.expression)))), + + direction: $ => choice( + 'in', + 'out', + 'inout', + ), + + package_type_declaration: $ => choice( + seq(field("annotation", optional($.annotation_list)), field("KeyWord", 'package'), field('name', $.name), field('parameters_type', optional($.type_parameters))), + seq(field('parameters', optional($.parameter_list)), ')'), + ), + instantiation: $ => choice( + seq(field("type", $.type_ref), '(', field("args", optional($.argument_list)), ')', field('name', $.name), ';'), + seq(field("annotation", optional($.annotation_list)), field("type", $.type_ref), '(', field("args", optional($.argument_list)), ')', field('name', $.name), ';'), + seq(field("annotation", optional($.annotation_list)), field("type", $.type_ref), '(', field("args", optional($.argument_list)), ')', field('name', $.name), '=', field('obj', $.obj_initializer), ';'), + seq(field("type", $.type_ref), '(', field("args", optional($.argument_list)), ')', field('name', $.name), '=', field('obj', $.obj_initializer), ';'), + ), + + obj_initializer: $ => seq( + '{', repeat($._obj_declaration), '}' + ), + + _obj_declaration: $ => choice( + $.function_declaration, + $.instantiation, + ), + + dot_prefix: $ => seq( + '.', + ), + + parser_declaration: $ => seq( + field("declaration", $.parser_type_declaration), + field("body", $.parser_body) + ), + + parser_body: $ => seq( + '{', + repeat($._parser_local_element), + repeat($.parser_state), + '}' + ), + + _parser_local_element: $ => choice( + $.constant_declaration, + $.variable_declaration, + $.instantiation, + $.value_set_declaration, + ), + + parser_type_declaration: $ => seq( + field("annotation", optional($.annotation_list)), field("KeyWord", 'parser'), field('name', $.name), field('parameters_type', optional($.type_parameters)), '(', field('parameters', optional($.parameter_list)), ')' + ), + parser_state: $ => seq( + field("annotation", optional($.annotation_list)), field("KeyWord", 'state'), field("name", $.name), field("body", $.parser_state_body) + ), + parser_state_body: $ => seq( + '{', + field("statement", optional($.parser_state_body_statement)), + field("transition_statement", optional($.transition_statement)), + '}' + ), + + parser_state_body_statement: $ => repeat1($._parser_statement), + + _parser_statement: $ => choice( + $.assignment_or_method_call_statement, + $.direct_application, + $.parser_block_statement, + $.constant_declaration, + $.variable_declaration, + $.empty_statement, + $.conditional_statement, + ), + + parser_block_statement: $ => seq( + field("annotation", optional($.annotation_list)), field("body",$.parser_block_statement_body) + ), + + parser_block_statement_body: $ => seq( + '{', repeat($._parser_statement), '}' + ), + + transition_statement: $ => seq( + field("KeyWord", 'transition'), $._state_expression + ), + + _state_expression: $ => choice( + seq(field("name",$.name), ';'), + $.select_expression, + ), + + select_expression: $ => seq( + field("KeyWord", 'select'), $.select_expression_params, $.select_expression_body + ), + select_expression_params: $ => seq('(', optional($.expression_list), ')'), + select_expression_body: $ => seq('{', optional($.select_case_list), '}'), + + select_case_list: $ => repeat1($.select_case), + + select_case: $ => seq( + field('type',$._keyset_expression), ':', field('name',$.name), ';' + ), + + _keyset_expression: $ => choice( + $.tuple_keyset_expression, + $.simple_keyset_expression, + ), + + tuple_keyset_expression: $ => choice( + seq("(", $.simple_keyset_expression, ",", $.simple_expression_list, ")"), + seq("(", field("reduce", $.reduced_simple_keyset_expression), ")"), + ), + + simple_expression_list: $ => seq(repeat(seq($.simple_keyset_expression, ',')), $.simple_keyset_expression), + + reduced_simple_keyset_expression: $ => choice( + seq(field("value", $.expression), "&&&", field("value2", $.expression)), + seq(field("value", $.expression), "..", field("value2", $.expression)), + 'default', + "_", + ), + + simple_keyset_expression: $ => choice( + field("value", $.expression), + 'default', + '_', + seq(field("value", $.expression), 'mask', field("value2", $.expression)), + seq(field("value", $.expression), 'range', field("value2", $.expression)), + ), + + value_set_declaration: $ => seq( + field("annotation", optional($.annotation_list)), + field("KeyWord", 'valueset'), + '<', + field("type", choice($.base_type, $.tuple_type, $.type_name)), + '>', + '(', + field("expression", $.expression), + ')', + field("name", $.name), + ';' + ), + + control_declaration: $ => seq( + field("declaration", $.control_type_declaration), + field("body", $.control_body), + ), + + parser_declaration: $ => seq( + field("declaration", $.parser_type_declaration), + field("body", $.parser_body) + ), + + control_body: $ => seq( + '{', + repeat($._control_local_declaration), + field("KeyWord", 'apply'), + $.block_statement, + '}' + ), + + control_type_declaration: $ => seq( + field("annotation", optional($.annotation_list)), field("KeyWord", 'control'), field("name", $.name), field('parameters_type', optional($.type_parameters)), '(', field("parameters", optional($.parameter_list)), ')' + ), + + _control_local_declaration: $ => choice( + $.constant_declaration, + $.action_declaration, + $.table_declaration, + $.instantiation, + $.variable_declaration, + ), + + extern_declaration: $ => choice( + seq(field("annotation", optional($.annotation_list)), field("KeyWord", 'extern'), field('name', $.non_type_name), field('parameters_type', optional($.type_parameters)), '{', field('method', optional($.method_prototype_list)), '}'), + seq(field("annotation", optional($.annotation_list)), field("KeyWord", 'extern'), field('function', $.function_prototype), ';'), + ), + + function_prototype: $ => seq( + field("type", $.type_or_void), field("name", $.name), field('parameters_type', optional($.type_parameters)), '(', field("parameters_list", optional($.parameter_list)), ')' + ), + + method_prototype_list: $ => repeat1($.method_prototype), + + method_prototype: $ => choice( + seq(field("annotation", optional($.annotation_list)), field('function', $.function_prototype), ';'), + seq(field("annotation", optional($.annotation_list)), field('type', $.type_identifier), '(', field('parameters', optional($.parameter_list)), ')', ';'), + ), + + type_ref: $ => choice( + $.base_type, + $.type_name, + $.specialized_type, + $.header_stack_type, + $.tuple_type, + ), + + named_type: $ => choice( + $.type_name, + $.specialized_type, + ), + + prefixed_type: $ => choice( + $.type_identifier, + seq($.dot_prefix, $.type_identifier), + ), + + type_name: $ => seq( + $.prefixed_type, + ), + + tuple_type: $ => seq( + field("KeyWord", 'tuple'), '<', optional($.type_argument_list), '>' + ), + + header_stack_type: $ => choice( + seq($.type_name, '[', $.expression, ']'), + seq($.specialized_type, '[', $.expression, ']'), + ), + + specialized_type: $ => seq( + $.prefixed_type, '<', optional($.type_argument_list), '>' + ), + + base_type: $ => choice( + 'bool', + 'error', + 'match_kind', + 'string', + 'int', + 'bit', + seq('bit', '<', $.integer, '>'), + seq('int', '<', $.integer, '>'), + seq('varbit', '<', $.integer, '>'), + seq('bit', '<', '(', $.expression, ')', '>'), + seq('int', '<', '(', $.expression, ')', '>'), + seq('varbit', '<', '(', $.expression, ')', '>'), + seq('bit', '<', $.define_symbol, '>'), + seq('int', '<', $.define_symbol, '>'), + seq('varbit', '<', $.define_symbol, '>'), + ), + + define_symbol: $ => $.identifier, + + type_or_void: $ => prec.left(1, choice( + $.type_ref, + 'void', + $.identifier, + )), + + type_parameters: $ => seq( + '<', $.type_parameter_list, '>' + ), + + type_parameter_list: $ => seq(repeat(seq($.name, ',')), $.name), + + real_type_arg: $ => choice( + '_', + $.type_ref, + 'void', + ), + + type_arg: $ => choice( + '_', + $.type_ref, + $.non_type_name, + 'void', + ), + + // TODO: Check if last real_type_arg should be type_arg + real_type_argument_list: $ => seq(repeat(seq($.real_type_arg, ',')), $.real_type_arg), + + type_argument_list: $ => seq(repeat(seq($.type_arg, ',')), $.type_arg), + + type_declaration: $ => field("type_kind", choice( + $._derived_type_declaration, + $.typedef_declaration, + seq($.parser_type_declaration, ';'), + seq($.control_type_declaration, ';'), + seq($.package_type_declaration, ';'), + )), + + _derived_type_declaration: $ => choice( + $.header_type_declaration, + $.header_union_declaration, + $.struct_type_declaration, + $.enum_declaration, + ), + + header_type_declaration: $ => seq( + field("annotation", optional($.annotation_list)), field("KeyWord", 'header'), field("name", $.name), field('parameters_type', optional($.type_parameters)), '{', field("field_list", optional($.struct_field_list)), '}' + ), + + header_union_declaration: $ => seq( + field("annotation", optional($.annotation_list)), field("KeyWord", 'header_union'), field("name", $.name), field('parameters_type', optional($.type_parameters)), '{', field("field_list", optional($.struct_field_list)), '}' + ), + + struct_type_declaration: $ => seq( + field("annotation", optional($.annotation_list)), field("KeyWord", 'struct'), field("name", $.name), field('parameters_type', optional($.type_parameters)), '{', field("field_list", optional($.struct_field_list)), '}' + ), + + struct_field_list: $ => repeat1($.struct_field), + struct_field: $ => seq( + field("annotation", optional($.annotation_list)), field("type", $.type_ref), field("name", $.name), ';' + ), + + enum_declaration: $ => choice( + seq(field("annotation", optional($.annotation_list)), field("KeyWord", 'enum'), field("name", $.name), '{', field("option_list", $.identifier_list), '}'), + seq(field("annotation", optional($.annotation_list)), field("KeyWord", 'enum'), field("type", $.type_ref), field("name", $.name), '{', field("option_list", $.specified_identifier_list), '}'), + ), + + error_declaration: $ => seq( + field("KeyWord", 'error'), '{', field("option_list", $.identifier_list), '}' + ), + + match_kind_declaration: $ => seq( + field("KeyWord", 'match_kind'), '{', field("option_list", $.identifier_list), '}' + ), + + identifier_list: $ => seq(repeat(seq($.name, ',')), $.name), + + specified_identifier_list: $ => choice( + $.specified_identifier, + seq($.specified_identifier_list, ',', $.specified_identifier), + ), + + specified_identifier: $ => seq( + $.name, '=', $.initializer + ), + + typedef_declaration: $ => choice( + seq(field("annotation", optional($.annotation_list)), field("KeyWord", 'typedef'), field("type", $.type_ref), field("name", $.name), ';'), + seq(field("annotation", optional($.annotation_list)), field("KeyWord", 'typedef'), field("type", $._derived_type_declaration), field("name", $.name), ';'), + seq(field("annotation", optional($.annotation_list)), field("KeyWord", 'type'), field("type", $.type_ref), field("name", $.name), ';'), + seq(field("annotation", optional($.annotation_list)), field("KeyWord", 'type'), field("type", $._derived_type_declaration), field("name", $.name), ';'), + ), + + assignment_or_method_call_statement: $ => choice( + seq(field("name", $.lvalue), '(', field("parameters", optional($.argument_list)), ')', ';'), + seq(field("name", $.lvalue), '<', field("type", optional($.type_argument_list)), '>', '(', field("parameters", optional($.argument_list)), ')', ';'), + seq(field("name", $.lvalue), '=', field("expression", $.expression), ';'), + ), + + empty_statement: $ => seq( + ';', + ), + + return_statement: $ => seq(field("KeyWord", 'return'), field("expression", optional($.expression)), ';'), + + exit_statement: $ => seq( + 'exit', ';' + ), + + conditional_statement: $ => choice( + prec.left(seq(field("KeyWord", 'if'), '(', field("expression", $.expression), ')', field("bodyIf", $._statement))), + prec.left(seq(field("KeyWord", 'if'), '(', field("expression", $.expression), ')', field("bodyIf", $._statement), field("KeyWordEnd", 'else'), field("bodyElse", $._statement))), + ), + + direct_application: $ => choice( + seq(field("name", $.type_name), '.', field("KeyWord", 'apply'), '(', field("args", optional($.argument_list)), ')', ';'), + seq(field("specialized", $.specialized_type), '.', field("KeyWord", 'apply'), '(', field("args", optional($.argument_list)), ')', ';'), + ), + + _statement: $ => choice( + $.assignment_or_method_call_statement, + $.direct_application, + $.conditional_statement, + $.empty_statement, + $.block_statement, + $.exit_statement, + $.return_statement, + $.switch_statement, + ), + + block_statement: $ => seq( + field("annotation", optional($.annotation_list)), '{', optional($._stat_or_decl_list), '}' + ), + + _stat_or_decl_list: $ => repeat1($._statement_or_declaration), + + switch_statement: $ => seq( + field("KeyWord", 'switch'), '(', field("expression",$.expression), ')', '{', field("body", repeat($.switch_case)), '}' + ), + + switch_case: $ => choice( + seq(field("name",$.switch_label), ':', field("value",$.block_statement)), + seq(field("name",$.switch_label), ':'), + ), + + switch_label: $ => choice( + 'default', + $.non_brace_expression, + ), + + _statement_or_declaration: $ => choice( + $.variable_declaration, + $.constant_declaration, + $._statement, + ), + + table_declaration: $ => seq( + field("annotation", optional($.annotation_list)), field("KeyWord", 'table'), field("name", $.name), '{', field("table", $.table_property_list), '}' + ), + + table_property_list: $ => repeat1($._table_property), + + _table_property: $ => choice( + $.keys_table, + $.action_table, + $.entries_table, + $.name_table + ), + + keys_table: $ => seq(field("KeyWord", 'key'), '=', '{', field("keys", optional($.key_element_list)), '}'), + action_table: $ => seq(field("KeyWord", 'actions'), '=', '{', field("actions", optional($.action_list)), '}'), + entries_table: $ => seq(field("annotation", optional($.annotation_list)), field("KeyWord", 'const'), field("KeyWordEnd", 'entries'), '=', '{', field("entries", optional($.entry_list)), '}'), + name_table: $ => seq(field("annotation", optional($.annotation_list)), field("KeyWord", optional('const')), field("name", $.non_table_kw_name), '=', field("expression", $.initializer), ';'), + + key_element_list: $ => repeat1($.key_element), + + key_element: $ => seq( + seq(field("expression", $.expression), ':', field("name", $.name), field("annotation", optional($.annotation_list)), ';'), + ), + + action_list: $ => repeat1($.action), + action: $ => seq(field("annotation", optional($.annotation_list)), $._action_ref, ';'), + _action_ref: $ => choice( + field("name", $.prefixed_non_type_name), + seq(field("name", $.prefixed_non_type_name), '(', field("args", optional($.argument_list)), ')'), + ), + + entry_list: $ => repeat1($.entry), + + entry: $ => seq( + $._keyset_expression, ':', $._action_ref, field("annotation", optional($.annotation_list)), ';' + ), + + action_declaration: $ => seq( + field("annotation", optional($.annotation_list)), field("KeyWord", 'action'), field("name", $.name), '(', field('parameters', optional($.parameter_list)), ')', field('block', $.block_statement) + ), + + variable_declaration: $ => seq(field("annotation", optional($.annotation_list)), field("type", $.type_ref), field("name", $.name), optional(seq('=', field("value", $.initializer))), ';'), + + constant_declaration: $ => seq( + field("annotation", optional($.annotation_list)), field("KeyWord", 'const'), field("type", $.type_ref), field("name", $.name), '=', field("value", $.initializer), ';' + ), + + initializer: $ => seq( + $.expression, + ), + + function_declaration: $ => seq( + $.function_prototype, $.block_statement + ), + + argument_list: $ => seq(repeat(seq($.argument, ',')), $.argument), + + argument: $ => choice( + field("expression", $.expression), + seq(field("name", $.name), '=', field("expression", $.expression)), + '_', + seq(field("name", $.name), '=', '_'), + ), + + kv_list: $ => seq(repeat(seq($.kv_pair, ',')), $.kv_pair), + + kv_pair: $ => seq( + $.name, '=', $.expression + ), + + expression_list: $ => seq(repeat(seq($.expression, ',')), $.expression), + + annotation_token: $ => choice( + 'abstract', + 'action', + 'actions', + 'apply', + 'bool', + $.bool, + 'bit', + 'const', + 'control', + 'default', + 'else', + 'entries', + 'enum', + 'error', + 'exit', + 'extern', + 'header', + 'header_union', + 'if', + 'in', + 'inout', + 'int', + 'key', + 'match_kind', + 'type', + 'out', + 'parser', + 'package', + 'pragma', + 'return', + 'select', + 'state', + 'string', + 'struct', + 'switch', + 'table', + 'transition', + 'tuple', + 'typedef', + 'varbit', + 'valueset', + 'void', + "_", + $.identifier, + $.type_identifier, + $.string, + $.integer, + "&&&", + "..", + "<<", + "&&", + "||", + "==", + "!=", + ">=", + "<=", + "++", + "+", + "|+|", + "-", + "|-|", + "*", + "/", + "%", + "|", + "&", + "^", + "~", + "[", + "]", + "{", + "}", + "<", + ">", + "!", + ":", + ",", + "?", + ".", + "=", + ";", + "@", + 'unknown_token', + ), + + member: $ => seq( + $.name, + ), + + prefixed_non_type_name: $ => choice( + $.non_type_name, + seq($.dot_prefix, $.non_type_name), + ), + + lvalue: $ => choice( + $.prefixed_non_type_name, + 'this', + $.lvalue_dot, + $.lvalue_bra, + $.lvalue_double_dot, + ), + lvalue_dot: $ => seq($.lvalue, '.', $.member), + lvalue_bra: $ => seq($.lvalue, '[', $.expression, ']'), + lvalue_double_dot: $ => seq($.lvalue, '[', $.expression, ':', $.expression, ']'), + + bool: $ => choice( + 'true', + 'false' + ), + + expression: $ => choice( + $.integer, + $.bool, + 'this', + $.string, + $.non_type_name, + seq($.dot_prefix, $.non_type_name), + prec.left(1, seq($.expression, '[', $.expression, ']')), + prec.left(1, seq($.expression, '[', $.expression, ':', $.expression, ']')), + prec.left(1, seq('{', optional($.expression_list), '}')), + prec.left(1, seq('{', $.kv_list, '}')), + prec.left(1, seq('(', $.expression, ')')), + prec.right(2, seq('!', $.expression)), + prec.right(2, seq('~', $.expression)), + prec.right(2, seq('-', $.expression)), + prec.right(2, seq('+', $.expression)), + prec.left(1, seq($.type_name, '.', $.member)), + prec.left(1, seq('error', '.', $.member)), + prec.left(1, seq($.expression, '.', $.member)), + prec.left(3, seq($.expression, '*', $.expression)), + prec.left(3, seq($.expression, '/', $.expression)), + prec.left(3, seq($.expression, '%', $.expression)), + prec.left(4, seq($.expression, '+', $.expression)), + prec.left(4, seq($.expression, '-', $.expression)), + prec.left(4, seq($.expression, '|+|', $.expression)), + prec.left(4, seq($.expression, '|-|', $.expression)), + prec.left(5, seq($.expression, '<<', $.expression)), + prec.left(5, seq($.expression, '>>', $.expression)), + prec.left(11, seq($.expression, '<=', $.expression)), //TODO: Double check precedence of <=,<... and == + prec.left(11, seq($.expression, '>=', $.expression)), + prec.left(11, seq($.expression, '<', $.expression)), + prec.left(11, seq($.expression, '>', $.expression)), + prec.left(7, seq($.expression, '!=', $.expression)), + prec.left(7, seq($.expression, '==', $.expression)), + prec.left(8, seq($.expression, '&', $.expression)), + prec.left(9, seq($.expression, '^', $.expression)), + prec.left(10, seq($.expression, '|', $.expression)), + prec.left(1, seq($.expression, '++', $.expression)), + prec.left(12, seq($.expression, '&&', $.expression)), + prec.left(12, seq($.expression, '||', $.expression)), + prec.right(13, seq($.expression, '?', $.expression, ':', $.expression)), + prec.left(1, seq($.expression, '<', $.real_type_argument_list, '>', '(', optional($.argument_list), ')')), + prec.left(1, seq($.expression, '(', optional($.argument_list), ')')), + prec.left(1, seq($.named_type, '(', optional($.argument_list), ')')), + prec.right(2, seq('(', $.type_ref, ')', $.expression)), + ), + + non_brace_expression: $ => choice( + $.integer, + $.string, + $.bool, + 'this', + $.non_type_name, + seq($.dot_prefix, $.non_type_name), + seq($.non_brace_expression, '[', $.expression, ']'), + seq($.non_brace_expression, '[', $.expression, ':', $.expression, ']'), + seq('(', $.expression, ')'), + seq('!', $.expression), + seq('~', $.expression), + seq('-', $.expression), + seq('+', $.expression), + seq($.type_name, '.', $.member), + seq('error', '.', $.member), + seq($.non_brace_expression, '.', $.member), + seq($.non_brace_expression, '*', $.expression), + seq($.non_brace_expression, '/', $.expression), + seq($.non_brace_expression, '%', $.expression), + seq($.non_brace_expression, '+', $.expression), + seq($.non_brace_expression, '-', $.expression), + seq($.non_brace_expression, '|+|', $.expression), + seq($.non_brace_expression, '|-|', $.expression), + seq($.non_brace_expression, '<<', $.expression), + seq($.non_brace_expression, '>>', $.expression), + seq($.non_brace_expression, '<=', $.expression), + seq($.non_brace_expression, '>=', $.expression), + seq($.non_brace_expression, '<', $.expression), + seq($.non_brace_expression, '>', $.expression), + seq($.non_brace_expression, '!=', $.expression), + seq($.non_brace_expression, '==', $.expression), + seq($.non_brace_expression, '&', $.expression), + seq($.non_brace_expression, '^', $.expression), + seq($.non_brace_expression, '|', $.expression), + seq($.non_brace_expression, '++', $.expression), + seq($.non_brace_expression, '&&', $.expression), + seq($.non_brace_expression, '||', $.expression), + seq($.non_brace_expression, '?', $.expression, ':', $.expression), + seq($.non_brace_expression, '<', $.real_type_argument_list, '>', '(', optional($.argument_list), ')'), + seq($.non_brace_expression, '(', optional($.argument_list), ')'), + seq($.named_type, '(', optional($.argument_list), ')'), + seq('(', $.type_ref, ')', $.expression), + ), + + integer: $ => /(\d+([wWsS]))?\d+(([xX][0-9A-F_]+)|([bB][0-1_]+)|([oO][0-7_]+)|([dD][0-9_]+))?/, + + string: $ => /"(\\.|[^"\\])*"/, + + + prec: $ => $.identifier, + + identifier: $ => /[a-zA-Z_]\w*/, + + type_identifier: $ => $.identifier, + + } +}); \ No newline at end of file diff --git a/src/metadata/ast/translator.rs b/src/metadata/ast/translator.rs index b2bba7d..b26d08f 100644 --- a/src/metadata/ast/translator.rs +++ b/src/metadata/ast/translator.rs @@ -84,39 +84,43 @@ impl TreesitterTranslator { let mut cursor = node.walk(); for child in node.named_children(&mut cursor) { - let child_node_id = - self.arena - .new_node(Node::new(NodeKind::Method, node, &self.source_code)); - if let Some(annotation) = child.child_by_field_name("annotation") { - node_id.append( - self.parse_annotation(&annotation) - .unwrap_or_else(|| self.new_error_node(&annotation)), - &mut self.arena, - ); - } - if let Some(type_node) = node.child_by_field_name("type") { - child_node_id.append( - self.parse_type_ref(&type_node, NodeKind::Type) - .unwrap_or_else(|| self.new_error_node(&type_node)), - &mut self.arena, - ); + if child.is_error() { + node_id.append(self.new_error_node(&child), &mut self.arena); + } else { + let child_node_id = + self.arena + .new_node(Node::new(NodeKind::Method, node, &self.source_code)); + if let Some(annotation) = child.child_by_field_name("annotation") { + node_id.append( + self.parse_annotation(&annotation) + .unwrap_or_else(|| self.new_error_node(&annotation)), + &mut self.arena, + ); + } + if let Some(type_node) = node.child_by_field_name("type") { + child_node_id.append( + self.parse_type_ref(&type_node, NodeKind::Type, true) + .unwrap_or_else(|| self.new_error_node(&type_node)), + &mut self.arena, + ); - if let Some(paramters) = node.child_by_field_name("parameters") { - let params_node_id = self - .parse_params(¶mters) - .unwrap_or_else(|| self.new_error_node(¶mters)); - child_node_id.append(params_node_id, &mut self.arena); + if let Some(paramters) = node.child_by_field_name("parameters") { + let params_node_id = self + .parse_params(¶mters) + .unwrap_or_else(|| self.new_error_node(¶mters)); + child_node_id.append(params_node_id, &mut self.arena); + } + } + if let Some(function) = node.child_by_field_name("function") { + child_node_id.append( + self.function_prototype(&function) + .unwrap_or_else(|| self.new_error_node(&function)), + &mut self.arena, + ); } - } - if let Some(function) = node.child_by_field_name("function") { - child_node_id.append( - self.function_prototype(&function) - .unwrap_or_else(|| self.new_error_node(&function)), - &mut self.arena, - ); - } - node_id.append(child_node_id, &mut self.arena); + node_id.append(child_node_id, &mut self.arena); + } } Some(node_id) @@ -343,7 +347,7 @@ impl TreesitterTranslator { // Add type node let type_node = node.child_by_field_name("type").unwrap(); node_id.append( - self.parse_type_ref(&type_node, NodeKind::Type) + self.parse_type_ref(&type_node, NodeKind::Type, true) .unwrap_or_else(|| self.new_error_node(&type_node)), &mut self.arena, ); @@ -416,6 +420,13 @@ impl TreesitterTranslator { )); node_value.append(name_node, &mut self_v.arena); } + "base_type" => { + let x = self_v.parse_type_ref(&node, NodeKind::Type, false); + if let Some(y) = x { + name_node = y.clone(); + node_value.append(name_node, &mut self_v.arena); + } + } _ => { if accept.contains(&kind) { name_node = self_v.arena.new_node(Node::new( @@ -512,8 +523,11 @@ impl TreesitterTranslator { &mut self.arena, ); } - let type_node: NodeId = self - .parse_type_ref(&type_kind_node.child_by_field_name("type")?, NodeKind::Type)?; + let type_node: NodeId = self.parse_type_ref( + &type_kind_node.child_by_field_name("type")?, + NodeKind::Type, + true, + )?; node_id.append(type_node, &mut self.arena); let name_node = self.arena.new_node(Node::new( @@ -664,7 +678,7 @@ impl TreesitterTranslator { } if let Some(x) = type_kind_node.child_by_field_name("type") { node_id.append( - self.parse_type_ref(&x, NodeKind::Type) + self.parse_type_ref(&x, NodeKind::Type, true) .unwrap_or_else(|| self.new_error_node(&x)), &mut self.arena, ); @@ -843,7 +857,7 @@ impl TreesitterTranslator { // Add type node if let Some(x) = field_child.child_by_field_name("type") { field_node_id.append( - self.parse_type_ref(&x, NodeKind::Type) + self.parse_type_ref(&x, NodeKind::Type, true) .unwrap_or_else(|| self.new_error_node(&x)), &mut self.arena, ); @@ -897,8 +911,14 @@ impl TreesitterTranslator { &mut self, node: &tree_sitter::Node, n_kind: fn(Type) -> NodeKind, + child_bool: bool, ) -> Option { - let child = node.named_child(0)?; + let child: tree_sitter::Node<'_>; + if child_bool { + child = node.named_child(0)?; + } else { + child = node.clone(); + } let node: Option = match child.kind() { "base_type" => { @@ -969,7 +989,7 @@ impl TreesitterTranslator { &self.source_code, ))); } - } else if child_child.kind() == "expression" { + } else{ let node_return: NodeId; if text.starts_with("int") { node_return = self.arena.new_node(Node::new( @@ -995,8 +1015,14 @@ impl TreesitterTranslator { node, &self.source_code, )); + } + if child_child.kind() == "define_symbol" { + node_return.append(self.arena + .new_node(Node::new(NodeKind::DefineSymbol, node, &self.source_code)), &mut self.arena); + + } else if child_child.kind() == "expression" { + node_return.append(self.parse_value(&child_child)?, &mut self.arena); } - node_return.append(self.parse_value(&child_child)?, &mut self.arena); return Some(node_return); } None @@ -1075,16 +1101,20 @@ impl TreesitterTranslator { let mut cursor = body_syntax_node.walk(); for syntax_child in body_syntax_node.named_children(&mut cursor) { - let child_node_id = match syntax_child.kind() { - // _parser_local_element - "constant_declaration" => self.parse_const_dec(&syntax_child), - "variable_declaration" => self.parse_var_dec(&syntax_child), - "instantiation" => self.instantiation(&syntax_child), - "value_set_declaration" => self.parse_val_set(&syntax_child), - - // parser_state - "parser_state" => self.parse_state(&syntax_child), - _ => None, + let child_node_id = if syntax_child.is_error() { + Some(self.new_error_node(&syntax_child)) + } else { + match syntax_child.kind() { + // _parser_local_element + "constant_declaration" => self.parse_const_dec(&syntax_child), + "variable_declaration" => self.parse_var_dec(&syntax_child), + "instantiation" => self.instantiation(&syntax_child), + "value_set_declaration" => self.parse_val_set(&syntax_child), + + // parser_state + "parser_state" => self.parse_state(&syntax_child), + _ => None, + } }; if let Some(id) = child_node_id { @@ -1142,15 +1172,19 @@ impl TreesitterTranslator { let mut cursor = body_syntax_node.walk(); for syntax_child in body_syntax_node.named_children(&mut cursor) { - let child_node_id = match syntax_child.kind() { - "constant_declaration" => self.parse_const_dec(&syntax_child), - "variable_declaration" => self.parse_var_dec(&syntax_child), - "instantiation" => self.instantiation(&syntax_child), - "action_declaration" => self.parse_control_action(&syntax_child), - "table_declaration" => self.parse_control_table(&syntax_child), - - "block_statement" => self.parse_block(&syntax_child), - _ => None, + let child_node_id = if syntax_child.is_error() { + Some(self.new_error_node(&syntax_child)) + } else { + match syntax_child.kind() { + "constant_declaration" => self.parse_const_dec(&syntax_child), + "variable_declaration" => self.parse_var_dec(&syntax_child), + "instantiation" => self.instantiation(&syntax_child), + "action_declaration" => self.parse_control_action(&syntax_child), + "table_declaration" => self.parse_control_table(&syntax_child), + + "block_statement" => self.parse_block(&syntax_child), + _ => None, + } }; if let Some(id) = child_node_id { @@ -1198,7 +1232,7 @@ impl TreesitterTranslator { // Add type node let type_syntax_node = syntax_child.child_by_field_name("type")?; param_node_id.append( - self.parse_type_ref(&type_syntax_node, NodeKind::Type) + self.parse_type_ref(&type_syntax_node, NodeKind::Type, true) .unwrap_or_else(|| self.new_error_node(&type_syntax_node)), &mut self.arena, ); @@ -1275,10 +1309,14 @@ impl TreesitterTranslator { let mut cursor = node.walk(); for syntax_child in node.named_children(&mut cursor) { - let child_node_id = match syntax_child.kind() { - "function_declaration" => self.function_declaration(&syntax_child), - "instantiation" => self.instantiation(&syntax_child), - _ => None, + let child_node_id = if syntax_child.is_error() { + Some(self.new_error_node(&syntax_child)) + } else { + match syntax_child.kind() { + "function_declaration" => self.function_declaration(&syntax_child), + "instantiation" => self.instantiation(&syntax_child), + _ => None, + } }; if let Some(child_node) = child_node_id { obj_node_id.append(child_node, &mut self.arena); @@ -1314,7 +1352,7 @@ impl TreesitterTranslator { if type_node.kind() == "type_ref" { // TODO fn_node_id.append( - self.parse_type_ref(&type_node, NodeKind::Type) + self.parse_type_ref(&type_node, NodeKind::Type, true) .unwrap_or_else(|| self.new_error_node(&type_node)), &mut self.arena, ); @@ -1352,19 +1390,25 @@ impl TreesitterTranslator { } let mut cursor = node.walk(); for syntax_child in node.named_children(&mut cursor) { - let child_node_id = match syntax_child.kind() { - "constant_declaration" => self.parse_const_dec(&syntax_child), - "variable_declaration" => self.parse_var_dec(&syntax_child), - "assignment_or_method_call_statement" => self.parse_state_assignment(&syntax_child), - "direct_application" => self.parse_state_direct(&syntax_child), - "conditional_statement" => self.parse_state_conditional(&syntax_child), - "empty_statement" => None, - "block_statement" => self.parse_block(&syntax_child), - - "exit_statement" => None, - "return_statement" => self.return_statement(&syntax_child), - "switch_statement" => self.switch_statement(&syntax_child), - _ => None, + let child_node_id = if syntax_child.is_error() { + Some(self.new_error_node(&syntax_child)) + } else { + match syntax_child.kind() { + "constant_declaration" => self.parse_const_dec(&syntax_child), + "variable_declaration" => self.parse_var_dec(&syntax_child), + "assignment_or_method_call_statement" => { + self.parse_state_assignment(&syntax_child) + } + "direct_application" => self.parse_state_direct(&syntax_child), + "conditional_statement" => self.parse_state_conditional(&syntax_child), + "empty_statement" => None, + "block_statement" => self.parse_block(&syntax_child), + + "exit_statement" => None, + "return_statement" => self.return_statement(&syntax_child), + "switch_statement" => self.switch_statement(&syntax_child), + _ => None, + } }; if let Some(child_node) = child_node_id { block_node_id.append(child_node, &mut self.arena); @@ -1407,7 +1451,7 @@ impl TreesitterTranslator { // Add type node let type_node = node.child_by_field_name("type").unwrap(); node_id.append( - self.parse_type_ref(&type_node, NodeKind::Type) + self.parse_type_ref(&type_node, NodeKind::Type, true) .unwrap_or_else(|| self.new_error_node(&type_node)), &mut self.arena, ); @@ -1441,7 +1485,7 @@ impl TreesitterTranslator { "prefixed_non_type_name" => { let node_id = self.arena.new_node(Node::new( NodeKind::Type(Type::Name), - &node, + &node.named_child(0).unwrap(), &self.source_code, )); if let Some(new_child) = last_node { @@ -1456,9 +1500,10 @@ impl TreesitterTranslator { &node, &self.source_code, )); + let t = node.named_child(1).unwrap().named_child(0).unwrap(); let node_id_dot = self.arena.new_node(Node::new( NodeKind::ValueSymbol, - &node.named_child(1).unwrap(), + &t, &self.source_code, )); @@ -1581,14 +1626,18 @@ impl TreesitterTranslator { let mut cursor = param_list.walk(); for syntax_child in param_list.named_children(&mut cursor) { - let child_node_id = match syntax_child.named_child(0)?.kind() { - "type_ref" => self.parse_type_ref(&syntax_child, NodeKind::TypeList), - "non_type_name" => Some(self.arena.new_node(Node::new( - NodeKind::TypeList(Type::Name), - node, - &self.source_code, - ))), - _ => Some(self.new_error_node(&syntax_child)), + let child_node_id = if syntax_child.is_error() { + Some(self.new_error_node(&syntax_child)) + } else { + match syntax_child.named_child(0)?.kind() { + "type_ref" => self.parse_type_ref(&syntax_child, NodeKind::TypeList, true), + "non_type_name" => Some(self.arena.new_node(Node::new( + NodeKind::TypeList(Type::Name), + node, + &self.source_code, + ))), + _ => Some(self.new_error_node(&syntax_child)), + } }; if let Some(child_node) = child_node_id { params_node_id.append(child_node, &mut self.arena); @@ -1660,15 +1709,21 @@ impl TreesitterTranslator { let body = node.child_by_field_name("body")?; let mut cursor = body.walk(); for body_child in body.named_children(&mut cursor) { - let child_node_id = match body_child.kind() { - "assignment_or_method_call_statement" => self.parse_state_assignment(&body_child), - "direct_application" => self.parse_state_direct(&body_child), - "parser_block_statement" => self.parse_state_block(&body_child), - "constant_declaration" => self.parse_const_dec(&body_child), - "variable_declaration" => self.parse_var_dec(&body_child), - "empty_statement" => None, - "conditional_statement" => self.parse_state_conditional(&body_child), - _ => None, + let child_node_id = if body_child.is_error() { + Some(self.new_error_node(&body_child)) + } else { + match body_child.kind() { + "assignment_or_method_call_statement" => { + self.parse_state_assignment(&body_child) + } + "direct_application" => self.parse_state_direct(&body_child), + "parser_block_statement" => self.parse_state_block(&body_child), + "constant_declaration" => self.parse_const_dec(&body_child), + "variable_declaration" => self.parse_var_dec(&body_child), + "empty_statement" => None, + "conditional_statement" => self.parse_state_conditional(&body_child), + _ => None, + } }; if let Some(id) = child_node_id { @@ -1733,17 +1788,23 @@ impl TreesitterTranslator { let mut cursor = node.walk(); for body_child in node.named_children(&mut cursor) { - let child_node_id = match body_child.kind() { - "assignment_or_method_call_statement" => self.parse_state_assignment(&body_child), - "direct_application" => self.parse_state_direct(&body_child), - "conditional_statement" => self.parse_state_conditional(&body_child), - "empty_statement" => None, - "block_statement" => self.parse_block(&body_child), - - "exit_statement" => None, - "return_statement" => self.return_statement(&body_child), - "switch_statement" => self.switch_statement(&body_child), - _ => None, + let child_node_id = if body_child.is_error() { + Some(self.new_error_node(&body_child)) + } else { + match body_child.kind() { + "assignment_or_method_call_statement" => { + self.parse_state_assignment(&body_child) + } + "direct_application" => self.parse_state_direct(&body_child), + "conditional_statement" => self.parse_state_conditional(&body_child), + "empty_statement" => None, + "block_statement" => self.parse_block(&body_child), + + "exit_statement" => None, + "return_statement" => self.return_statement(&body_child), + "switch_statement" => self.switch_statement(&body_child), + _ => None, + } }; if let Some(id) = child_node_id { @@ -1801,7 +1862,9 @@ impl TreesitterTranslator { let body_node = node.child_by_field_name("body")?; let mut cursor = body_node.walk(); for body_child in body_node.named_children(&mut cursor) { - if body_child.kind() == "switch_case" { + if body_child.is_error() { + node_id.append(self.new_error_node(&body_child), &mut self.arena); + } else if body_child.kind() == "switch_case" { let label: NodeId = self.arena .new_node(Node::new(NodeKind::SwitchLabel, node, &self.source_code)); @@ -1851,7 +1914,7 @@ impl TreesitterTranslator { // Add type node let type_node = node.child_by_field_name("type").unwrap(); node_id.append( - self.parse_type_ref(&type_node, NodeKind::Type) + self.parse_type_ref(&type_node, NodeKind::Type, true) .unwrap_or_else(|| self.new_error_node(&type_node)), &mut self.arena, ); @@ -1891,7 +1954,7 @@ impl TreesitterTranslator { // Add type node let type_node = node.child_by_field_name("type").unwrap(); node_id.append( - self.parse_type_ref(&type_node, NodeKind::Type) + self.parse_type_ref(&type_node, NodeKind::Type, true) .unwrap_or_else(|| self.new_error_node(&type_node)), &mut self.arena, ); @@ -2005,196 +2068,205 @@ impl TreesitterTranslator { let mut cursor = table_syntax_node.walk(); for table_child in table_syntax_node.named_children(&mut cursor) { let mut child_node_id: Option = None; - - match table_child.kind() { - "keys_table" => { - let keys = table_child.child_by_field_name("keys").unwrap(); - let keys_node_id = self.arena.new_node(Node::new( - NodeKind::Keys, - &table_child, - &self.source_code, - )); - let mut cursor = keys.walk(); - for keys_child in keys.named_children(&mut cursor) { - // Add name node - let key_node_id = self.arena.new_node(Node::new( - NodeKind::Key, - &keys_child, + if table_child.is_error() { + child_node_id = Some(self.new_error_node(&table_child)); + } else { + match table_child.kind() { + "keys_table" => { + let keys = table_child.child_by_field_name("keys").unwrap(); + let keys_node_id = self.arena.new_node(Node::new( + NodeKind::Keys, + &table_child, &self.source_code, )); - // Add annotation node - if let Some(annotation) = keys_child.child_by_field_name("annotation") { + let mut cursor = keys.walk(); + for keys_child in keys.named_children(&mut cursor) { + // Add name node + let key_node_id = self.arena.new_node(Node::new( + NodeKind::Key, + &keys_child, + &self.source_code, + )); + // Add annotation node + if let Some(annotation) = keys_child.child_by_field_name("annotation") { + key_node_id.append( + self.parse_annotation(&annotation) + .unwrap_or_else(|| self.new_error_node(&annotation)), + &mut self.arena, + ); + } + + // Add name node + let name_node = self.arena.new_node(Node::new( + NodeKind::Name, + &keys_child.child_by_field_name("name").unwrap(), + &self.source_code, + )); + key_node_id.append(name_node, &mut self.arena); + + // Add value node + let value_node = keys_child.child_by_field_name("expression").unwrap(); key_node_id.append( - self.parse_annotation(&annotation) - .unwrap_or_else(|| self.new_error_node(&annotation)), + self.parse_value(&value_node) + .unwrap_or_else(|| self.new_error_node(&value_node)), &mut self.arena, ); - } - // Add name node - let name_node = self.arena.new_node(Node::new( - NodeKind::Name, - &keys_child.child_by_field_name("name").unwrap(), + keys_node_id.append(key_node_id, &mut self.arena); + } + child_node_id = Some(keys_node_id); + } + "action_table" => { + let actions = table_child.child_by_field_name("actions").unwrap(); + let actions_node_id = self.arena.new_node(Node::new( + NodeKind::Actions, + &table_child, &self.source_code, )); - key_node_id.append(name_node, &mut self.arena); + let mut cursor = actions.walk(); + for actions_child in actions.named_children(&mut cursor) { + // Add name node + let action_node_id = self.arena.new_node(Node::new( + NodeKind::Action, + &actions_child, + &self.source_code, + )); + // Add annotation node + if let Some(annotation) = + actions_child.child_by_field_name("annotation") + { + action_node_id.append( + self.parse_annotation(&annotation) + .unwrap_or_else(|| self.new_error_node(&annotation)), + &mut self.arena, + ); + } - // Add value node - let value_node = keys_child.child_by_field_name("expression").unwrap(); - key_node_id.append( - self.parse_value(&value_node) - .unwrap_or_else(|| self.new_error_node(&value_node)), - &mut self.arena, - ); + // Add name node + let name_node = self.arena.new_node(Node::new( + NodeKind::Type(Type::Name), + &actions_child.child_by_field_name("name").unwrap(), + &self.source_code, + )); + action_node_id.append(name_node, &mut self.arena); - keys_node_id.append(key_node_id, &mut self.arena); + if let Some(params_syntax_node) = node.child_by_field_name("args") { + let params_node_id = self + .parse_args(¶ms_syntax_node) + .unwrap_or_else(|| self.new_error_node(¶ms_syntax_node)); + node_id.append(params_node_id, &mut self.arena); + } + + actions_node_id.append(action_node_id, &mut self.arena); + } + child_node_id = Some(actions_node_id); } - child_node_id = Some(keys_node_id); - } - "action_table" => { - let actions = table_child.child_by_field_name("actions").unwrap(); - let actions_node_id = self.arena.new_node(Node::new( - NodeKind::Actions, - &table_child, - &self.source_code, - )); - let mut cursor = actions.walk(); - for actions_child in actions.named_children(&mut cursor) { - // Add name node - let action_node_id = self.arena.new_node(Node::new( - NodeKind::Action, - &actions_child, + "entries_table" => { + let entries = table_child.child_by_field_name("entries").unwrap(); + let entries_node_id = self.arena.new_node(Node::new( + NodeKind::Entries, + &table_child, &self.source_code, )); - // Add annotation node - if let Some(annotation) = actions_child.child_by_field_name("annotation") { - action_node_id.append( - self.parse_annotation(&annotation) - .unwrap_or_else(|| self.new_error_node(&annotation)), - &mut self.arena, - ); - } + let mut cursor = entries.walk(); + for entries_child in entries.named_children(&mut cursor) { + // Add name node + let entrie_node_id = self.arena.new_node(Node::new( + NodeKind::Entrie, + &entries_child, + &self.source_code, + )); + // Add annotation node + if let Some(annotation) = + entries_child.child_by_field_name("annotation") + { + entrie_node_id.append( + self.parse_annotation(&annotation) + .unwrap_or_else(|| self.new_error_node(&annotation)), + &mut self.arena, + ); + } - // Add name node - let name_node = self.arena.new_node(Node::new( - NodeKind::Type(Type::Name), - &actions_child.child_by_field_name("name").unwrap(), - &self.source_code, - )); - action_node_id.append(name_node, &mut self.arena); + // Add name node + let name_node = self.arena.new_node(Node::new( + NodeKind::Name, + &entries_child.child_by_field_name("name").unwrap(), + &self.source_code, + )); + entrie_node_id.append(name_node, &mut self.arena); - if let Some(params_syntax_node) = node.child_by_field_name("args") { - let params_node_id = self - .parse_args(¶ms_syntax_node) - .unwrap_or_else(|| self.new_error_node(¶ms_syntax_node)); - node_id.append(params_node_id, &mut self.arena); - } + if let Some(params_syntax_node) = node.child_by_field_name("args") { + let params_node_id = self + .parse_args(¶ms_syntax_node) + .unwrap_or_else(|| self.new_error_node(¶ms_syntax_node)); + node_id.append(params_node_id, &mut self.arena); + } + + // _keyset_expression + if let Some(x) = entries_child.named_child(0) { + if x.kind() == "tuple_keyset_expression" { + if let Some(y) = x.child_by_field_name("reduce") { + entrie_node_id.append( + self.parse_reduced_simple_keyset_expression(&y) + .unwrap_or_else(|| self.new_error_node(&y)), + &mut self.arena, + ); + } else { + let t = x.named_child(0)?; + let tt = x.named_child(1)?; + entrie_node_id.append( + self.parse_simple_keyset_expression(&t) + .unwrap_or_else(|| self.new_error_node(&t)), + &mut self.arena, + ); + entrie_node_id.append( + self.parse_simple_expression_list(&tt) + .unwrap_or_else(|| self.new_error_node(&tt)), + &mut self.arena, + ); + } + } else if x.kind() == "simple_keyset_expression" { + entrie_node_id.append( + self.parse_simple_keyset_expression(&x) + .unwrap_or_else(|| self.new_error_node(&x)), + &mut self.arena, + ); + } + } - actions_node_id.append(action_node_id, &mut self.arena); + entries_node_id.append(entrie_node_id, &mut self.arena); + } + child_node_id = Some(entries_node_id); } - child_node_id = Some(actions_node_id); - } - "entries_table" => { - let entries = table_child.child_by_field_name("entries").unwrap(); - let entries_node_id = self.arena.new_node(Node::new( - NodeKind::Entries, - &table_child, - &self.source_code, - )); - let mut cursor = entries.walk(); - for entries_child in entries.named_children(&mut cursor) { - // Add name node - let entrie_node_id = self.arena.new_node(Node::new( - NodeKind::Entrie, - &entries_child, + "name_table" => { + let name = table_child.child_by_field_name("name").unwrap(); + let table_kw_node_id = self.arena.new_node(Node::new( + NodeKind::TableKw, + &table_child, &self.source_code, )); - // Add annotation node - if let Some(annotation) = entries_child.child_by_field_name("annotation") { - entrie_node_id.append( - self.parse_annotation(&annotation) - .unwrap_or_else(|| self.new_error_node(&annotation)), - &mut self.arena, - ); - } // Add name node let name_node = self.arena.new_node(Node::new( NodeKind::Name, - &entries_child.child_by_field_name("name").unwrap(), + &name, &self.source_code, )); - entrie_node_id.append(name_node, &mut self.arena); - - if let Some(params_syntax_node) = node.child_by_field_name("args") { - let params_node_id = self - .parse_args(¶ms_syntax_node) - .unwrap_or_else(|| self.new_error_node(¶ms_syntax_node)); - node_id.append(params_node_id, &mut self.arena); - } + table_kw_node_id.append(name_node, &mut self.arena); - // _keyset_expression - if let Some(x) = entries_child.named_child(0) { - if x.kind() == "tuple_keyset_expression" { - if let Some(y) = x.child_by_field_name("reduce") { - entrie_node_id.append( - self.parse_reduced_simple_keyset_expression(&y) - .unwrap_or_else(|| self.new_error_node(&y)), - &mut self.arena, - ); - } else { - let t = x.named_child(0)?; - let tt = x.named_child(1)?; - entrie_node_id.append( - self.parse_simple_keyset_expression(&t) - .unwrap_or_else(|| self.new_error_node(&t)), - &mut self.arena, - ); - entrie_node_id.append( - self.parse_simple_expression_list(&tt) - .unwrap_or_else(|| self.new_error_node(&tt)), - &mut self.arena, - ); - } - } else if x.kind() == "simple_keyset_expression" { - entrie_node_id.append( - self.parse_simple_keyset_expression(&x) - .unwrap_or_else(|| self.new_error_node(&x)), - &mut self.arena, - ); - } + // Add value node + if let Some(expr) = table_child.child_by_field_name("expression") { + let value_node = expr.named_child(0).unwrap(); + table_kw_node_id.append( + self.parse_value(&value_node) + .unwrap_or_else(|| self.new_error_node(&value_node)), + &mut self.arena, + ); } - - entries_node_id.append(entrie_node_id, &mut self.arena); - } - child_node_id = Some(entries_node_id); - } - "name_table" => { - let name = table_child.child_by_field_name("name").unwrap(); - let table_kw_node_id = self.arena.new_node(Node::new( - NodeKind::TableKw, - &table_child, - &self.source_code, - )); - - // Add name node - let name_node = - self.arena - .new_node(Node::new(NodeKind::Name, &name, &self.source_code)); - table_kw_node_id.append(name_node, &mut self.arena); - - // Add value node - if let Some(expr) = table_child.child_by_field_name("expression") { - let value_node = expr.named_child(0).unwrap(); - table_kw_node_id.append( - self.parse_value(&value_node) - .unwrap_or_else(|| self.new_error_node(&value_node)), - &mut self.arena, - ); + child_node_id = Some(table_kw_node_id); } - child_node_id = Some(table_kw_node_id); + _ => {} } - _ => {} } if let Some(id) = child_node_id { @@ -2276,17 +2348,21 @@ impl TreesitterTranslator { if let Some(statement) = body_node.child_by_field_name("statement") { let mut cursor = statement.walk(); for body_child in statement.named_children(&mut cursor) { - let child_node_id = match body_child.kind() { - "assignment_or_method_call_statement" => { - self.parse_state_assignment(&body_child) + let child_node_id = if body_child.is_error() { + Some(self.new_error_node(&body_child)) + } else { + match body_child.kind() { + "assignment_or_method_call_statement" => { + self.parse_state_assignment(&body_child) + } + "direct_application" => self.parse_state_direct(&body_child), + "parser_block_statement" => self.parse_state_block(&body_child), + "constant_declaration" => self.parse_const_dec(&body_child), + "variable_declaration" => self.parse_var_dec(&body_child), + "empty_statement" => None, + "conditional_statement" => self.parse_state_conditional(&body_child), + _ => None, } - "direct_application" => self.parse_state_direct(&body_child), - "parser_block_statement" => self.parse_state_block(&body_child), - "constant_declaration" => self.parse_const_dec(&body_child), - "variable_declaration" => self.parse_var_dec(&body_child), - "empty_statement" => None, - "conditional_statement" => self.parse_state_conditional(&body_child), - _ => None, }; if let Some(id) = child_node_id { @@ -2357,7 +2433,10 @@ impl TreesitterTranslator { )); let mut cursor = select_expression_body_node.walk(); for body_child in select_expression_body_node.named_children(&mut cursor) { - if body_child.kind() == "select_case" { + if body_child.is_error() { + expression_body_node + .append(self.new_error_node(&body_child), &mut self.arena); + } else if body_child.kind() == "select_case" { let t = self.arena.new_node(Node::new( NodeKind::Row, &body_node, @@ -2426,43 +2505,47 @@ impl TreesitterTranslator { let mut cursor = node.walk(); for child in node.named_children(&mut cursor) { - let child_node_id = - self.arena - .new_node(Node::new(NodeKind::Annotation, node, &self.source_code)); - - child_node_id.append( - self.arena.new_node(Node::new( - NodeKind::Name, - &child.child_by_field_name("name").unwrap(), - &self.source_code, - )), - &mut self.arena, - ); + if child.is_error() { + node_id.append(self.new_error_node(&child), &mut self.arena); + } else { + let child_node_id = + self.arena + .new_node(Node::new(NodeKind::Annotation, node, &self.source_code)); - if let Some(body) = child.child_by_field_name("body") { child_node_id.append( - self.parse_annotation_body(&body) - .unwrap_or_else(|| self.new_error_node(&body)), + self.arena.new_node(Node::new( + NodeKind::Name, + &child.child_by_field_name("name").unwrap(), + &self.source_code, + )), &mut self.arena, ); - } - if let Some(struct_body) = node.child_by_field_name("struct") { - if struct_body.kind() == "expression_list" { - child_node_id.append( - self.parse_expression_list(&struct_body) - .unwrap_or_else(|| self.new_error_node(&struct_body)), - &mut self.arena, - ); - } else if struct_body.kind() == "kv_list" { + + if let Some(body) = child.child_by_field_name("body") { child_node_id.append( - self.parse_kv_list(&struct_body) - .unwrap_or_else(|| self.new_error_node(&struct_body)), + self.parse_annotation_body(&body) + .unwrap_or_else(|| self.new_error_node(&body)), &mut self.arena, ); } - } + if let Some(struct_body) = node.child_by_field_name("struct") { + if struct_body.kind() == "expression_list" { + child_node_id.append( + self.parse_expression_list(&struct_body) + .unwrap_or_else(|| self.new_error_node(&struct_body)), + &mut self.arena, + ); + } else if struct_body.kind() == "kv_list" { + child_node_id.append( + self.parse_kv_list(&struct_body) + .unwrap_or_else(|| self.new_error_node(&struct_body)), + &mut self.arena, + ); + } + } - node_id.append(child_node_id, &mut self.arena); + node_id.append(child_node_id, &mut self.arena); + } } Some(node_id) @@ -2475,26 +2558,30 @@ impl TreesitterTranslator { let mut cursor = node.walk(); for child in node.named_children(&mut cursor) { - let child_node_id = - self.arena - .new_node(Node::new(NodeKind::Kv, node, &self.source_code)); + if child.is_error() { + node_id.append(self.new_error_node(&child), &mut self.arena); + } else { + let child_node_id = + self.arena + .new_node(Node::new(NodeKind::Kv, node, &self.source_code)); - // Add name node - let node_name = child.named_child(0).unwrap(); - let name_node = - self.arena - .new_node(Node::new(NodeKind::Name, &node_name, &self.source_code)); - child_node_id.append(name_node, &mut self.arena); + // Add name node + let node_name = child.named_child(0).unwrap(); + let name_node = + self.arena + .new_node(Node::new(NodeKind::Name, &node_name, &self.source_code)); + child_node_id.append(name_node, &mut self.arena); - // Add value node - let node_value = child.named_child(1).unwrap(); - child_node_id.append( - self.parse_value(&node_value) - .unwrap_or_else(|| self.new_error_node(&node_value)), - &mut self.arena, - ); + // Add value node + let node_value = child.named_child(1).unwrap(); + child_node_id.append( + self.parse_value(&node_value) + .unwrap_or_else(|| self.new_error_node(&node_value)), + &mut self.arena, + ); - node_id.append(child_node_id, &mut self.arena); + node_id.append(child_node_id, &mut self.arena); + } } Some(node_id) diff --git a/src/metadata/ast/tree.rs b/src/metadata/ast/tree.rs index d5ed3b9..a8d3d7d 100644 --- a/src/metadata/ast/tree.rs +++ b/src/metadata/ast/tree.rs @@ -112,6 +112,7 @@ pub enum NodeKind { MatchKind, Args, Arg, + DefineSymbol, } const SCOPE_NODES: [NodeKind; 17] = [ From 8b94b016dd857f9aa561aad99b314ad8d53c1219 Mon Sep 17 00:00:00 2001 From: MaelC001 <55336346+MaelC001@users.noreply.github.com> Date: Tue, 11 Jul 2023 16:10:28 -0400 Subject: [PATCH 02/19] new grammar --- Cargo.lock | 1 - Cargo.toml | 3 +- examples/basic.p4 | 10 + examples/t.p4 | 366 +++++++++++++++++++++++++++++++++ grammar.js | 54 +++-- src/metadata/ast/translator.rs | 40 ++-- 6 files changed, 441 insertions(+), 33 deletions(-) create mode 100644 examples/t.p4 diff --git a/Cargo.lock b/Cargo.lock index 1dc7163..c2ed7e6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2289,7 +2289,6 @@ dependencies = [ [[package]] name = "tree-sitter-p4" version = "0.0.1" -source = "git+https://github.com/ace-design/tree-sitter-p4#27200e8e6f42445146eb56fc58f37361eaf4c751" dependencies = [ "cc", "tree-sitter", diff --git a/Cargo.toml b/Cargo.toml index 2f84be8..a4172ce 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -19,4 +19,5 @@ time = "0.3.20" tokio = { version = "1.28.2", features = ["full"] } tower-lsp = "0.19.0" tree-sitter = "0.20.9" -tree-sitter-p4 = {git = "https://github.com/ace-design/tree-sitter-p4"} +tree-sitter-p4 = { path = "/home/mc/Documents/tree-sitter-p4" } +# {git = "https://github.com/ace-design/tree-sitter-p4"} diff --git a/examples/basic.p4 b/examples/basic.p4 index 7b60d84..9d73968 100644 --- a/examples/basic.p4 +++ b/examples/basic.p4 @@ -81,7 +81,17 @@ parser MyParser(packet_in packet, control MyVerifyChecksum(inout headers hdr, inout metadata meta) { apply { } } +// expand key decrypt +#define get_exp_key(ROUND) action get_exp_key_r##ROUND##(){ \ + t0_inv = meta.aes.expandkey_r##ROUND##[127:96]; \ + t1_inv = meta.aes.expandkey_r##ROUND##[95:64]; \ + t2_inv = meta.aes.expandkey_r##ROUND##[63:32]; \ + t3_inv = meta.aes.expandkey_r##ROUND##[31:0]; \ +} + +#define dsgdsgsd 24 +#define afsfds /************************************************************************* ************** I N G R E S S P R O C E S S I N G ******************* diff --git a/examples/t.p4 b/examples/t.p4 new file mode 100644 index 0000000..c76c7cb --- /dev/null +++ b/examples/t.p4 @@ -0,0 +1,366 @@ +/* -*- P4_16 -*- */ +#include +#include + +const bit<16> TYPE_IPV4 = 0x800; +const bit<8> TYPE_UDP = 0x11; + +/************************************************************************* +*********************** H E A D E R S *********************************** +*************************************************************************/ + +typedef bit<9> egressSpec_t; +typedef bit<48> macAddr_t; +typedef bit<32> ip4Addr_t; + +header ethernet_t { + macAddr_t dstAddr; + macAddr_t srcAddr; + bit<16> etherType; +} + +header ipv4_t { + bit<4> version; + bit<4> ihl; + bit<8> diffserv; + bit<16> totalLen; + bit<16> identification; + bit<3> flags; + bit<13> fragOffset; + bit<8> ttl; + bit<8> protocol; + bit<16> hdrChecksum; + ip4Addr_t srcAddr; + ip4Addr_t dstAddr; +} + +header udp_t{ + bit<16> srcPort; + bit<16> desPort; + bit<16> len; + bit<16> checksum; +} + +header pmu_t { + bit<16> sync; + bit<16> frame_size; + bit<16> id_code; + bit<32> soc; + bit<32> fracsec; + bit<16> stat; + bit<64> phasors; + bit<16> freq; + bit<16> dfreq; + bit<32> analog; + bit<16> digital; + bit<16> chk; +} + +struct headers { + ethernet_t ethernet; + ipv4_t ipv4; + udp_t udp; + pmu_t pmu; +} + +/* +struct controller_pmu_packet { + bit<32> soc; + bit<32> fracsec; + bit<64> phasors; +} +*/ + +struct jpt_pmu_triplet_t { + bit<32> soc0; + bit<32> fracsec0; + bit<64> phasors0; + bit<32> soc1; + bit<32> fracsec1; + bit<64> phasors1; + bit<32> soc2; + bit<32> fracsec2; + bit<64> phasors2; + bit<32> curr_soc; + bit<32> curr_fracsec; +} +struct metadata { + jpt_pmu_triplet_t jpt_packet; +} + + +/* +struct metadata { + controller_pmu_packet jpt_packet; +} +*/ + +/************************************************************************* +*********************** P A R S E R *********************************** +*************************************************************************/ + +parser MyParser(packet_in packet, + out headers hdr, + inout metadata meta, + inout standard_metadata_t standard_metadata) { + + state start { + transition parse_ethernet; + } + + state parse_ethernet { + packet.extract(hdr.ethernet); + transition select(hdr.ethernet.etherType) { + TYPE_IPV4: parse_ipv4; + default: accept; + } + } + + state parse_ipv4 { + packet.extract(hdr.ipv4); + transition select(hdr.ipv4.protocol){ + TYPE_UDP: parse_udp; + default: accept; + } + } + + state parse_udp { + packet.extract(hdr.udp); + transition select(hdr.udp.desPort){ + 4712: parse_pmu; + default: accept; + } + } + + state parse_pmu { + packet.extract(hdr.pmu); + transition accept; + } + + +} + +/************************************************************************* +************ C H E C K S U M V E R I F I C A T I O N ************* +*************************************************************************/ + +control MyVerifyChecksum(inout headers hdr, inout metadata meta) { + apply { } +} + + +/************************************************************************* +************** I N G R E S S P R O C E S S I N G ******************* +*************************************************************************/ +struct phasor_t { + bit<32> magnitude; + bit<32> angle; +} +control MyIngress(inout headers hdr, + inout metadata meta, + inout standard_metadata_t standard_metadata) { + + register>(3) frac_sec_regs; + register>(3) soc_regs; + register>(3) magnitude_regs; + register>(3) phase_angle_regs; + register>(3) R1; + + + bit<32> new_reg3; + bit<32> new_reg2; + + bit<32> temp_mag; + bit<32> temp_ang; + + action drop() { + mark_to_drop(standard_metadata); + } + + action update_registers() { + //0 is top of stackssss + frac_sec_regs.read(new_reg3, (bit<32>)1); + frac_sec_regs.read(new_reg2, (bit<32>)0); + frac_sec_regs.write((bit<32>)2, new_reg3); + frac_sec_regs.write((bit<32>)1, new_reg2); + frac_sec_regs.write((bit<32>)0, hdr.pmu.fracsec); + + soc_regs.read(new_reg3, (bit<32>)1); + soc_regs.read(new_reg2, (bit<32>)0); + soc_regs.write((bit<32>)2, new_reg3); + soc_regs.write((bit<32>)1, new_reg2); + soc_regs.write((bit<32>)0, hdr.pmu.soc); + + magnitude_regs.read(new_reg3, (bit<32>)1); + magnitude_regs.read(new_reg2, (bit<32>)0); + magnitude_regs.write((bit<32>)2, new_reg3); + magnitude_regs.write((bit<32>)1, new_reg2); + magnitude_regs.write((bit<32>)0, (bit<32>)(hdr.pmu.phasors >> 32)); + + phase_angle_regs.read(new_reg3, (bit<32>)1); + phase_angle_regs.read(new_reg2, (bit<32>)0); + phase_angle_regs.write((bit<32>)2, new_reg3); + phase_angle_regs.write((bit<32>)1, new_reg2); + phase_angle_regs.write((bit<32>)0, (bit<32>)hdr.pmu.phasors); + } + + action send_pmu_to_control_plane() { + // 0 is top of stack and most recent packets + + magnitude_regs.read(temp_mag, (bit<32>)0); + phase_angle_regs.read(temp_ang, (bit<32>)0); + meta.jpt_packet.phasors0 = temp_mag ++ temp_ang; + soc_regs.read(meta.jpt_packet.soc0, (bit<32>)0); + frac_sec_regs.read(meta.jpt_packet.fracsec0, (bit<32>)0); + + magnitude_regs.read(temp_mag, (bit<32>)1); + phase_angle_regs.read(temp_ang, (bit<32>)1); + meta.jpt_packet.phasors1 = temp_mag ++ temp_ang; + soc_regs.read(meta.jpt_packet.soc1, (bit<32>)1); + frac_sec_regs.read(meta.jpt_packet.fracsec1, (bit<32>)1); + + magnitude_regs.read(temp_mag, (bit<32>)2); + phase_angle_regs.read(temp_ang, (bit<32>)2); + meta.jpt_packet.phasors2 = temp_mag ++ temp_ang; + soc_regs.read(meta.jpt_packet.soc2, (bit<32>)2); + frac_sec_regs.read(meta.jpt_packet.fracsec2, (bit<32>)2); + + + + meta.jpt_packet.curr_soc = hdr.pmu.soc; + meta.jpt_packet.curr_fracsec = hdr.pmu.fracsec; + + digest(1, meta.jpt_packet); + } + + action ipv4_forward(macAddr_t dstAddr, egressSpec_t port) { + standard_metadata.egress_spec = port; + hdr.ethernet.srcAddr = hdr.ethernet.dstAddr; + hdr.ethernet.dstAddr = dstAddr; + hdr.ipv4.ttl = hdr.ipv4.ttl - 1; + } + + table ipv4_lpm { + key = { + hdr.ipv4.dstAddr: lpm; + } + actions = { + ipv4_forward; + drop; + NoAction; + } + size = 1024; + default_action = drop(); + } + + apply { + //disable hdr is valid for speed test + if (hdr.ipv4.isValid()) { + bit<32> temp_soc; + bit<32> temp_frac_sec; + //if generated packet + if(hdr.pmu.stat == (bit<16>)0x0) + { + soc_regs.read(temp_soc, (bit<32>)0); + frac_sec_regs.read(temp_frac_sec, (bit<32>)0); + + bit<32> soc_diff_in_frac_sec = (hdr.pmu.soc - temp_soc) * 1000000; + bit<32> frac_sec_diff = soc_diff_in_frac_sec - temp_frac_sec + hdr.pmu.fracsec; + + if(frac_sec_diff > 20000 && temp_soc != 0) //gives a bit of "breathing room" for measurements + { + //SPEED_TEST: attaching local timestamp of when packets sent to control plane + /*hdr.pmu.analog = (bit<32>)standard_metadata.ingress_global_timestamp;*/ + send_pmu_to_control_plane(); + } + + update_registers(); + } + else + { + //SPEED_TEST: attaching local timestamp of arrival from control plane + /* + hdr.pmu.digital = (bit<16>)(standard_metadata.ingress_global_timestamp >> 16); + hdr.pmu.chk = (bit<16>)standard_metadata.ingress_global_timestamp; + */ + } + + + ipv4_lpm.apply(); + } + } +} + +/************************************************************************* +**************** E G R E S S P R O C E S S I N G ******************* +*************************************************************************/ + +control MyEgress(inout headers hdr, + inout metadata meta, + inout standard_metadata_t standard_metadata) { + apply { + + } +} + +/************************************************************************* +************* C H E C K S U M C O M P U T A T I O N ************** +*************************************************************************/ + +control MyComputeChecksum(inout headers hdr, inout metadata meta) { + apply { + update_checksum( + hdr.ipv4.isValid(), + { hdr.ipv4.version, + hdr.ipv4.ihl, + hdr.ipv4.diffserv, + hdr.ipv4.totalLen, + hdr.ipv4.identification, + hdr.ipv4.flags, + hdr.ipv4.fragOffset, + hdr.ipv4.ttl, + hdr.ipv4.protocol, + hdr.ipv4.srcAddr, + hdr.ipv4.dstAddr }, + hdr.ipv4.hdrChecksum, + HashAlgorithm.csum16); + + update_checksum_with_payload( + hdr.udp.isValid(), + { + hdr.udp.srcPort, + hdr.udp.desPort, + hdr.udp.len, + }, + hdr.udp.checksum, + HashAlgorithm.csum16); + + } +} + +/************************************************************************* +*********************** D E P A R S E R ******************************* +*************************************************************************/ + +control MyDeparser(packet_out packet, in headers hdr) { + + apply { + packet.emit(hdr.ethernet); + packet.emit(hdr.ipv4); + packet.emit(hdr.udp); + packet.emit(hdr.pmu); + } +} + +/************************************************************************* +*********************** S W I T C H ******************************* +*************************************************************************/ + +V1Switch( +MyParser(), +MyVerifyChecksum(), +MyIngress(), +MyEgress(), +MyComputeChecksum(), +MyDeparser() +) main; \ No newline at end of file diff --git a/grammar.js b/grammar.js index be21a2c..bd78d0d 100644 --- a/grammar.js +++ b/grammar.js @@ -1,7 +1,18 @@ module.exports = grammar({ name: 'p4', - extras: $ => [/\s/, $.line_comment, $.block_comment], + extras: $ => [ + /\s/, + $.line_comment, + $.block_comment, + $.preproc_include_declaration, + $.preproc_define_declaration, + $.preproc_undef_declaration, + $.preproc_conditional_declaration, + $.preproc_conditional_declaration_elif, + $.preproc_conditional_declaration_else, + $.preproc_conditional_declaration_end + ], externals: $ => [$.block_comment], @@ -28,11 +39,7 @@ module.exports = grammar({ $.instantiation, $.error_declaration, $.match_kind_declaration, - $.function_declaration, - $.preproc_include_declaration, - $.preproc_define_declaration, - $.preproc_undef_declaration, - $.preproc_conditional_declaration + $.function_declaration ), non_type_name: $ => choice( @@ -74,29 +81,42 @@ module.exports = grammar({ ) ) ), + preproc_define_declaration: $ => seq( field("KeyWord", seq('#','define')), - $.name, - $.expression - ), + //field("name", $.identifier), + //field("param", optional(seq("(",$.identifier, optional($.identifier_list),")"))), + field("body", $.body_define) + ), // todo + identifier_list: $ => repeat1(seq(',',$.identifier)), + body_define: $ => seq(optional(/[^\/]*\\/),/.*/), preproc_undef_declaration: $ => seq( field("KeyWord", seq('#','undef')), - $.name + $.identifier ), preproc_conditional_declaration: $ => prec.left(seq( '#', - field("KeyWord", choice('if', 'ifdef', 'ifndef')), - $.expression, + choice( + seq(field("KeyWord", 'if'), /.*/),//$.expression), + seq(field("KeyWord", 'ifdef'), $.identifier), + seq(field("KeyWord", 'ifndef'), $.identifier) + ) + /*, $._declaration, repeat($.preproc_conditional_declaration_elif), optional($.preproc_conditional_declaration_else), '#', - field("KeyWordEnd", 'endif'))), - preproc_conditional_declaration_else: $ => prec.left(seq('#', field("KeyWord", 'else'), $._declaration)), - preproc_conditional_declaration_elif: $ => prec.left(seq('#', field("KeyWord", 'elif'), $.expression, $._declaration,)), + field("KeyWordEnd", 'endif')*/ + )), + preproc_conditional_declaration_end: $ => prec.left(seq( + '#', + field("KeyWordEnd", 'endif') + )), + preproc_conditional_declaration_else: $ => prec.left(seq('#', field("KeyWord", 'else'))),//, $._declaration)), + preproc_conditional_declaration_elif: $ => prec.left(seq('#', field("KeyWord", 'elif'), /.*/)),//$.expression)),//, $._declaration,)), - file_name: $ => /[^\0]+/, + file_name: $ => /[^<>"]+/, non_table_kw_name: $ => choice( $.identifier, @@ -803,7 +823,7 @@ module.exports = grammar({ seq('(', $.type_ref, ')', $.expression), ), - integer: $ => /(\d+([wWsS]))?\d+(([xX][0-9A-F_]+)|([bB][0-1_]+)|([oO][0-7_]+)|([dD][0-9_]+))?/, + integer: $ => /(\d+([wWsS]))?\d+(([xX][0-9A-Fa-f_]+)|([bB][0-1_]+)|([oO][0-7_]+)|([dD][0-9_]+))?/, string: $ => /"(\\.|[^"\\])*"/, diff --git a/src/metadata/ast/translator.rs b/src/metadata/ast/translator.rs index b26d08f..2bbe167 100644 --- a/src/metadata/ast/translator.rs +++ b/src/metadata/ast/translator.rs @@ -45,7 +45,7 @@ impl TreesitterTranslator { let tree = self.tree.clone(); let mut cursor = tree.walk(); for child in tree.root_node().named_children(&mut cursor) { - //debug!("{:?}",child); + debug!("{:?}",child); let new_child = if child.is_error() { Some(self.new_error_node(&child)) } else { @@ -269,32 +269,44 @@ impl TreesitterTranslator { self.arena .new_node(Node::new(NodeKind::PreprocDefine, node, &self.source_code)); + debug!("0"); // Add keyword node - if let Some(type_node) = node.child_by_field_name("KeyWord") { + let type_node = node.child_by_field_name("KeyWord").unwrap(); node_id.append( self.arena .new_node(Node::new(NodeKind::KeyWord, &type_node, &self.source_code)), &mut self.arena, ); - } + debug!("1"); // Add name node - let node_name = node.named_child(0).unwrap(); + /*let node_name = node.child_by_field_name("name").unwrap(); let name_node = self.arena .new_node(Node::new(NodeKind::Name, &node_name, &self.source_code)); - node_id.append(name_node, &mut self.arena); - - // Add value node - let node_value = node.named_child(1).unwrap(); - node_id.append( - self.parse_value(&node_value) - .unwrap_or_else(|| self.new_error_node(&node_value)), - &mut self.arena, - ); + node_id.append(name_node, &mut self.arena);*/ - node_id.append(name_node, &mut self.arena); + debug!("2"); + // Add param node + /*let node_name = node.child_by_field_name("param").unwrap(); + let name_node = + self.arena + .new_node(Node::new(NodeKind::Name, &node_name, &self.source_code)); + node_id.append(name_node, &mut self.arena);*/ + + debug!("3"); + // Add body node + if let Some(node_body) = node.child_by_field_name("body"){ + node_id.append(self.arena + .new_node(Node::new(NodeKind::Body, &node_body, &self.source_code)), + //self.parse_value(&node_value) + //.unwrap_or_else(|| self.new_error_node(&node_value)), + &mut self.arena, + ); + } + debug!("4"); + Some(node_id) } fn parse_preproc_undef(&mut self, node: &tree_sitter::Node) -> Option { From 2ce0cc611966bad450d1813ea45cc006d9a15d7e Mon Sep 17 00:00:00 2001 From: MaelC001 <55336346+MaelC001@users.noreply.github.com> Date: Wed, 12 Jul 2023 10:00:03 -0400 Subject: [PATCH 03/19] preproc define grammar --- grammar.js | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/grammar.js b/grammar.js index bd78d0d..f39f431 100644 --- a/grammar.js +++ b/grammar.js @@ -7,6 +7,7 @@ module.exports = grammar({ $.block_comment, $.preproc_include_declaration, $.preproc_define_declaration, + $.preproc_define_declaration_macro, $.preproc_undef_declaration, $.preproc_conditional_declaration, $.preproc_conditional_declaration_elif, @@ -84,12 +85,33 @@ module.exports = grammar({ preproc_define_declaration: $ => seq( field("KeyWord", seq('#','define')), - //field("name", $.identifier), - //field("param", optional(seq("(",$.identifier, optional($.identifier_list),")"))), + field("name", $.identifier), + /\s/, + field("body", choice( + $.integer, + $.string, + $.bool, + $.identifier, + $.null_value + )) + ), + preproc_define_declaration_macro: $ => seq( + field("KeyWord", seq('#','define')), + field("name", $.identifier), + optional(/\s/), + '(', + optional( + field("param", seq( + $.identifier, + optional($.identifier_list) + )) + ), + ')', field("body", $.body_define) ), // todo identifier_list: $ => repeat1(seq(',',$.identifier)), body_define: $ => seq(optional(/[^\/]*\\/),/.*/), + null_value: $ => /\s/, preproc_undef_declaration: $ => seq( field("KeyWord", seq('#','undef')), From ac9447a123d083693aa01f1dc62f5c31a6c621ac Mon Sep 17 00:00:00 2001 From: MaelC001 <55336346+MaelC001@users.noreply.github.com> Date: Wed, 12 Jul 2023 10:31:31 -0400 Subject: [PATCH 04/19] prerpoc define in translator --- src/metadata/ast/translator.rs | 59 +++++++++++++++++++++++++--------- src/metadata/types.rs | 1 + 2 files changed, 44 insertions(+), 16 deletions(-) diff --git a/src/metadata/ast/translator.rs b/src/metadata/ast/translator.rs index 2bbe167..6f4b997 100644 --- a/src/metadata/ast/translator.rs +++ b/src/metadata/ast/translator.rs @@ -62,7 +62,7 @@ impl TreesitterTranslator { "extern_declaration" => self.parse_extern(&child), "preproc_include_declaration" => self.parse_preproc_include(&child), - "preproc_define_declaration" => self.parse_preproc_define(&child), + "preproc_define_declaration" | "preproc_define_declaration_macro" => self.parse_preproc_define(&child), "preproc_undef_declaration" => self.parse_preproc_undef(&child), _ => None, @@ -269,7 +269,6 @@ impl TreesitterTranslator { self.arena .new_node(Node::new(NodeKind::PreprocDefine, node, &self.source_code)); - debug!("0"); // Add keyword node let type_node = node.child_by_field_name("KeyWord").unwrap(); node_id.append( @@ -278,37 +277,57 @@ impl TreesitterTranslator { &mut self.arena, ); - debug!("1"); // Add name node - /*let node_name = node.child_by_field_name("name").unwrap(); + let node_name = node.child_by_field_name("name").unwrap(); let name_node = self.arena .new_node(Node::new(NodeKind::Name, &node_name, &self.source_code)); - node_id.append(name_node, &mut self.arena);*/ + node_id.append(name_node, &mut self.arena); - debug!("2"); // Add param node - /*let node_name = node.child_by_field_name("param").unwrap(); - let name_node = - self.arena - .new_node(Node::new(NodeKind::Name, &node_name, &self.source_code)); - node_id.append(name_node, &mut self.arena);*/ + if let Some(param_node) = node.child_by_field_name("param"){ + node_id.append(self.parse_params_define(¶m_node).unwrap_or_else(|| self.new_error_node(¶m_node)), &mut self.arena); + } - debug!("3"); // Add body node if let Some(node_body) = node.child_by_field_name("body"){ + node_id.append(self.parse_value(&node_body).unwrap_or_else(|| self.new_error_node(&node_body)), + &mut self.arena, + ); + } + + // Add body node + if let Some(node_body) = node.child_by_field_name("body_macro"){ node_id.append(self.arena .new_node(Node::new(NodeKind::Body, &node_body, &self.source_code)), - //self.parse_value(&node_value) - //.unwrap_or_else(|| self.new_error_node(&node_value)), &mut self.arena, ); } - - debug!("4"); Some(node_id) } + + fn parse_params_define(&mut self, node: &tree_sitter::Node) -> Option { + let params_node_id = + self.arena + .new_node(Node::new(NodeKind::Params, node, &self.source_code)); + + let mut cursor = node.walk(); + for syntax_child in node.named_children(&mut cursor) { + if syntax_child.is_error() { + params_node_id.append(self.new_error_node(&syntax_child), &mut self.arena); + } else if syntax_child.kind() == "identifier" { + let param_node_id = self.arena.new_node(Node::new( + NodeKind::Param, + &syntax_child, + &self.source_code, + )); + + params_node_id.append(param_node_id, &mut self.arena); + } + } + Some(params_node_id) + } fn parse_preproc_undef(&mut self, node: &tree_sitter::Node) -> Option { let node_id = self.arena @@ -439,6 +458,14 @@ impl TreesitterTranslator { node_value.append(name_node, &mut self_v.arena); } } + "null_value" => { + name_node = self_v.arena.new_node(Node::new( + NodeKind::Type(Type::Base(BaseType::Null)), + node, + &self_v.source_code, + )); + node_value.append(name_node, &mut self_v.arena); + } _ => { if accept.contains(&kind) { name_node = self_v.arena.new_node(Node::new( diff --git a/src/metadata/types.rs b/src/metadata/types.rs index a995370..c9a5560 100644 --- a/src/metadata/types.rs +++ b/src/metadata/types.rs @@ -9,6 +9,7 @@ pub enum BaseType { Int, Bit, Varbit, + Null, SizedInt(Option), SizedVarbit(Option), SizedBit(Option), From e209f2108c4f51fb14451d23eee1bd1f5c85aa62 Mon Sep 17 00:00:00 2001 From: MaelC001 <55336346+MaelC001@users.noreply.github.com> Date: Wed, 12 Jul 2023 10:32:14 -0400 Subject: [PATCH 05/19] Update grammar.js --- grammar.js | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/grammar.js b/grammar.js index f39f431..2fb1f98 100644 --- a/grammar.js +++ b/grammar.js @@ -101,15 +101,16 @@ module.exports = grammar({ optional(/\s/), '(', optional( - field("param", seq( - $.identifier, - optional($.identifier_list) - )) + field("param", $.param_define) ), ')', - field("body", $.body_define) + field("body_macro", $.body_define) ), // todo - identifier_list: $ => repeat1(seq(',',$.identifier)), + param_define: $ => seq( + $.identifier, + optional($._identifier_list) + ), + _identifier_list: $ => repeat1(seq(',', $.identifier)), body_define: $ => seq(optional(/[^\/]*\\/),/.*/), null_value: $ => /\s/, From e6a4a4604b21d487e75b7b602192117aca5bc0dc Mon Sep 17 00:00:00 2001 From: MaelC001 <55336346+MaelC001@users.noreply.github.com> Date: Wed, 12 Jul 2023 10:32:48 -0400 Subject: [PATCH 06/19] prettier translator --- src/metadata/ast/translator.rs | 57 +++++++++++++++++++++------------- 1 file changed, 36 insertions(+), 21 deletions(-) diff --git a/src/metadata/ast/translator.rs b/src/metadata/ast/translator.rs index 6f4b997..9e5e149 100644 --- a/src/metadata/ast/translator.rs +++ b/src/metadata/ast/translator.rs @@ -45,7 +45,7 @@ impl TreesitterTranslator { let tree = self.tree.clone(); let mut cursor = tree.walk(); for child in tree.root_node().named_children(&mut cursor) { - debug!("{:?}",child); + debug!("{:?}", child); let new_child = if child.is_error() { Some(self.new_error_node(&child)) } else { @@ -62,7 +62,9 @@ impl TreesitterTranslator { "extern_declaration" => self.parse_extern(&child), "preproc_include_declaration" => self.parse_preproc_include(&child), - "preproc_define_declaration" | "preproc_define_declaration_macro" => self.parse_preproc_define(&child), + "preproc_define_declaration" | "preproc_define_declaration_macro" => { + self.parse_preproc_define(&child) + } "preproc_undef_declaration" => self.parse_preproc_undef(&child), _ => None, @@ -271,11 +273,11 @@ impl TreesitterTranslator { // Add keyword node let type_node = node.child_by_field_name("KeyWord").unwrap(); - node_id.append( - self.arena - .new_node(Node::new(NodeKind::KeyWord, &type_node, &self.source_code)), - &mut self.arena, - ); + node_id.append( + self.arena + .new_node(Node::new(NodeKind::KeyWord, &type_node, &self.source_code)), + &mut self.arena, + ); // Add name node let node_name = node.child_by_field_name("name").unwrap(); @@ -285,25 +287,32 @@ impl TreesitterTranslator { node_id.append(name_node, &mut self.arena); // Add param node - if let Some(param_node) = node.child_by_field_name("param"){ - node_id.append(self.parse_params_define(¶m_node).unwrap_or_else(|| self.new_error_node(¶m_node)), &mut self.arena); + if let Some(param_node) = node.child_by_field_name("param") { + node_id.append( + self.parse_params_define(¶m_node) + .unwrap_or_else(|| self.new_error_node(¶m_node)), + &mut self.arena, + ); } // Add body node - if let Some(node_body) = node.child_by_field_name("body"){ - node_id.append(self.parse_value(&node_body).unwrap_or_else(|| self.new_error_node(&node_body)), + if let Some(node_body) = node.child_by_field_name("body") { + node_id.append( + self.parse_value(&node_body) + .unwrap_or_else(|| self.new_error_node(&node_body)), &mut self.arena, ); } // Add body node - if let Some(node_body) = node.child_by_field_name("body_macro"){ - node_id.append(self.arena - .new_node(Node::new(NodeKind::Body, &node_body, &self.source_code)), + if let Some(node_body) = node.child_by_field_name("body_macro") { + node_id.append( + self.arena + .new_node(Node::new(NodeKind::Body, &node_body, &self.source_code)), &mut self.arena, ); } - + Some(node_id) } @@ -1028,7 +1037,7 @@ impl TreesitterTranslator { &self.source_code, ))); } - } else{ + } else { let node_return: NodeId; if text.starts_with("int") { node_return = self.arena.new_node(Node::new( @@ -1054,13 +1063,19 @@ impl TreesitterTranslator { node, &self.source_code, )); - } + } if child_child.kind() == "define_symbol" { - node_return.append(self.arena - .new_node(Node::new(NodeKind::DefineSymbol, node, &self.source_code)), &mut self.arena); - + node_return.append( + self.arena.new_node(Node::new( + NodeKind::DefineSymbol, + node, + &self.source_code, + )), + &mut self.arena, + ); } else if child_child.kind() == "expression" { - node_return.append(self.parse_value(&child_child)?, &mut self.arena); + node_return + .append(self.parse_value(&child_child)?, &mut self.arena); } return Some(node_return); } From f69d7aa73a2c094ba44691103c442b412aa80b55 Mon Sep 17 00:00:00 2001 From: MaelC001 <55336346+MaelC001@users.noreply.github.com> Date: Wed, 12 Jul 2023 11:33:15 -0400 Subject: [PATCH 07/19] preproc special table --- src/metadata/symbol_table.rs | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/metadata/symbol_table.rs b/src/metadata/symbol_table.rs index 2a1a05b..a0fffe7 100644 --- a/src/metadata/symbol_table.rs +++ b/src/metadata/symbol_table.rs @@ -330,6 +330,7 @@ pub struct Symbols { pub constants: Vec, pub variables: Vec, pub functions: Vec, + pub preproc: Vec, } impl Symbols { @@ -515,15 +516,18 @@ impl ScopeSymbolTable { table.symbols.variables.push(x); } } + NodeKind::PreprocDefine | NodeKind::PreprocInclude | NodeKind::PreprocUndef => { + if let Some(x) = _create_symbol_for_parse(child_visit_node, NodeKind::Name) + { + table.symbols.preproc.push(x); + } + } NodeKind::ParserDec | NodeKind::ControlDec | NodeKind::ControlAction | NodeKind::Instantiation | NodeKind::MatchKind | NodeKind::ErrorCst - | NodeKind::PreprocInclude - | NodeKind::PreprocDefine - | NodeKind::PreprocUndef | NodeKind::StateParser | NodeKind::ValueSet | NodeKind::ControlTable From 7fdf32f61fc281d7f59af9ebadf7484fd2f4b215 Mon Sep 17 00:00:00 2001 From: MaelC001 <55336346+MaelC001@users.noreply.github.com> Date: Wed, 12 Jul 2023 22:23:10 -0400 Subject: [PATCH 08/19] define in symbol table --- src/metadata/symbol_table.rs | 190 +++++++++++++++++++++++++++++++---- 1 file changed, 169 insertions(+), 21 deletions(-) diff --git a/src/metadata/symbol_table.rs b/src/metadata/symbol_table.rs index a0fffe7..33c6c5e 100644 --- a/src/metadata/symbol_table.rs +++ b/src/metadata/symbol_table.rs @@ -2,7 +2,7 @@ use crate::utils; use std::fmt; use crate::metadata::ast::{Ast, NodeKind, TypeDecType, VisitNode, Visitable}; -use crate::metadata::types::Type; +use crate::metadata::types::{Type, BaseType}; use indextree::{Arena, NodeId}; use std::sync::atomic::{AtomicUsize, Ordering}; use tower_lsp::lsp_types::{Position, Range}; @@ -25,6 +25,7 @@ pub trait SymbolTableActions { fn get_top_level_symbols(&self) -> Option; fn get_symbol_at_pos(&self, name: String, position: Position) -> Option<&Symbol>; fn get_symbol_at_pos_mut(&mut self, name: String, position: Position) -> Option<&mut Symbol>; + fn get_symbol_at_pos_mut_preproc(&mut self, name: String, position: Position) -> Option<&mut Symbol>; fn rename_symbol(&mut self, id: usize, new_name: String); } @@ -174,6 +175,25 @@ impl SymbolTableActions for SymbolTable { None } + fn get_symbol_at_pos_mut_preproc(&mut self, name: String, position: Position) -> Option<&mut Symbol> { + let scope_id = self.get_scope_id(position)?; + + for pre_id in scope_id.predecessors(&self.arena) { + let scope = self.arena.get(pre_id)?.get(); + + if scope.symbols.contains_preproc(&name) { + return self + .arena + .get_mut(pre_id)? + .get_mut() + .symbols + .find_mut(&name); + } + } + + None + } + fn get_symbol_at_pos(&self, name: String, position: Position) -> Option<&Symbol> { let scope_id = self.get_scope_id(position)?; @@ -196,7 +216,7 @@ impl SymbolTable { pub fn new(ast: &Ast) -> SymbolTable { let mut table = SymbolTable::default(); - table.root_id = Some(table.parse_scope(ast.visit_root()).unwrap()); + table.root_id = Some(table.parse_scope(ast.visit_root(), None).unwrap()); table.parse_usages(ast.visit_root()); table @@ -225,7 +245,7 @@ impl SymbolTable { self.root_id } - fn parse_scope(&mut self, visit_node: VisitNode) -> Option { + /*fn parse_scope(&mut self, visit_node: VisitNode) -> Option { let table_option = ScopeSymbolTable::parse(visit_node); if let Some(table) = table_option { let node_id = self.arena.new_node(table); @@ -244,6 +264,36 @@ impl SymbolTable { return Some(node_id); } None + }*/ + + fn parse_scope(&mut self, visit_node: VisitNode, last_node: Option) -> Option { + let table_option = ScopeSymbolTable::parse(visit_node); + + let mut node_id_t: Option = last_node; + let mut b = false; + + if let Some(table) = table_option{ + node_id_t = Some(self.arena.new_node(table)); + b = true; + } + + if let Some(node_id) = node_id_t{ + for child_visit in visit_node.get_children() { + //let child_visit_id = child_visit.get(); + //let kind = &child_visit_id.kind; + //if kind.is_scope_node() { + let subtable = self.parse_scope(child_visit, Some(node_id)); + if let Some(x) = subtable { + node_id.append(x, &mut self.arena); + } + //} + } + + if b{ + return Some(node_id); + } + } + None } fn get_value_symbol(&mut self, child_value: VisitNode, symbol: Symbol) { @@ -273,7 +323,37 @@ impl SymbolTable { if matches!(type_node.kind, NodeKind::Type(_)) { let used_type = type_node_visit.get_type().unwrap(); match used_type { - Type::Base(_) => {} + Type::Base(base_type) => { + match base_type { + BaseType::SizedInt(None) + | BaseType::SizedVarbit(None) + | BaseType::SizedBit(None) => { + if let Some(node_symbol_visit) = type_node_visit.get_child_of_kind(NodeKind::DefineSymbol){ + let node_symbol = node_symbol_visit.get(); + let name_symbol = node_symbol.content.clone(); + let pos_symbol = node_symbol.range.start; + + if let Some(symbol) = + self.get_symbol_at_pos_mut_preproc(name_symbol.clone(), pos_symbol) + { + if let Some(type_symbol) = symbol.type_.get_name(){ + if type_symbol == Type::Base(BaseType::Int){ + symbol.usages.push(node_symbol.range); + } else { + self.undefined_list.push(node_symbol.range) + } + } else { + self.undefined_list.push(node_symbol.range) + } + } else { + self.undefined_list.push(node_symbol.range) + } + } + }, + _ => {} + } + + } Type::Name => { let name_symbol = type_node.content.clone(); let pos_symbol = type_node.range.start; @@ -339,6 +419,7 @@ impl Symbols { self.constants.retain(|s| s.def_position.end < position); self.variables.retain(|s| s.def_position.end < position); self.functions.retain(|s| s.def_position.end < position); + self.preproc.retain(|s| s.def_position.end < position); } pub fn add(&mut self, mut other: Symbols, position: Position) { @@ -348,6 +429,7 @@ impl Symbols { self.constants.append(&mut other.constants); self.variables.append(&mut other.variables); self.functions.append(&mut other.functions); + self.preproc.append(&mut other.preproc); } pub fn contains(&self, name: &str) -> bool { @@ -371,6 +453,21 @@ impl Symbols { return true; } } + for symbol in &self.preproc { + if symbol.name == name { + return true; + } + } + + false + } + + pub fn contains_preproc(&self, name: &str) -> bool { + for symbol in &self.preproc { + if symbol.name == name { + return true; + } + } false } @@ -391,6 +488,11 @@ impl Symbols { return Some(symbol); } } + for symbol in &self.preproc { + if symbol.name == name { + return Some(symbol); + } + } self.functions.iter().find(|&symbol| symbol.name == name) } @@ -407,6 +509,9 @@ impl Symbols { if let Some(s) = self.functions.iter_mut().find(|symbol| symbol.name == name) { return Some(s); } + if let Some(s) = self.preproc.iter_mut().find(|symbol| symbol.name == name) { + return Some(s); + } None } @@ -424,6 +529,9 @@ impl Symbols { if let Some(s) = self.functions.iter_mut().find(|symbol| symbol.id == id) { return Some(s); } + if let Some(s) = self.preproc.iter_mut().find(|symbol| symbol.id == id) { + return Some(s); + } None } @@ -466,6 +574,10 @@ impl fmt::Display for ScopeSymbolTable { output.push_str(format!("{: <8} | {}\n", "function", s).as_str()); } + for s in &self.symbols.preproc { + output.push_str(format!("{: <8} | {}\n", "preproc", s).as_str()); + } + fmt.write_str(&output) } } @@ -476,17 +588,34 @@ impl ScopeSymbolTable { } fn parse(root_visit_node: VisitNode) -> Option { - fn _create_symbol_for_parse(child_visit_node: VisitNode, kind: NodeKind) -> Option { + fn _create_symbol_for_parse(child_visit_node: VisitNode, kind: NodeKind, value_type: bool) -> Option { if let Some(name_node) = child_visit_node.get_child_of_kind(kind) { + //debug!("{:?}",name_node); let name = name_node.get().content.clone(); - let type_node = child_visit_node.get_type_node(); let mut node: Option = None; - let type_ = if let Some(type_node) = type_node { - node = Some(type_node.get().clone()); - type_node.get_type() - } else { - None + let type_ = if value_type { + let type_node = child_visit_node.get_value_node(); + let mut temp : Option = None; + if let Some(value_node) = type_node { + for child in value_node.get_children(){ + let type_node= child.get(); + if let Some(x) = child.get_type(){ + node = Some(type_node.clone()); + temp = Some(x); + break + } + } + } + temp + } else{ + let type_node = child_visit_node.get_type_node(); + if let Some(type_node) = type_node { + node = Some(type_node.get().clone()); + type_node.get_type() + } else { + None + } }; return Some(Symbol::new( @@ -505,19 +634,19 @@ impl ScopeSymbolTable { match &child_node.kind { NodeKind::ConstantDec => { - if let Some(x) = _create_symbol_for_parse(child_visit_node, NodeKind::Name) + if let Some(x) = _create_symbol_for_parse(child_visit_node, NodeKind::Name, false) { table.symbols.constants.push(x); } } NodeKind::VariableDec => { - if let Some(x) = _create_symbol_for_parse(child_visit_node, NodeKind::Name) + if let Some(x) = _create_symbol_for_parse(child_visit_node, NodeKind::Name, false) { table.symbols.variables.push(x); } } NodeKind::PreprocDefine | NodeKind::PreprocInclude | NodeKind::PreprocUndef => { - if let Some(x) = _create_symbol_for_parse(child_visit_node, NodeKind::Name) + if let Some(x) = _create_symbol_for_parse(child_visit_node, NodeKind::Name, true) { table.symbols.preproc.push(x); } @@ -534,9 +663,9 @@ impl ScopeSymbolTable { | NodeKind::TableKw | NodeKind::Row | NodeKind::SwitchLabel => { - if let Some(x) = _create_symbol_for_parse(child_visit_node, NodeKind::Name) + if let Some(x) = _create_symbol_for_parse(child_visit_node, NodeKind::Name, false) { - table.symbols.constants.push(x); + table.symbols.functions.push(x); } } NodeKind::TypeDec(_type_dec_type) => { @@ -663,13 +792,13 @@ impl ScopeSymbolTable { } } NodeKind::Extern => { - if let Some(x) = _create_symbol_for_parse(child_visit_node, NodeKind::Name) + if let Some(x) = _create_symbol_for_parse(child_visit_node, NodeKind::Name, false) { table.symbols.functions.push(x); } else if let Some(fn_node) = root_visit_node.get_child_of_kind(NodeKind::FunctionName) { - if let Some(x) = _create_symbol_for_parse(fn_node, NodeKind::Name) { + if let Some(x) = _create_symbol_for_parse(fn_node, NodeKind::Name, false) { table.symbols.functions.push(x); } } @@ -678,7 +807,7 @@ impl ScopeSymbolTable { if let Some(fn_node) = root_visit_node.get_child_of_kind(NodeKind::FunctionName) { - if let Some(x) = _create_symbol_for_parse(fn_node, NodeKind::Name) { + if let Some(x) = _create_symbol_for_parse(fn_node, NodeKind::Name, false) { table.symbols.functions.push(x); } } @@ -688,7 +817,7 @@ impl ScopeSymbolTable { if let Some(fn_node) = child_child_visit_node.get_child_of_kind(NodeKind::FunctionName) { - if let Some(x) = _create_symbol_for_parse(fn_node, NodeKind::Name) { + if let Some(x) = _create_symbol_for_parse(fn_node, NodeKind::Name, false) { table.symbols.functions.push(x); } } @@ -699,6 +828,25 @@ impl ScopeSymbolTable { } } + fn do_loop_parse_general(root_visit_node: VisitNode, table: &mut ScopeSymbolTable) -> bool { + let mut b = false; + for child_visit_node in root_visit_node.get_children() { + let child_node = child_visit_node.get(); + + match &child_node.kind { + NodeKind::PreprocDefine | NodeKind::PreprocInclude | NodeKind::PreprocUndef => { + if let Some(x) = _create_symbol_for_parse(child_visit_node, NodeKind::Name, true) + { + table.symbols.preproc.push(x); + b = true; + } + } + _ => {} + } + } + return b + } + let root_visit_node_id = root_visit_node.get(); let mut table = ScopeSymbolTable { range: root_visit_node_id.range, @@ -722,7 +870,7 @@ impl ScopeSymbolTable { | NodeKind::SwitchLabel = &root_visit_node_id.kind { do_loop_parse(root_visit_node, &mut table); - } else { + } else if !do_loop_parse_general(root_visit_node, &mut table){ return None; } From 51a346fd56f12ec4cd0b84497525ae53fd595a95 Mon Sep 17 00:00:00 2001 From: MaelC001 <55336346+MaelC001@users.noreply.github.com> Date: Wed, 12 Jul 2023 22:36:41 -0400 Subject: [PATCH 09/19] prettier --- src/metadata/symbol_table.rs | 130 +++++++++++++++++++++-------------- 1 file changed, 77 insertions(+), 53 deletions(-) diff --git a/src/metadata/symbol_table.rs b/src/metadata/symbol_table.rs index 33c6c5e..68f28c1 100644 --- a/src/metadata/symbol_table.rs +++ b/src/metadata/symbol_table.rs @@ -2,7 +2,7 @@ use crate::utils; use std::fmt; use crate::metadata::ast::{Ast, NodeKind, TypeDecType, VisitNode, Visitable}; -use crate::metadata::types::{Type, BaseType}; +use crate::metadata::types::{BaseType, Type}; use indextree::{Arena, NodeId}; use std::sync::atomic::{AtomicUsize, Ordering}; use tower_lsp::lsp_types::{Position, Range}; @@ -25,7 +25,11 @@ pub trait SymbolTableActions { fn get_top_level_symbols(&self) -> Option; fn get_symbol_at_pos(&self, name: String, position: Position) -> Option<&Symbol>; fn get_symbol_at_pos_mut(&mut self, name: String, position: Position) -> Option<&mut Symbol>; - fn get_symbol_at_pos_mut_preproc(&mut self, name: String, position: Position) -> Option<&mut Symbol>; + fn get_symbol_at_pos_mut_preproc( + &mut self, + name: String, + position: Position, + ) -> Option<&mut Symbol>; fn rename_symbol(&mut self, id: usize, new_name: String); } @@ -175,7 +179,11 @@ impl SymbolTableActions for SymbolTable { None } - fn get_symbol_at_pos_mut_preproc(&mut self, name: String, position: Position) -> Option<&mut Symbol> { + fn get_symbol_at_pos_mut_preproc( + &mut self, + name: String, + position: Position, + ) -> Option<&mut Symbol> { let scope_id = self.get_scope_id(position)?; for pre_id in scope_id.predecessors(&self.arena) { @@ -268,28 +276,28 @@ impl SymbolTable { fn parse_scope(&mut self, visit_node: VisitNode, last_node: Option) -> Option { let table_option = ScopeSymbolTable::parse(visit_node); - + let mut node_id_t: Option = last_node; let mut b = false; - if let Some(table) = table_option{ + if let Some(table) = table_option { node_id_t = Some(self.arena.new_node(table)); b = true; } - if let Some(node_id) = node_id_t{ + if let Some(node_id) = node_id_t { for child_visit in visit_node.get_children() { //let child_visit_id = child_visit.get(); //let kind = &child_visit_id.kind; //if kind.is_scope_node() { - let subtable = self.parse_scope(child_visit, Some(node_id)); - if let Some(x) = subtable { - node_id.append(x, &mut self.arena); - } + let subtable = self.parse_scope(child_visit, Some(node_id)); + if let Some(x) = subtable { + node_id.append(x, &mut self.arena); + } //} } - if b{ + if b { return Some(node_id); } } @@ -323,37 +331,37 @@ impl SymbolTable { if matches!(type_node.kind, NodeKind::Type(_)) { let used_type = type_node_visit.get_type().unwrap(); match used_type { - Type::Base(base_type) => { - match base_type { - BaseType::SizedInt(None) - | BaseType::SizedVarbit(None) - | BaseType::SizedBit(None) => { - if let Some(node_symbol_visit) = type_node_visit.get_child_of_kind(NodeKind::DefineSymbol){ - let node_symbol = node_symbol_visit.get(); - let name_symbol = node_symbol.content.clone(); - let pos_symbol = node_symbol.range.start; - - if let Some(symbol) = - self.get_symbol_at_pos_mut_preproc(name_symbol.clone(), pos_symbol) - { - if let Some(type_symbol) = symbol.type_.get_name(){ - if type_symbol == Type::Base(BaseType::Int){ - symbol.usages.push(node_symbol.range); - } else { - self.undefined_list.push(node_symbol.range) - } + Type::Base(base_type) => match base_type { + BaseType::SizedInt(None) + | BaseType::SizedVarbit(None) + | BaseType::SizedBit(None) => { + if let Some(node_symbol_visit) = + type_node_visit.get_child_of_kind(NodeKind::DefineSymbol) + { + let node_symbol = node_symbol_visit.get(); + let name_symbol = node_symbol.content.clone(); + let pos_symbol = node_symbol.range.start; + + if let Some(symbol) = self.get_symbol_at_pos_mut_preproc( + name_symbol.clone(), + pos_symbol, + ) { + if let Some(type_symbol) = symbol.type_.get_name() { + if type_symbol == Type::Base(BaseType::Int) { + symbol.usages.push(node_symbol.range); } else { self.undefined_list.push(node_symbol.range) } } else { self.undefined_list.push(node_symbol.range) } + } else { + self.undefined_list.push(node_symbol.range) } - }, - _ => {} + } } - - } + _ => {} + }, Type::Name => { let name_symbol = type_node.content.clone(); let pos_symbol = type_node.range.start; @@ -588,7 +596,11 @@ impl ScopeSymbolTable { } fn parse(root_visit_node: VisitNode) -> Option { - fn _create_symbol_for_parse(child_visit_node: VisitNode, kind: NodeKind, value_type: bool) -> Option { + fn _create_symbol_for_parse( + child_visit_node: VisitNode, + kind: NodeKind, + value_type: bool, + ) -> Option { if let Some(name_node) = child_visit_node.get_child_of_kind(kind) { //debug!("{:?}",name_node); let name = name_node.get().content.clone(); @@ -596,19 +608,19 @@ impl ScopeSymbolTable { let mut node: Option = None; let type_ = if value_type { let type_node = child_visit_node.get_value_node(); - let mut temp : Option = None; + let mut temp: Option = None; if let Some(value_node) = type_node { - for child in value_node.get_children(){ - let type_node= child.get(); - if let Some(x) = child.get_type(){ + for child in value_node.get_children() { + let type_node = child.get(); + if let Some(x) = child.get_type() { node = Some(type_node.clone()); temp = Some(x); - break + break; } } - } + } temp - } else{ + } else { let type_node = child_visit_node.get_type_node(); if let Some(type_node) = type_node { node = Some(type_node.get().clone()); @@ -634,19 +646,22 @@ impl ScopeSymbolTable { match &child_node.kind { NodeKind::ConstantDec => { - if let Some(x) = _create_symbol_for_parse(child_visit_node, NodeKind::Name, false) + if let Some(x) = + _create_symbol_for_parse(child_visit_node, NodeKind::Name, false) { table.symbols.constants.push(x); } } NodeKind::VariableDec => { - if let Some(x) = _create_symbol_for_parse(child_visit_node, NodeKind::Name, false) + if let Some(x) = + _create_symbol_for_parse(child_visit_node, NodeKind::Name, false) { table.symbols.variables.push(x); } } NodeKind::PreprocDefine | NodeKind::PreprocInclude | NodeKind::PreprocUndef => { - if let Some(x) = _create_symbol_for_parse(child_visit_node, NodeKind::Name, true) + if let Some(x) = + _create_symbol_for_parse(child_visit_node, NodeKind::Name, true) { table.symbols.preproc.push(x); } @@ -663,7 +678,8 @@ impl ScopeSymbolTable { | NodeKind::TableKw | NodeKind::Row | NodeKind::SwitchLabel => { - if let Some(x) = _create_symbol_for_parse(child_visit_node, NodeKind::Name, false) + if let Some(x) = + _create_symbol_for_parse(child_visit_node, NodeKind::Name, false) { table.symbols.functions.push(x); } @@ -792,13 +808,16 @@ impl ScopeSymbolTable { } } NodeKind::Extern => { - if let Some(x) = _create_symbol_for_parse(child_visit_node, NodeKind::Name, false) + if let Some(x) = + _create_symbol_for_parse(child_visit_node, NodeKind::Name, false) { table.symbols.functions.push(x); } else if let Some(fn_node) = root_visit_node.get_child_of_kind(NodeKind::FunctionName) { - if let Some(x) = _create_symbol_for_parse(fn_node, NodeKind::Name, false) { + if let Some(x) = + _create_symbol_for_parse(fn_node, NodeKind::Name, false) + { table.symbols.functions.push(x); } } @@ -807,7 +826,9 @@ impl ScopeSymbolTable { if let Some(fn_node) = root_visit_node.get_child_of_kind(NodeKind::FunctionName) { - if let Some(x) = _create_symbol_for_parse(fn_node, NodeKind::Name, false) { + if let Some(x) = + _create_symbol_for_parse(fn_node, NodeKind::Name, false) + { table.symbols.functions.push(x); } } @@ -817,7 +838,9 @@ impl ScopeSymbolTable { if let Some(fn_node) = child_child_visit_node.get_child_of_kind(NodeKind::FunctionName) { - if let Some(x) = _create_symbol_for_parse(fn_node, NodeKind::Name, false) { + if let Some(x) = + _create_symbol_for_parse(fn_node, NodeKind::Name, false) + { table.symbols.functions.push(x); } } @@ -835,7 +858,8 @@ impl ScopeSymbolTable { match &child_node.kind { NodeKind::PreprocDefine | NodeKind::PreprocInclude | NodeKind::PreprocUndef => { - if let Some(x) = _create_symbol_for_parse(child_visit_node, NodeKind::Name, true) + if let Some(x) = + _create_symbol_for_parse(child_visit_node, NodeKind::Name, true) { table.symbols.preproc.push(x); b = true; @@ -844,7 +868,7 @@ impl ScopeSymbolTable { _ => {} } } - return b + return b; } let root_visit_node_id = root_visit_node.get(); @@ -870,7 +894,7 @@ impl ScopeSymbolTable { | NodeKind::SwitchLabel = &root_visit_node_id.kind { do_loop_parse(root_visit_node, &mut table); - } else if !do_loop_parse_general(root_visit_node, &mut table){ + } else if !do_loop_parse_general(root_visit_node, &mut table) { return None; } From 08a547dc3844def2c6b82b8589e46992759d5ff8 Mon Sep 17 00:00:00 2001 From: MaelC001 <55336346+MaelC001@users.noreply.github.com> Date: Thu, 13 Jul 2023 14:18:01 -0400 Subject: [PATCH 10/19] find every define in cst for the ast --- src/features/goto.rs | 1 + src/metadata/ast/translator.rs | 635 ++++++++++++++++++++++++++------- src/metadata/symbol_table.rs | 1 + 3 files changed, 500 insertions(+), 137 deletions(-) diff --git a/src/features/goto.rs b/src/features/goto.rs index 2ec353d..90054ce 100644 --- a/src/features/goto.rs +++ b/src/features/goto.rs @@ -8,6 +8,7 @@ pub fn get_definition_range( symbol_table_query: &Arc>, position: Position, ) -> Option { + // Todo - change for define let ast_query = ast_query.lock().unwrap(); let root_visit = ast_query.visit_root(); let node = root_visit.get_node_at_position(position)?; diff --git a/src/metadata/ast/translator.rs b/src/metadata/ast/translator.rs index 9e5e149..608543d 100644 --- a/src/metadata/ast/translator.rs +++ b/src/metadata/ast/translator.rs @@ -88,6 +88,8 @@ impl TreesitterTranslator { for child in node.named_children(&mut cursor) { if child.is_error() { node_id.append(self.new_error_node(&child), &mut self.arena); + } else if let Some(t) = self.look_for_preproc_kind(&child) { + node_id.append(t, &mut self.arena); } else { let child_node_id = self.arena @@ -121,6 +123,10 @@ impl TreesitterTranslator { ); } + for node_preproc in self.look_for_preproc(&child) { + child_node_id.append(node_preproc, &mut self.arena); + } + node_id.append(child_node_id, &mut self.arena); } } @@ -174,6 +180,10 @@ impl TreesitterTranslator { &mut self.arena, ); } + + for node_preproc in self.look_for_preproc(&node) { + node_id.append(node_preproc, &mut self.arena); + } //node_id.append(self.parse_type_options_dec(&option_list_node).unwrap_or_else(|| self.new_error_node(&option_list_node)), &mut self.arena); Some(node_id) @@ -187,11 +197,24 @@ impl TreesitterTranslator { let mut cursor = node_param_type.walk(); for child in node_param_type.named_children(&mut cursor) { - let child_id = - self.arena - .new_node(Node::new(NodeKind::Name, &child, &self.source_code)); - node_param_type_id.append(child_id, &mut self.arena); + if child.kind() == "preproc_include_declaration" { + if let Some(t) = self.parse_preproc_include(&child) { + node_param_type_id.append(t, &mut self.arena); + } + } else if let Some(t) = self.look_for_preproc_kind(&child) { + node_param_type_id.append(t, &mut self.arena); + } else { + let child_id = + self.arena + .new_node(Node::new(NodeKind::Name, &child, &self.source_code)); + node_param_type_id.append(child_id, &mut self.arena); + } + } + + for node_preproc in self.look_for_preproc(&node) { + node_param_type_id.append(node_preproc, &mut self.arena); } + Some(node_param_type_id) } fn parse_error(&mut self, node: &tree_sitter::Node) -> Option { @@ -216,6 +239,10 @@ impl TreesitterTranslator { &mut self.arena, ); + for node_preproc in self.look_for_preproc(&node) { + node_id.append(node_preproc, &mut self.arena); + } + Some(node_id) } fn parse_match_kind(&mut self, node: &tree_sitter::Node) -> Option { @@ -240,9 +267,49 @@ impl TreesitterTranslator { &mut self.arena, ); + for node_preproc in self.look_for_preproc(&node) { + node_id.append(node_preproc, &mut self.arena); + } + Some(node_id) } + fn look_for_preproc_kind(&mut self, node: &tree_sitter::Node) -> Option { + let kind = node.kind(); + if kind == "preproc_include_declaration" { + return self.parse_preproc_include(&node); + } else if kind == "preproc_define_declaration" || kind == "preproc_define_declaration_macro" + { + return self.parse_preproc_define(&node); + } else if kind == "preproc_undef_declaration" { + return self.parse_preproc_undef(&node); + } + None + } + + fn look_for_preproc(&mut self, node: &tree_sitter::Node) -> Vec { + let mut vec_node: Vec = vec![]; + + let mut cursor = node.walk(); + for child in node.named_children(&mut cursor) { + debug!("{:?}", child); + let new_child = match child.kind() { + "preproc_include_declaration" => self.parse_preproc_include(&child), + "preproc_define_declaration" | "preproc_define_declaration_macro" => { + self.parse_preproc_define(&child) + } + "preproc_undef_declaration" => self.parse_preproc_undef(&child), + _ => None, + }; + + if let Some(new_child) = new_child { + vec_node.push(new_child); + } + } + + vec_node + } + fn parse_preproc_include(&mut self, node: &tree_sitter::Node) -> Option { let node_id = self.arena @@ -325,6 +392,8 @@ impl TreesitterTranslator { for syntax_child in node.named_children(&mut cursor) { if syntax_child.is_error() { params_node_id.append(self.new_error_node(&syntax_child), &mut self.arena); + } else if let Some(t) = self.look_for_preproc_kind(&syntax_child) { + params_node_id.append(t, &mut self.arena); } else if syntax_child.kind() == "identifier" { let param_node_id = self.arena.new_node(Node::new( NodeKind::Param, @@ -335,6 +404,11 @@ impl TreesitterTranslator { params_node_id.append(param_node_id, &mut self.arena); } } + + for node_preproc in self.look_for_preproc(&node) { + params_node_id.append(node_preproc, &mut self.arena); + } + Some(params_node_id) } fn parse_preproc_undef(&mut self, node: &tree_sitter::Node) -> Option { @@ -408,10 +482,15 @@ impl TreesitterTranslator { &mut self.arena, ); + for node_preproc in self.look_for_preproc(&node) { + node_id.append(node_preproc, &mut self.arena); + } + Some(node_id) } fn parse_value(&mut self, node: &tree_sitter::Node) -> Option { + // todo-preproc fn loop_value( node_value: &mut NodeId, last_node: NodeId, @@ -865,6 +944,12 @@ impl TreesitterTranslator { } } } + for node_preproc in self.look_for_preproc(&node) { + node_id.append(node_preproc, &mut self.arena); + } + for node_preproc in self.look_for_preproc(&type_kind_node) { + node_id.append(node_preproc, &mut self.arena); + } Some(node_id) } @@ -878,6 +963,8 @@ impl TreesitterTranslator { for field_child in node.named_children(&mut cursor) { if field_child.is_error() { fields_node_id.append(self.new_error_node(&field_child), &mut self.arena); + } else if let Some(t) = self.look_for_preproc_kind(&field_child) { + fields_node_id.append(t, &mut self.arena); } else if field_child.kind() == "struct_field" { let field_node_id = self.arena.new_node(Node::new( NodeKind::Field, @@ -926,6 +1013,8 @@ impl TreesitterTranslator { for option_child in node.named_children(&mut cursor) { let new_node_id = if option_child.is_error() { self.new_error_node(&option_child) + } else if let Some(t) = self.look_for_preproc_kind(&option_child) { + t } else { //let node_text = utils::get_node_text(&option_child, &self.source_code); //let text = node_text.as_str().trim(); @@ -968,7 +1057,7 @@ impl TreesitterTranslator { child = node.clone(); } - let node: Option = match child.kind() { + let node_id: Option = match child.kind() { "base_type" => { let node_text = utils::get_node_text(&child, &self.source_code); let text = node_text.as_str().trim(); @@ -1011,6 +1100,7 @@ impl TreesitterTranslator { ))), _ => { let child_child = child.named_child(0).unwrap(); + let mut node_id: Option = None; if child_child.kind() == "integer" { let size = Some( utils::get_node_text(&child_child, &self.source_code) @@ -1019,19 +1109,19 @@ impl TreesitterTranslator { ); if text.starts_with("int") { - return Some(self.arena.new_node(Node::new( + node_id = Some(self.arena.new_node(Node::new( n_kind(Type::Base(BaseType::SizedInt(size))), node, &self.source_code, ))); } else if text.starts_with("bit") { - return Some(self.arena.new_node(Node::new( + node_id = Some(self.arena.new_node(Node::new( n_kind(Type::Base(BaseType::SizedBit(size))), node, &self.source_code, ))); } else if text.starts_with("varbit") { - return Some(self.arena.new_node(Node::new( + node_id = Some(self.arena.new_node(Node::new( n_kind(Type::Base(BaseType::SizedVarbit(size))), node, &self.source_code, @@ -1068,7 +1158,7 @@ impl TreesitterTranslator { node_return.append( self.arena.new_node(Node::new( NodeKind::DefineSymbol, - node, + &child_child, &self.source_code, )), &mut self.arena, @@ -1077,9 +1167,17 @@ impl TreesitterTranslator { node_return .append(self.parse_value(&child_child)?, &mut self.arena); } - return Some(node_return); + + node_id = Some(node_return); + } + if let Some(t) = node_id { + for node_preproc in self.look_for_preproc(&child_child) { + t.append(node_preproc, &mut self.arena); + } + Some(t) + } else { + node_id } - None } } } @@ -1106,7 +1204,19 @@ impl TreesitterTranslator { _ => None, }; - node + if let Some(node_id_t) = node_id { + for node_preproc in self.look_for_preproc(&node) { + node_id_t.append(node_preproc, &mut self.arena); + } + if child_bool { + for node_preproc in self.look_for_preproc(&child) { + node_id_t.append(node_preproc, &mut self.arena); + } + } + return Some(node_id_t); + } + + node_id } fn parse_parser(&mut self, node: &tree_sitter::Node) -> Option { @@ -1167,6 +1277,12 @@ impl TreesitterTranslator { // parser_state "parser_state" => self.parse_state(&syntax_child), + + "preproc_include_declaration" => self.parse_preproc_include(&syntax_child), + "preproc_define_declaration" | "preproc_define_declaration_macro" => { + self.parse_preproc_define(&syntax_child) + } + "preproc_undef_declaration" => self.parse_preproc_undef(&syntax_child), _ => None, } }; @@ -1177,6 +1293,16 @@ impl TreesitterTranslator { } node_id.append(body_node_id, &mut self.arena); + for node_preproc in self.look_for_preproc(&node) { + node_id.append(node_preproc, &mut self.arena); + } + for node_preproc in self.look_for_preproc(&declaration_body) { + node_id.append(node_preproc, &mut self.arena); + } + for node_preproc in self.look_for_preproc(&body_syntax_node) { + node_id.append(node_preproc, &mut self.arena); + } + Some(node_id) } @@ -1237,6 +1363,12 @@ impl TreesitterTranslator { "table_declaration" => self.parse_control_table(&syntax_child), "block_statement" => self.parse_block(&syntax_child), + + "preproc_include_declaration" => self.parse_preproc_include(&syntax_child), + "preproc_define_declaration" | "preproc_define_declaration_macro" => { + self.parse_preproc_define(&syntax_child) + } + "preproc_undef_declaration" => self.parse_preproc_undef(&syntax_child), _ => None, } }; @@ -1247,6 +1379,13 @@ impl TreesitterTranslator { } node_id.append(body_node_id, &mut self.arena); + for node_preproc in self.look_for_preproc(&node) { + node_id.append(node_preproc, &mut self.arena); + } + for node_preproc in self.look_for_preproc(&declaration_body) { + node_id.append(node_preproc, &mut self.arena); + } + Some(node_id) } @@ -1260,6 +1399,8 @@ impl TreesitterTranslator { //debug!("a,{:?}",syntax_child); if syntax_child.is_error() { params_node_id.append(self.new_error_node(&syntax_child), &mut self.arena); + } else if let Some(t) = self.look_for_preproc_kind(&syntax_child) { + params_node_id.append(t, &mut self.arena); } else if syntax_child.kind() == "parameter" { let param_node_id = self.arena.new_node(Node::new( NodeKind::Param, @@ -1326,6 +1467,8 @@ impl TreesitterTranslator { //debug!("a,{:?}",syntax_child); if syntax_child.is_error() { params_node_id.append(self.new_error_node(&syntax_child), &mut self.arena); + } else if let Some(t) = self.look_for_preproc_kind(&syntax_child) { + params_node_id.append(t, &mut self.arena); } else if syntax_child.kind() == "argument" { let param_node_id = self.arena @@ -1369,6 +1512,12 @@ impl TreesitterTranslator { match syntax_child.kind() { "function_declaration" => self.function_declaration(&syntax_child), "instantiation" => self.instantiation(&syntax_child), + + "preproc_include_declaration" => self.parse_preproc_include(&syntax_child), + "preproc_define_declaration" | "preproc_define_declaration_macro" => { + self.parse_preproc_define(&syntax_child) + } + "preproc_undef_declaration" => self.parse_preproc_undef(&syntax_child), _ => None, } }; @@ -1392,6 +1541,10 @@ impl TreesitterTranslator { fn_node_id.append(x, &mut self.arena); } + for node_preproc in self.look_for_preproc(&node) { + fn_node_id.append(node_preproc, &mut self.arena); + } + Some(fn_node_id) } fn function_prototype(&mut self, node: &tree_sitter::Node) -> Option { @@ -1427,6 +1580,13 @@ impl TreesitterTranslator { ); } + for node_preproc in self.look_for_preproc(&node) { + fn_node_id.append(node_preproc, &mut self.arena); + } + for node_preproc in self.look_for_preproc(&type_node) { + fn_node_id.append(node_preproc, &mut self.arena); + } + Some(fn_node_id) } fn parse_block(&mut self, node: &tree_sitter::Node) -> Option { @@ -1461,6 +1621,12 @@ impl TreesitterTranslator { "exit_statement" => None, "return_statement" => self.return_statement(&syntax_child), "switch_statement" => self.switch_statement(&syntax_child), + + "preproc_include_declaration" => self.parse_preproc_include(&syntax_child), + "preproc_define_declaration" | "preproc_define_declaration_macro" => { + self.parse_preproc_define(&syntax_child) + } + "preproc_undef_declaration" => self.parse_preproc_undef(&syntax_child), _ => None, } }; @@ -1469,10 +1635,15 @@ impl TreesitterTranslator { } } + for node_preproc in self.look_for_preproc(&node) { + block_node_id.append(node_preproc, &mut self.arena); + } + Some(block_node_id) } fn parse_direction(&mut self, node: &tree_sitter::Node) -> Option { + // not preproc let dir = match utils::get_node_text(node, &self.source_code).as_str() { "in" => Direction::In, "out" => Direction::Out, @@ -1527,6 +1698,10 @@ impl TreesitterTranslator { ); } + for node_preproc in self.look_for_preproc(&node) { + node_id.append(node_preproc, &mut self.arena); + } + Some(node_id) } fn parse_name_assignment(&mut self, node_t: &tree_sitter::Node) -> Option { @@ -1627,6 +1802,33 @@ impl TreesitterTranslator { bool = false; } } + "preproc_include_declaration" => { + if let Some(t) = self.parse_preproc_include(&node) { + if let Some(x) = last_node { + x.append(t, &mut self.arena); + } else { + last_node = Some(t); + } + } + } + "preproc_define_declaration" | "preproc_define_declaration_macro" => { + if let Some(t) = self.parse_preproc_define(&node) { + if let Some(x) = last_node { + x.append(t, &mut self.arena); + } else { + last_node = Some(t); + } + } + } + "preproc_undef_declaration" => { + if let Some(t) = self.parse_preproc_undef(&node) { + if let Some(x) = last_node { + x.append(t, &mut self.arena); + } else { + last_node = Some(t); + } + } + } _ => { bool = false; } @@ -1643,6 +1845,10 @@ impl TreesitterTranslator { name_node.append(new_child, &mut self.arena); } + for node_preproc in self.look_for_preproc(&node_first) { + name_node.append(node_preproc, &mut self.arena); + } + Some(name_node) } fn parse_state_assignment(&mut self, node: &tree_sitter::Node) -> Option { @@ -1682,6 +1888,8 @@ impl TreesitterTranslator { for syntax_child in param_list.named_children(&mut cursor) { let child_node_id = if syntax_child.is_error() { Some(self.new_error_node(&syntax_child)) + } else if let Some(t) = self.look_for_preproc_kind(&syntax_child) { + Some(t) } else { match syntax_child.named_child(0)?.kind() { "type_ref" => self.parse_type_ref(&syntax_child, NodeKind::TypeList, true), @@ -1690,6 +1898,12 @@ impl TreesitterTranslator { node, &self.source_code, ))), + + "preproc_include_declaration" => self.parse_preproc_include(&syntax_child), + "preproc_define_declaration" | "preproc_define_declaration_macro" => { + self.parse_preproc_define(&syntax_child) + } + "preproc_undef_declaration" => self.parse_preproc_undef(&syntax_child), _ => Some(self.new_error_node(&syntax_child)), } }; @@ -1701,6 +1915,10 @@ impl TreesitterTranslator { node_id.append(params_node_id, &mut self.arena); } + for node_preproc in self.look_for_preproc(&node) { + node_id.append(node_preproc, &mut self.arena); + } + Some(node_id) } fn parse_state_direct(&mut self, node: &tree_sitter::Node) -> Option { @@ -1745,6 +1963,10 @@ impl TreesitterTranslator { node_id.append(params_node_id, &mut self.arena); } + for node_preproc in self.look_for_preproc(&node) { + node_id.append(node_preproc, &mut self.arena); + } + Some(node_id) } fn parse_state_block(&mut self, node: &tree_sitter::Node) -> Option { @@ -1776,6 +1998,12 @@ impl TreesitterTranslator { "variable_declaration" => self.parse_var_dec(&body_child), "empty_statement" => None, "conditional_statement" => self.parse_state_conditional(&body_child), + + "preproc_include_declaration" => self.parse_preproc_include(&body_child), + "preproc_define_declaration" | "preproc_define_declaration_macro" => { + self.parse_preproc_define(&body_child) + } + "preproc_undef_declaration" => self.parse_preproc_undef(&body_child), _ => None, } }; @@ -1785,6 +2013,10 @@ impl TreesitterTranslator { } } + for node_preproc in self.look_for_preproc(&node) { + node_id.append(node_preproc, &mut self.arena); + } + Some(node_id) } @@ -1833,6 +2065,10 @@ impl TreesitterTranslator { ); } + for node_preproc in self.look_for_preproc(&node) { + node_id.append(node_preproc, &mut self.arena); + } + Some(node_id) } fn fn_statement(&mut self, node: tree_sitter::Node<'_>, type_node: NodeKind) -> Option { @@ -1857,6 +2093,12 @@ impl TreesitterTranslator { "exit_statement" => None, "return_statement" => self.return_statement(&body_child), "switch_statement" => self.switch_statement(&body_child), + + "preproc_include_declaration" => self.parse_preproc_include(&body_child), + "preproc_define_declaration" | "preproc_define_declaration_macro" => { + self.parse_preproc_define(&body_child) + } + "preproc_undef_declaration" => self.parse_preproc_undef(&body_child), _ => None, } }; @@ -1866,6 +2108,10 @@ impl TreesitterTranslator { } } + for node_preproc in self.look_for_preproc(&node) { + node_id.append(node_preproc, &mut self.arena); + } + Some(node_id) } fn return_statement(&mut self, node: &tree_sitter::Node) -> Option { @@ -1889,6 +2135,11 @@ impl TreesitterTranslator { ); return Some(node_id); } + + for node_preproc in self.look_for_preproc(&node) { + node_id.append(node_preproc, &mut self.arena); + } + None } fn switch_statement(&mut self, node: &tree_sitter::Node) -> Option { @@ -1918,6 +2169,8 @@ impl TreesitterTranslator { for body_child in body_node.named_children(&mut cursor) { if body_child.is_error() { node_id.append(self.new_error_node(&body_child), &mut self.arena); + } else if let Some(t) = self.look_for_preproc_kind(&body_child) { + node_id.append(t, &mut self.arena); } else if body_child.kind() == "switch_case" { let label: NodeId = self.arena @@ -1940,6 +2193,10 @@ impl TreesitterTranslator { } } + for node_preproc in self.look_for_preproc(&node) { + node_id.append(node_preproc, &mut self.arena); + } + Some(node_id) } @@ -1989,6 +2246,10 @@ impl TreesitterTranslator { &mut self.arena, ); + for node_preproc in self.look_for_preproc(&node) { + node_id.append(node_preproc, &mut self.arena); + } + Some(node_id) } @@ -2035,6 +2296,10 @@ impl TreesitterTranslator { node_id.append(params_node_id, &mut self.arena); } + for node_preproc in self.look_for_preproc(&node) { + node_id.append(node_preproc, &mut self.arena); + } + Some(node_id) } fn parse_control_action(&mut self, node: &tree_sitter::Node) -> Option { @@ -2080,6 +2345,10 @@ impl TreesitterTranslator { .unwrap_or_else(|| self.new_error_node(&block_syntax_node)); node_id.append(block_node_id, &mut self.arena); + for node_preproc in self.look_for_preproc(&node) { + node_id.append(node_preproc, &mut self.arena); + } + Some(node_id) } @@ -2135,38 +2404,48 @@ impl TreesitterTranslator { )); let mut cursor = keys.walk(); for keys_child in keys.named_children(&mut cursor) { - // Add name node - let key_node_id = self.arena.new_node(Node::new( - NodeKind::Key, - &keys_child, - &self.source_code, - )); - // Add annotation node - if let Some(annotation) = keys_child.child_by_field_name("annotation") { + if keys_child.is_error() { + keys_node_id + .append(self.new_error_node(&keys_child), &mut self.arena); + } else if let Some(t) = self.look_for_preproc_kind(&keys_child) { + keys_node_id.append(t, &mut self.arena); + } else { + // Add name node + let key_node_id = self.arena.new_node(Node::new( + NodeKind::Key, + &keys_child, + &self.source_code, + )); + // Add annotation node + if let Some(annotation) = + keys_child.child_by_field_name("annotation") + { + key_node_id.append( + self.parse_annotation(&annotation) + .unwrap_or_else(|| self.new_error_node(&annotation)), + &mut self.arena, + ); + } + + // Add name node + let name_node = self.arena.new_node(Node::new( + NodeKind::Name, + &keys_child.child_by_field_name("name").unwrap(), + &self.source_code, + )); + key_node_id.append(name_node, &mut self.arena); + + // Add value node + let value_node = + keys_child.child_by_field_name("expression").unwrap(); key_node_id.append( - self.parse_annotation(&annotation) - .unwrap_or_else(|| self.new_error_node(&annotation)), + self.parse_value(&value_node) + .unwrap_or_else(|| self.new_error_node(&value_node)), &mut self.arena, ); - } - - // Add name node - let name_node = self.arena.new_node(Node::new( - NodeKind::Name, - &keys_child.child_by_field_name("name").unwrap(), - &self.source_code, - )); - key_node_id.append(name_node, &mut self.arena); - - // Add value node - let value_node = keys_child.child_by_field_name("expression").unwrap(); - key_node_id.append( - self.parse_value(&value_node) - .unwrap_or_else(|| self.new_error_node(&value_node)), - &mut self.arena, - ); - keys_node_id.append(key_node_id, &mut self.arena); + keys_node_id.append(key_node_id, &mut self.arena); + } } child_node_id = Some(keys_node_id); } @@ -2179,39 +2458,47 @@ impl TreesitterTranslator { )); let mut cursor = actions.walk(); for actions_child in actions.named_children(&mut cursor) { - // Add name node - let action_node_id = self.arena.new_node(Node::new( - NodeKind::Action, - &actions_child, - &self.source_code, - )); - // Add annotation node - if let Some(annotation) = - actions_child.child_by_field_name("annotation") - { - action_node_id.append( - self.parse_annotation(&annotation) - .unwrap_or_else(|| self.new_error_node(&annotation)), - &mut self.arena, - ); - } + if actions_child.is_error() { + actions_node_id + .append(self.new_error_node(&actions_child), &mut self.arena); + } else if let Some(t) = self.look_for_preproc_kind(&actions_child) { + actions_node_id.append(t, &mut self.arena); + } else { + // Add name node + let action_node_id = self.arena.new_node(Node::new( + NodeKind::Action, + &actions_child, + &self.source_code, + )); + // Add annotation node + if let Some(annotation) = + actions_child.child_by_field_name("annotation") + { + action_node_id.append( + self.parse_annotation(&annotation) + .unwrap_or_else(|| self.new_error_node(&annotation)), + &mut self.arena, + ); + } - // Add name node - let name_node = self.arena.new_node(Node::new( - NodeKind::Type(Type::Name), - &actions_child.child_by_field_name("name").unwrap(), - &self.source_code, - )); - action_node_id.append(name_node, &mut self.arena); + // Add name node + let name_node = self.arena.new_node(Node::new( + NodeKind::Type(Type::Name), + &actions_child.child_by_field_name("name").unwrap(), + &self.source_code, + )); + action_node_id.append(name_node, &mut self.arena); + + if let Some(params_syntax_node) = node.child_by_field_name("args") { + let params_node_id = + self.parse_args(¶ms_syntax_node).unwrap_or_else(|| { + self.new_error_node(¶ms_syntax_node) + }); + node_id.append(params_node_id, &mut self.arena); + } - if let Some(params_syntax_node) = node.child_by_field_name("args") { - let params_node_id = self - .parse_args(¶ms_syntax_node) - .unwrap_or_else(|| self.new_error_node(¶ms_syntax_node)); - node_id.append(params_node_id, &mut self.arena); + actions_node_id.append(action_node_id, &mut self.arena); } - - actions_node_id.append(action_node_id, &mut self.arena); } child_node_id = Some(actions_node_id); } @@ -2224,71 +2511,81 @@ impl TreesitterTranslator { )); let mut cursor = entries.walk(); for entries_child in entries.named_children(&mut cursor) { - // Add name node - let entrie_node_id = self.arena.new_node(Node::new( - NodeKind::Entrie, - &entries_child, - &self.source_code, - )); - // Add annotation node - if let Some(annotation) = - entries_child.child_by_field_name("annotation") - { - entrie_node_id.append( - self.parse_annotation(&annotation) - .unwrap_or_else(|| self.new_error_node(&annotation)), - &mut self.arena, - ); - } - - // Add name node - let name_node = self.arena.new_node(Node::new( - NodeKind::Name, - &entries_child.child_by_field_name("name").unwrap(), - &self.source_code, - )); - entrie_node_id.append(name_node, &mut self.arena); + if entries_child.is_error() { + entries_node_id + .append(self.new_error_node(&entries_child), &mut self.arena); + } else if let Some(t) = self.look_for_preproc_kind(&entries_child) { + entries_node_id.append(t, &mut self.arena); + } else { + // Add name node + let entrie_node_id = self.arena.new_node(Node::new( + NodeKind::Entrie, + &entries_child, + &self.source_code, + )); + // Add annotation node + if let Some(annotation) = + entries_child.child_by_field_name("annotation") + { + entrie_node_id.append( + self.parse_annotation(&annotation) + .unwrap_or_else(|| self.new_error_node(&annotation)), + &mut self.arena, + ); + } - if let Some(params_syntax_node) = node.child_by_field_name("args") { - let params_node_id = self - .parse_args(¶ms_syntax_node) - .unwrap_or_else(|| self.new_error_node(¶ms_syntax_node)); - node_id.append(params_node_id, &mut self.arena); - } + // Add name node + let name_node = self.arena.new_node(Node::new( + NodeKind::Name, + &entries_child.child_by_field_name("name").unwrap(), + &self.source_code, + )); + entrie_node_id.append(name_node, &mut self.arena); + + if let Some(params_syntax_node) = node.child_by_field_name("args") { + let params_node_id = + self.parse_args(¶ms_syntax_node).unwrap_or_else(|| { + self.new_error_node(¶ms_syntax_node) + }); + node_id.append(params_node_id, &mut self.arena); + } - // _keyset_expression - if let Some(x) = entries_child.named_child(0) { - if x.kind() == "tuple_keyset_expression" { - if let Some(y) = x.child_by_field_name("reduce") { - entrie_node_id.append( - self.parse_reduced_simple_keyset_expression(&y) - .unwrap_or_else(|| self.new_error_node(&y)), - &mut self.arena, - ); - } else { - let t = x.named_child(0)?; - let tt = x.named_child(1)?; - entrie_node_id.append( - self.parse_simple_keyset_expression(&t) - .unwrap_or_else(|| self.new_error_node(&t)), - &mut self.arena, - ); + // _keyset_expression + if let Some(x) = entries_child.named_child(0) { + if x.kind() == "tuple_keyset_expression" { + if let Some(y) = x.child_by_field_name("reduce") { + entrie_node_id.append( + self.parse_reduced_simple_keyset_expression(&y) + .unwrap_or_else(|| self.new_error_node(&y)), + &mut self.arena, + ); + } else { + let t = x.named_child(0)?; + let tt = x.named_child(1)?; + entrie_node_id.append( + self.parse_simple_keyset_expression(&t) + .unwrap_or_else(|| self.new_error_node(&t)), + &mut self.arena, + ); + entrie_node_id.append( + self.parse_simple_expression_list(&tt) + .unwrap_or_else(|| self.new_error_node(&tt)), + &mut self.arena, + ); + } + } else if x.kind() == "simple_keyset_expression" { entrie_node_id.append( - self.parse_simple_expression_list(&tt) - .unwrap_or_else(|| self.new_error_node(&tt)), + self.parse_simple_keyset_expression(&x) + .unwrap_or_else(|| self.new_error_node(&x)), &mut self.arena, ); + } else if let Some(t) = self.look_for_preproc_kind(&x) { + entrie_node_id.append(t, &mut self.arena); } - } else if x.kind() == "simple_keyset_expression" { - entrie_node_id.append( - self.parse_simple_keyset_expression(&x) - .unwrap_or_else(|| self.new_error_node(&x)), - &mut self.arena, - ); } - } - entries_node_id.append(entrie_node_id, &mut self.arena); + entries_node_id.append(entrie_node_id, &mut self.arena); + } } child_node_id = Some(entries_node_id); } @@ -2319,6 +2616,16 @@ impl TreesitterTranslator { } child_node_id = Some(table_kw_node_id); } + + "preproc_include_declaration" => { + child_node_id = self.parse_preproc_include(&table_child) + } + "preproc_define_declaration" | "preproc_define_declaration_macro" => { + child_node_id = self.parse_preproc_define(&table_child) + } + "preproc_undef_declaration" => { + child_node_id = self.parse_preproc_undef(&table_child) + } _ => {} } } @@ -2360,6 +2667,10 @@ impl TreesitterTranslator { node_id.append(table_node_id, &mut self.arena); + for node_preproc in self.look_for_preproc(&node) { + node_id.append(node_preproc, &mut self.arena); + } + Some(node_id) } @@ -2415,6 +2726,12 @@ impl TreesitterTranslator { "variable_declaration" => self.parse_var_dec(&body_child), "empty_statement" => None, "conditional_statement" => self.parse_state_conditional(&body_child), + + "preproc_include_declaration" => self.parse_preproc_include(&body_child), + "preproc_define_declaration" | "preproc_define_declaration_macro" => { + self.parse_preproc_define(&body_child) + } + "preproc_undef_declaration" => self.parse_preproc_undef(&body_child), _ => None, } }; @@ -2424,6 +2741,10 @@ impl TreesitterTranslator { } } } + for node_preproc in self.look_for_preproc(&body_node) { + value_node.append(node_preproc, &mut self.arena); + } + node_id.append(value_node, &mut self.arena); if let Some(transition_statement) = body_node.child_by_field_name("transition_statement") { @@ -2490,6 +2811,8 @@ impl TreesitterTranslator { if body_child.is_error() { expression_body_node .append(self.new_error_node(&body_child), &mut self.arena); + } else if let Some(t) = self.look_for_preproc_kind(&body_child) { + expression_body_node.append(t, &mut self.arena); } else if body_child.kind() == "select_case" { let t = self.arena.new_node(Node::new( NodeKind::Row, @@ -2510,6 +2833,7 @@ impl TreesitterTranslator { } if let Some(x) = body_child.child_by_field_name("type") { + // todo - preproc if x.kind() == "tuple_keyset_expression" { if let Some(y) = x.child_by_field_name("reduce") { transition_node.append( @@ -2544,11 +2868,18 @@ impl TreesitterTranslator { } transition_node.append(expression_body_node, &mut self.arena); } + for node_preproc in self.look_for_preproc(&transition_statement) { + transition_node.append(node_preproc, &mut self.arena); + } } node_id.append(transition_node, &mut self.arena); } + for node_preproc in self.look_for_preproc(&node) { + node_id.append(node_preproc, &mut self.arena); + } + Some(node_id) } @@ -2561,6 +2892,8 @@ impl TreesitterTranslator { for child in node.named_children(&mut cursor) { if child.is_error() { node_id.append(self.new_error_node(&child), &mut self.arena); + } else if let Some(t) = self.look_for_preproc_kind(&child) { + node_id.append(t, &mut self.arena); } else { let child_node_id = self.arena @@ -2595,6 +2928,8 @@ impl TreesitterTranslator { .unwrap_or_else(|| self.new_error_node(&struct_body)), &mut self.arena, ); + } else if let Some(t) = self.look_for_preproc_kind(&struct_body) { + child_node_id.append(t, &mut self.arena); } } @@ -2614,6 +2949,8 @@ impl TreesitterTranslator { for child in node.named_children(&mut cursor) { if child.is_error() { node_id.append(self.new_error_node(&child), &mut self.arena); + } else if let Some(t) = self.look_for_preproc_kind(&child) { + node_id.append(t, &mut self.arena); } else { let child_node_id = self.arena @@ -2670,6 +3007,10 @@ impl TreesitterTranslator { ); } + for node_preproc in self.look_for_preproc(&node) { + node_id.append(node_preproc, &mut self.arena); + } + Some(node_id) } fn parse_expression_list(&mut self, node: &tree_sitter::Node) -> Option { @@ -2679,11 +3020,17 @@ impl TreesitterTranslator { let mut cursor = node.walk(); for child in node.named_children(&mut cursor) { - node_id.append( - self.parse_value(&child) - .unwrap_or_else(|| self.new_error_node(&child)), - &mut self.arena, - ); + if child.is_error() { + node_id.append(self.new_error_node(&child), &mut self.arena); + } else if let Some(t) = self.look_for_preproc_kind(&child) { + node_id.append(t, &mut self.arena); + } else { + node_id.append( + self.parse_value(&child) + .unwrap_or_else(|| self.new_error_node(&child)), + &mut self.arena, + ); + } } Some(node_id) @@ -2709,6 +3056,10 @@ impl TreesitterTranslator { ); } + for node_preproc in self.look_for_preproc(&node) { + node_id.append(node_preproc, &mut self.arena); + } + Some(node_id) } fn parse_reduced_simple_keyset_expression( @@ -2734,6 +3085,10 @@ impl TreesitterTranslator { ); } + for node_preproc in self.look_for_preproc(&node) { + node_id.append(node_preproc, &mut self.arena); + } + Some(node_id) } fn parse_simple_expression_list(&mut self, node: &tree_sitter::Node) -> Option { @@ -2743,11 +3098,17 @@ impl TreesitterTranslator { let mut cursor = node.walk(); for child in node.named_children(&mut cursor) { - node_id.append( - self.parse_simple_keyset_expression(&child) - .unwrap_or_else(|| self.new_error_node(&child)), - &mut self.arena, - ); + if child.is_error() { + node_id.append(self.new_error_node(&child), &mut self.arena); + } else if let Some(t) = self.look_for_preproc_kind(&child) { + node_id.append(t, &mut self.arena); + } else { + node_id.append( + self.parse_simple_keyset_expression(&child) + .unwrap_or_else(|| self.new_error_node(&child)), + &mut self.arena, + ); + } } Some(node_id) diff --git a/src/metadata/symbol_table.rs b/src/metadata/symbol_table.rs index 68f28c1..7b11fbc 100644 --- a/src/metadata/symbol_table.rs +++ b/src/metadata/symbol_table.rs @@ -329,6 +329,7 @@ impl SymbolTable { for type_node_visit in child_visit.get_children().into_iter() { let type_node = type_node_visit.get(); if matches!(type_node.kind, NodeKind::Type(_)) { + //debug!("{:?}:{:?}",child_visit.get(),type_node); let used_type = type_node_visit.get_type().unwrap(); match used_type { Type::Base(base_type) => match base_type { From b79bcf2a8b87b96cb406515077ed328072395bc3 Mon Sep 17 00:00:00 2001 From: MaelC001 <55336346+MaelC001@users.noreply.github.com> Date: Fri, 14 Jul 2023 11:18:31 -0400 Subject: [PATCH 11/19] add error in symbl table --- src/features/diagnostics/mod.rs | 1 + src/features/diagnostics/provider.rs | 11 +++++-- src/features/diagnostics/symbol.rs | 48 ++++++++++++++++++++++++++++ src/metadata/st_manager.rs | 11 ++++++- src/metadata/symbol_table.rs | 44 ++++++++++++++++++------- 5 files changed, 101 insertions(+), 14 deletions(-) create mode 100644 src/features/diagnostics/symbol.rs diff --git a/src/features/diagnostics/mod.rs b/src/features/diagnostics/mod.rs index 211b98c..2ade5a6 100644 --- a/src/features/diagnostics/mod.rs +++ b/src/features/diagnostics/mod.rs @@ -1,4 +1,5 @@ mod parse; mod provider; +mod symbol; pub use provider::{get_full_diagnostics, get_quick_diagnostics}; diff --git a/src/features/diagnostics/provider.rs b/src/features/diagnostics/provider.rs index eabcb31..76ec802 100644 --- a/src/features/diagnostics/provider.rs +++ b/src/features/diagnostics/provider.rs @@ -3,6 +3,7 @@ use std::sync::{Arc, Mutex}; use tower_lsp::lsp_types::Diagnostic; use super::parse::Parse; +use super::symbol::ParseSymbol; use crate::metadata::{AstQuery, SymbolTableQuery}; macro_rules! diags { @@ -30,12 +31,18 @@ pub fn get_quick_diagnostics( ast_query: &Arc>, symbol_table_query: &Arc>, ) -> Vec { - diags![Parse::get_diagnostics(ast_query, symbol_table_query)] + diags![ + Parse::get_diagnostics(ast_query, symbol_table_query), + ParseSymbol::get_diagnostics(ast_query, symbol_table_query) + ] } pub fn get_full_diagnostics( ast_query: &Arc>, symbol_table_query: &Arc>, ) -> Vec { - diags![Parse::get_diagnostics(ast_query, symbol_table_query)] + diags![ + Parse::get_diagnostics(ast_query, symbol_table_query), + ParseSymbol::get_diagnostics(ast_query, symbol_table_query) + ] } diff --git a/src/features/diagnostics/symbol.rs b/src/features/diagnostics/symbol.rs new file mode 100644 index 0000000..b74094f --- /dev/null +++ b/src/features/diagnostics/symbol.rs @@ -0,0 +1,48 @@ +use std::sync::{Arc, Mutex}; + +use crate::metadata::{AstQuery, NodeKind, SymbolTableQuery, VisitNode, Visitable}; +use tower_lsp::lsp_types::{Diagnostic, DiagnosticSeverity}; + +use super::provider::DiagnosticProvider; + +pub struct ParseSymbol {} + +impl DiagnosticProvider for ParseSymbol { + fn get_diagnostics( + _ast_query: &Arc>, + symbol_table_query: &Arc>, + ) -> Vec { + let symbol_table_query = symbol_table_query.lock().unwrap(); + let mut vec_diagnostic: Vec = vec![]; + + for i in symbol_table_query.get_error() { + vec_diagnostic.push(Diagnostic::new( + i, + Some(DiagnosticSeverity::ERROR), + Some(tower_lsp::lsp_types::NumberOrString::String( + "symbol".to_string(), + )), + Some("symbol table".to_string()), + "Symbol error.".to_string(), + None, + None, + )) + } + + for i in symbol_table_query.get_undefined() { + vec_diagnostic.push(Diagnostic::new( + i, + Some(DiagnosticSeverity::WARNING), + Some(tower_lsp::lsp_types::NumberOrString::String( + "symbol".to_string(), + )), + Some("symbol table".to_string()), + "Symbol undefined.".to_string(), + None, + None, + )) + } + + return vec_diagnostic; + } +} diff --git a/src/metadata/st_manager.rs b/src/metadata/st_manager.rs index c0c9035..fa5443b 100644 --- a/src/metadata/st_manager.rs +++ b/src/metadata/st_manager.rs @@ -2,7 +2,7 @@ use super::Ast; use super::{symbol_table::SymbolTable, Field}; use crate::metadata::{Symbol, Symbols}; -use tower_lsp::lsp_types::Position; +use tower_lsp::lsp_types::{Position, Range}; use crate::metadata::symbol_table::SymbolTableActions; @@ -20,6 +20,8 @@ pub trait SymbolTableQuery { fn get_symbols_at_pos(&self, position: Position) -> Symbols; fn get_name_field(&self, position: Position, source_code: &str) -> Option>; fn get_symbol_at_pos(&self, name: String, position: Position) -> Option<&Symbol>; + fn get_error(&self) -> Vec; + fn get_undefined(&self) -> Vec; } #[derive(Debug, Clone)] @@ -47,6 +49,13 @@ impl SymbolTableQuery for SymbolTableManager { fn get_name_field(&self, position: Position, source_code: &str) -> Option> { self.symbol_table.get_variable_in_pos(position, source_code) } + + fn get_error(&self) -> Vec { + self.symbol_table.get_error() + } + fn get_undefined(&self) -> Vec { + self.symbol_table.get_undefined() + } } impl SymbolTableEditor for SymbolTableManager { diff --git a/src/metadata/symbol_table.rs b/src/metadata/symbol_table.rs index 7b11fbc..f83a5ab 100644 --- a/src/metadata/symbol_table.rs +++ b/src/metadata/symbol_table.rs @@ -17,6 +17,7 @@ pub struct SymbolTable { arena: Arena, root_id: Option, undefined_list: Vec, + error_list: Vec, } pub trait SymbolTableActions { @@ -29,7 +30,7 @@ pub trait SymbolTableActions { &mut self, name: String, position: Position, - ) -> Option<&mut Symbol>; + ) -> Option<(Option<&mut Symbol>,bool)>; fn rename_symbol(&mut self, id: usize, new_name: String); } @@ -183,19 +184,26 @@ impl SymbolTableActions for SymbolTable { &mut self, name: String, position: Position, - ) -> Option<&mut Symbol> { + ) -> Option<(Option<&mut Symbol>, bool)> { let scope_id = self.get_scope_id(position)?; for pre_id in scope_id.predecessors(&self.arena) { let scope = self.arena.get(pre_id)?.get(); if scope.symbols.contains_preproc(&name) { - return self + return Some((self .arena .get_mut(pre_id)? .get_mut() .symbols - .find_mut(&name); + .find_mut(&name),true)); + } else if scope.symbols.contains(&name) { + return Some((self + .arena + .get_mut(pre_id)? + .get_mut() + .symbols + .find_mut(&name),false)); } } @@ -342,16 +350,23 @@ impl SymbolTable { let node_symbol = node_symbol_visit.get(); let name_symbol = node_symbol.content.clone(); let pos_symbol = node_symbol.range.start; - - if let Some(symbol) = self.get_symbol_at_pos_mut_preproc( + if let Some((symbol_option, bool_preproc)) = self.get_symbol_at_pos_mut_preproc( name_symbol.clone(), pos_symbol, - ) { - if let Some(type_symbol) = symbol.type_.get_name() { - if type_symbol == Type::Base(BaseType::Int) { - symbol.usages.push(node_symbol.range); + ){ + if let Some(symbol) = symbol_option { + symbol.usages.push(node_symbol.range); + if bool_preproc{ + if let Some(type_symbol) = symbol.type_.get_name() { + if type_symbol == Type::Base(BaseType::Int) { + } else { + self.error_list.push(node_symbol.range) + } + } else { + self.error_list.push(node_symbol.range) + } } else { - self.undefined_list.push(node_symbol.range) + self.error_list.push(node_symbol.range) } } else { self.undefined_list.push(node_symbol.range) @@ -400,6 +415,13 @@ impl SymbolTable { } } } + + pub fn get_error(&self) -> Vec { + self.error_list.clone() + } + pub fn get_undefined(&self) -> Vec { + self.undefined_list.clone() + } } impl fmt::Display for SymbolTable { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { From 539ee7e4764f37a939432ac63e010cd2aa8571e5 Mon Sep 17 00:00:00 2001 From: MaelC001 <55336346+MaelC001@users.noreply.github.com> Date: Fri, 14 Jul 2023 11:23:15 -0400 Subject: [PATCH 12/19] change grammar --- Cargo.toml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index a4172ce..a665c64 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -19,5 +19,6 @@ time = "0.3.20" tokio = { version = "1.28.2", features = ["full"] } tower-lsp = "0.19.0" tree-sitter = "0.20.9" -tree-sitter-p4 = { path = "/home/mc/Documents/tree-sitter-p4" } -# {git = "https://github.com/ace-design/tree-sitter-p4"} +tree-sitter-p4 = { git = "https://github.com/ace-design/tree-sitter-p4" } +# { git = "https://github.com/ace-design/tree-sitter-p4"} +# { path = "/home/mc/Documents/tree-sitter-p4" } From e277db8c0e03f60c5fb2fdbdfde965a5c4cdc36e Mon Sep 17 00:00:00 2001 From: MaelC001 <55336346+MaelC001@users.noreply.github.com> Date: Fri, 14 Jul 2023 11:23:30 -0400 Subject: [PATCH 13/19] Update Cargo.lock --- Cargo.lock | 1 + 1 file changed, 1 insertion(+) diff --git a/Cargo.lock b/Cargo.lock index c2ed7e6..1dc7163 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2289,6 +2289,7 @@ dependencies = [ [[package]] name = "tree-sitter-p4" version = "0.0.1" +source = "git+https://github.com/ace-design/tree-sitter-p4#27200e8e6f42445146eb56fc58f37361eaf4c751" dependencies = [ "cc", "tree-sitter", From a4e9738cbb7a3908157ef9243f30889067c5de25 Mon Sep 17 00:00:00 2001 From: MaelC001 <55336346+MaelC001@users.noreply.github.com> Date: Fri, 14 Jul 2023 11:24:05 -0400 Subject: [PATCH 14/19] remove grammar --- grammar.js | 861 ----------------------------------------------------- 1 file changed, 861 deletions(-) delete mode 100644 grammar.js diff --git a/grammar.js b/grammar.js deleted file mode 100644 index 2fb1f98..0000000 --- a/grammar.js +++ /dev/null @@ -1,861 +0,0 @@ -module.exports = grammar({ - name: 'p4', - - extras: $ => [ - /\s/, - $.line_comment, - $.block_comment, - $.preproc_include_declaration, - $.preproc_define_declaration, - $.preproc_define_declaration_macro, - $.preproc_undef_declaration, - $.preproc_conditional_declaration, - $.preproc_conditional_declaration_elif, - $.preproc_conditional_declaration_else, - $.preproc_conditional_declaration_end - ], - - externals: $ => [$.block_comment], - - conflicts: $ => [ - [$.type_or_void, $.type_identifier], - [$.non_type_name, $.type_identifier], - [$.annotation_token, $.type_identifier], - [$.non_table_kw_name, $.type_identifier], - [$.expression], - ], - - rules: { - source_file: $ => repeat( - seq($._declaration, /\s/), - ), - - _declaration: $ => choice( - $.constant_declaration, - $.extern_declaration, - $.action_declaration, - $.parser_declaration, - $.type_declaration, - $.control_declaration, - $.instantiation, - $.error_declaration, - $.match_kind_declaration, - $.function_declaration - ), - - non_type_name: $ => choice( - $.identifier, - 'apply', - 'key', - 'actions', - 'state', - 'entries', - 'type', - ), - - comment: $ => choice( - $.line_comment, - $.block_comment - ), - - line_comment: $ => token(seq( - '//', /.*/ - )), - - - name: $ => choice( - $.non_type_name, - $.type_identifier, - ), - - preproc_include_declaration: $ => seq( - field("KeyWord", seq('#','include')), choice( - seq( - '<', - $.file_name, - '>' - ), - seq( - '"', - $.file_name, - '"' - ) - ) - ), - - preproc_define_declaration: $ => seq( - field("KeyWord", seq('#','define')), - field("name", $.identifier), - /\s/, - field("body", choice( - $.integer, - $.string, - $.bool, - $.identifier, - $.null_value - )) - ), - preproc_define_declaration_macro: $ => seq( - field("KeyWord", seq('#','define')), - field("name", $.identifier), - optional(/\s/), - '(', - optional( - field("param", $.param_define) - ), - ')', - field("body_macro", $.body_define) - ), // todo - param_define: $ => seq( - $.identifier, - optional($._identifier_list) - ), - _identifier_list: $ => repeat1(seq(',', $.identifier)), - body_define: $ => seq(optional(/[^\/]*\\/),/.*/), - null_value: $ => /\s/, - - preproc_undef_declaration: $ => seq( - field("KeyWord", seq('#','undef')), - $.identifier - ), - preproc_conditional_declaration: $ => prec.left(seq( - '#', - choice( - seq(field("KeyWord", 'if'), /.*/),//$.expression), - seq(field("KeyWord", 'ifdef'), $.identifier), - seq(field("KeyWord", 'ifndef'), $.identifier) - ) - /*, - $._declaration, - repeat($.preproc_conditional_declaration_elif), - optional($.preproc_conditional_declaration_else), - '#', - field("KeyWordEnd", 'endif')*/ - )), - preproc_conditional_declaration_end: $ => prec.left(seq( - '#', - field("KeyWordEnd", 'endif') - )), - preproc_conditional_declaration_else: $ => prec.left(seq('#', field("KeyWord", 'else'))),//, $._declaration)), - preproc_conditional_declaration_elif: $ => prec.left(seq('#', field("KeyWord", 'elif'), /.*/)),//$.expression)),//, $._declaration,)), - - file_name: $ => /[^<>"]+/, - - non_table_kw_name: $ => choice( - $.identifier, - $.type_identifier, - 'apply', - 'state', - 'type', - ), - - annotation: $ => choice( - seq('@', field("name", $.name)), - seq('@', field("name", $.name), '(', field("body", optional($.annotation_body)), ')'), - seq('@', field("name", $.name), '[', field("struct", $.structured_annotation_body), ']'), - ), - annotation_list: $ => repeat1($.annotation), - annotation_body: $ => choice( - seq(field("body", optional($.annotation_body)), '(', field("body2", optional($.annotation_body)), ')'), - seq(field("body", optional($.annotation_body)), field("token", $.annotation_token)), - ), - - structured_annotation_body: $ => choice( - $.expression_list, - $.kv_list, - ), - - parameter_list: $ => seq( - repeat(seq($.parameter, ',')), $.parameter - ), - - parameter: $ => seq(field("annotation", optional($.annotation_list)), field("direction", optional($.direction)), field("type", $.type_ref), field("name", $.name), optional(seq('=', field("value", $.expression)))), - - direction: $ => choice( - 'in', - 'out', - 'inout', - ), - - package_type_declaration: $ => choice( - seq(field("annotation", optional($.annotation_list)), field("KeyWord", 'package'), field('name', $.name), field('parameters_type', optional($.type_parameters))), - seq(field('parameters', optional($.parameter_list)), ')'), - ), - instantiation: $ => choice( - seq(field("type", $.type_ref), '(', field("args", optional($.argument_list)), ')', field('name', $.name), ';'), - seq(field("annotation", optional($.annotation_list)), field("type", $.type_ref), '(', field("args", optional($.argument_list)), ')', field('name', $.name), ';'), - seq(field("annotation", optional($.annotation_list)), field("type", $.type_ref), '(', field("args", optional($.argument_list)), ')', field('name', $.name), '=', field('obj', $.obj_initializer), ';'), - seq(field("type", $.type_ref), '(', field("args", optional($.argument_list)), ')', field('name', $.name), '=', field('obj', $.obj_initializer), ';'), - ), - - obj_initializer: $ => seq( - '{', repeat($._obj_declaration), '}' - ), - - _obj_declaration: $ => choice( - $.function_declaration, - $.instantiation, - ), - - dot_prefix: $ => seq( - '.', - ), - - parser_declaration: $ => seq( - field("declaration", $.parser_type_declaration), - field("body", $.parser_body) - ), - - parser_body: $ => seq( - '{', - repeat($._parser_local_element), - repeat($.parser_state), - '}' - ), - - _parser_local_element: $ => choice( - $.constant_declaration, - $.variable_declaration, - $.instantiation, - $.value_set_declaration, - ), - - parser_type_declaration: $ => seq( - field("annotation", optional($.annotation_list)), field("KeyWord", 'parser'), field('name', $.name), field('parameters_type', optional($.type_parameters)), '(', field('parameters', optional($.parameter_list)), ')' - ), - parser_state: $ => seq( - field("annotation", optional($.annotation_list)), field("KeyWord", 'state'), field("name", $.name), field("body", $.parser_state_body) - ), - parser_state_body: $ => seq( - '{', - field("statement", optional($.parser_state_body_statement)), - field("transition_statement", optional($.transition_statement)), - '}' - ), - - parser_state_body_statement: $ => repeat1($._parser_statement), - - _parser_statement: $ => choice( - $.assignment_or_method_call_statement, - $.direct_application, - $.parser_block_statement, - $.constant_declaration, - $.variable_declaration, - $.empty_statement, - $.conditional_statement, - ), - - parser_block_statement: $ => seq( - field("annotation", optional($.annotation_list)), field("body",$.parser_block_statement_body) - ), - - parser_block_statement_body: $ => seq( - '{', repeat($._parser_statement), '}' - ), - - transition_statement: $ => seq( - field("KeyWord", 'transition'), $._state_expression - ), - - _state_expression: $ => choice( - seq(field("name",$.name), ';'), - $.select_expression, - ), - - select_expression: $ => seq( - field("KeyWord", 'select'), $.select_expression_params, $.select_expression_body - ), - select_expression_params: $ => seq('(', optional($.expression_list), ')'), - select_expression_body: $ => seq('{', optional($.select_case_list), '}'), - - select_case_list: $ => repeat1($.select_case), - - select_case: $ => seq( - field('type',$._keyset_expression), ':', field('name',$.name), ';' - ), - - _keyset_expression: $ => choice( - $.tuple_keyset_expression, - $.simple_keyset_expression, - ), - - tuple_keyset_expression: $ => choice( - seq("(", $.simple_keyset_expression, ",", $.simple_expression_list, ")"), - seq("(", field("reduce", $.reduced_simple_keyset_expression), ")"), - ), - - simple_expression_list: $ => seq(repeat(seq($.simple_keyset_expression, ',')), $.simple_keyset_expression), - - reduced_simple_keyset_expression: $ => choice( - seq(field("value", $.expression), "&&&", field("value2", $.expression)), - seq(field("value", $.expression), "..", field("value2", $.expression)), - 'default', - "_", - ), - - simple_keyset_expression: $ => choice( - field("value", $.expression), - 'default', - '_', - seq(field("value", $.expression), 'mask', field("value2", $.expression)), - seq(field("value", $.expression), 'range', field("value2", $.expression)), - ), - - value_set_declaration: $ => seq( - field("annotation", optional($.annotation_list)), - field("KeyWord", 'valueset'), - '<', - field("type", choice($.base_type, $.tuple_type, $.type_name)), - '>', - '(', - field("expression", $.expression), - ')', - field("name", $.name), - ';' - ), - - control_declaration: $ => seq( - field("declaration", $.control_type_declaration), - field("body", $.control_body), - ), - - parser_declaration: $ => seq( - field("declaration", $.parser_type_declaration), - field("body", $.parser_body) - ), - - control_body: $ => seq( - '{', - repeat($._control_local_declaration), - field("KeyWord", 'apply'), - $.block_statement, - '}' - ), - - control_type_declaration: $ => seq( - field("annotation", optional($.annotation_list)), field("KeyWord", 'control'), field("name", $.name), field('parameters_type', optional($.type_parameters)), '(', field("parameters", optional($.parameter_list)), ')' - ), - - _control_local_declaration: $ => choice( - $.constant_declaration, - $.action_declaration, - $.table_declaration, - $.instantiation, - $.variable_declaration, - ), - - extern_declaration: $ => choice( - seq(field("annotation", optional($.annotation_list)), field("KeyWord", 'extern'), field('name', $.non_type_name), field('parameters_type', optional($.type_parameters)), '{', field('method', optional($.method_prototype_list)), '}'), - seq(field("annotation", optional($.annotation_list)), field("KeyWord", 'extern'), field('function', $.function_prototype), ';'), - ), - - function_prototype: $ => seq( - field("type", $.type_or_void), field("name", $.name), field('parameters_type', optional($.type_parameters)), '(', field("parameters_list", optional($.parameter_list)), ')' - ), - - method_prototype_list: $ => repeat1($.method_prototype), - - method_prototype: $ => choice( - seq(field("annotation", optional($.annotation_list)), field('function', $.function_prototype), ';'), - seq(field("annotation", optional($.annotation_list)), field('type', $.type_identifier), '(', field('parameters', optional($.parameter_list)), ')', ';'), - ), - - type_ref: $ => choice( - $.base_type, - $.type_name, - $.specialized_type, - $.header_stack_type, - $.tuple_type, - ), - - named_type: $ => choice( - $.type_name, - $.specialized_type, - ), - - prefixed_type: $ => choice( - $.type_identifier, - seq($.dot_prefix, $.type_identifier), - ), - - type_name: $ => seq( - $.prefixed_type, - ), - - tuple_type: $ => seq( - field("KeyWord", 'tuple'), '<', optional($.type_argument_list), '>' - ), - - header_stack_type: $ => choice( - seq($.type_name, '[', $.expression, ']'), - seq($.specialized_type, '[', $.expression, ']'), - ), - - specialized_type: $ => seq( - $.prefixed_type, '<', optional($.type_argument_list), '>' - ), - - base_type: $ => choice( - 'bool', - 'error', - 'match_kind', - 'string', - 'int', - 'bit', - seq('bit', '<', $.integer, '>'), - seq('int', '<', $.integer, '>'), - seq('varbit', '<', $.integer, '>'), - seq('bit', '<', '(', $.expression, ')', '>'), - seq('int', '<', '(', $.expression, ')', '>'), - seq('varbit', '<', '(', $.expression, ')', '>'), - seq('bit', '<', $.define_symbol, '>'), - seq('int', '<', $.define_symbol, '>'), - seq('varbit', '<', $.define_symbol, '>'), - ), - - define_symbol: $ => $.identifier, - - type_or_void: $ => prec.left(1, choice( - $.type_ref, - 'void', - $.identifier, - )), - - type_parameters: $ => seq( - '<', $.type_parameter_list, '>' - ), - - type_parameter_list: $ => seq(repeat(seq($.name, ',')), $.name), - - real_type_arg: $ => choice( - '_', - $.type_ref, - 'void', - ), - - type_arg: $ => choice( - '_', - $.type_ref, - $.non_type_name, - 'void', - ), - - // TODO: Check if last real_type_arg should be type_arg - real_type_argument_list: $ => seq(repeat(seq($.real_type_arg, ',')), $.real_type_arg), - - type_argument_list: $ => seq(repeat(seq($.type_arg, ',')), $.type_arg), - - type_declaration: $ => field("type_kind", choice( - $._derived_type_declaration, - $.typedef_declaration, - seq($.parser_type_declaration, ';'), - seq($.control_type_declaration, ';'), - seq($.package_type_declaration, ';'), - )), - - _derived_type_declaration: $ => choice( - $.header_type_declaration, - $.header_union_declaration, - $.struct_type_declaration, - $.enum_declaration, - ), - - header_type_declaration: $ => seq( - field("annotation", optional($.annotation_list)), field("KeyWord", 'header'), field("name", $.name), field('parameters_type', optional($.type_parameters)), '{', field("field_list", optional($.struct_field_list)), '}' - ), - - header_union_declaration: $ => seq( - field("annotation", optional($.annotation_list)), field("KeyWord", 'header_union'), field("name", $.name), field('parameters_type', optional($.type_parameters)), '{', field("field_list", optional($.struct_field_list)), '}' - ), - - struct_type_declaration: $ => seq( - field("annotation", optional($.annotation_list)), field("KeyWord", 'struct'), field("name", $.name), field('parameters_type', optional($.type_parameters)), '{', field("field_list", optional($.struct_field_list)), '}' - ), - - struct_field_list: $ => repeat1($.struct_field), - struct_field: $ => seq( - field("annotation", optional($.annotation_list)), field("type", $.type_ref), field("name", $.name), ';' - ), - - enum_declaration: $ => choice( - seq(field("annotation", optional($.annotation_list)), field("KeyWord", 'enum'), field("name", $.name), '{', field("option_list", $.identifier_list), '}'), - seq(field("annotation", optional($.annotation_list)), field("KeyWord", 'enum'), field("type", $.type_ref), field("name", $.name), '{', field("option_list", $.specified_identifier_list), '}'), - ), - - error_declaration: $ => seq( - field("KeyWord", 'error'), '{', field("option_list", $.identifier_list), '}' - ), - - match_kind_declaration: $ => seq( - field("KeyWord", 'match_kind'), '{', field("option_list", $.identifier_list), '}' - ), - - identifier_list: $ => seq(repeat(seq($.name, ',')), $.name), - - specified_identifier_list: $ => choice( - $.specified_identifier, - seq($.specified_identifier_list, ',', $.specified_identifier), - ), - - specified_identifier: $ => seq( - $.name, '=', $.initializer - ), - - typedef_declaration: $ => choice( - seq(field("annotation", optional($.annotation_list)), field("KeyWord", 'typedef'), field("type", $.type_ref), field("name", $.name), ';'), - seq(field("annotation", optional($.annotation_list)), field("KeyWord", 'typedef'), field("type", $._derived_type_declaration), field("name", $.name), ';'), - seq(field("annotation", optional($.annotation_list)), field("KeyWord", 'type'), field("type", $.type_ref), field("name", $.name), ';'), - seq(field("annotation", optional($.annotation_list)), field("KeyWord", 'type'), field("type", $._derived_type_declaration), field("name", $.name), ';'), - ), - - assignment_or_method_call_statement: $ => choice( - seq(field("name", $.lvalue), '(', field("parameters", optional($.argument_list)), ')', ';'), - seq(field("name", $.lvalue), '<', field("type", optional($.type_argument_list)), '>', '(', field("parameters", optional($.argument_list)), ')', ';'), - seq(field("name", $.lvalue), '=', field("expression", $.expression), ';'), - ), - - empty_statement: $ => seq( - ';', - ), - - return_statement: $ => seq(field("KeyWord", 'return'), field("expression", optional($.expression)), ';'), - - exit_statement: $ => seq( - 'exit', ';' - ), - - conditional_statement: $ => choice( - prec.left(seq(field("KeyWord", 'if'), '(', field("expression", $.expression), ')', field("bodyIf", $._statement))), - prec.left(seq(field("KeyWord", 'if'), '(', field("expression", $.expression), ')', field("bodyIf", $._statement), field("KeyWordEnd", 'else'), field("bodyElse", $._statement))), - ), - - direct_application: $ => choice( - seq(field("name", $.type_name), '.', field("KeyWord", 'apply'), '(', field("args", optional($.argument_list)), ')', ';'), - seq(field("specialized", $.specialized_type), '.', field("KeyWord", 'apply'), '(', field("args", optional($.argument_list)), ')', ';'), - ), - - _statement: $ => choice( - $.assignment_or_method_call_statement, - $.direct_application, - $.conditional_statement, - $.empty_statement, - $.block_statement, - $.exit_statement, - $.return_statement, - $.switch_statement, - ), - - block_statement: $ => seq( - field("annotation", optional($.annotation_list)), '{', optional($._stat_or_decl_list), '}' - ), - - _stat_or_decl_list: $ => repeat1($._statement_or_declaration), - - switch_statement: $ => seq( - field("KeyWord", 'switch'), '(', field("expression",$.expression), ')', '{', field("body", repeat($.switch_case)), '}' - ), - - switch_case: $ => choice( - seq(field("name",$.switch_label), ':', field("value",$.block_statement)), - seq(field("name",$.switch_label), ':'), - ), - - switch_label: $ => choice( - 'default', - $.non_brace_expression, - ), - - _statement_or_declaration: $ => choice( - $.variable_declaration, - $.constant_declaration, - $._statement, - ), - - table_declaration: $ => seq( - field("annotation", optional($.annotation_list)), field("KeyWord", 'table'), field("name", $.name), '{', field("table", $.table_property_list), '}' - ), - - table_property_list: $ => repeat1($._table_property), - - _table_property: $ => choice( - $.keys_table, - $.action_table, - $.entries_table, - $.name_table - ), - - keys_table: $ => seq(field("KeyWord", 'key'), '=', '{', field("keys", optional($.key_element_list)), '}'), - action_table: $ => seq(field("KeyWord", 'actions'), '=', '{', field("actions", optional($.action_list)), '}'), - entries_table: $ => seq(field("annotation", optional($.annotation_list)), field("KeyWord", 'const'), field("KeyWordEnd", 'entries'), '=', '{', field("entries", optional($.entry_list)), '}'), - name_table: $ => seq(field("annotation", optional($.annotation_list)), field("KeyWord", optional('const')), field("name", $.non_table_kw_name), '=', field("expression", $.initializer), ';'), - - key_element_list: $ => repeat1($.key_element), - - key_element: $ => seq( - seq(field("expression", $.expression), ':', field("name", $.name), field("annotation", optional($.annotation_list)), ';'), - ), - - action_list: $ => repeat1($.action), - action: $ => seq(field("annotation", optional($.annotation_list)), $._action_ref, ';'), - _action_ref: $ => choice( - field("name", $.prefixed_non_type_name), - seq(field("name", $.prefixed_non_type_name), '(', field("args", optional($.argument_list)), ')'), - ), - - entry_list: $ => repeat1($.entry), - - entry: $ => seq( - $._keyset_expression, ':', $._action_ref, field("annotation", optional($.annotation_list)), ';' - ), - - action_declaration: $ => seq( - field("annotation", optional($.annotation_list)), field("KeyWord", 'action'), field("name", $.name), '(', field('parameters', optional($.parameter_list)), ')', field('block', $.block_statement) - ), - - variable_declaration: $ => seq(field("annotation", optional($.annotation_list)), field("type", $.type_ref), field("name", $.name), optional(seq('=', field("value", $.initializer))), ';'), - - constant_declaration: $ => seq( - field("annotation", optional($.annotation_list)), field("KeyWord", 'const'), field("type", $.type_ref), field("name", $.name), '=', field("value", $.initializer), ';' - ), - - initializer: $ => seq( - $.expression, - ), - - function_declaration: $ => seq( - $.function_prototype, $.block_statement - ), - - argument_list: $ => seq(repeat(seq($.argument, ',')), $.argument), - - argument: $ => choice( - field("expression", $.expression), - seq(field("name", $.name), '=', field("expression", $.expression)), - '_', - seq(field("name", $.name), '=', '_'), - ), - - kv_list: $ => seq(repeat(seq($.kv_pair, ',')), $.kv_pair), - - kv_pair: $ => seq( - $.name, '=', $.expression - ), - - expression_list: $ => seq(repeat(seq($.expression, ',')), $.expression), - - annotation_token: $ => choice( - 'abstract', - 'action', - 'actions', - 'apply', - 'bool', - $.bool, - 'bit', - 'const', - 'control', - 'default', - 'else', - 'entries', - 'enum', - 'error', - 'exit', - 'extern', - 'header', - 'header_union', - 'if', - 'in', - 'inout', - 'int', - 'key', - 'match_kind', - 'type', - 'out', - 'parser', - 'package', - 'pragma', - 'return', - 'select', - 'state', - 'string', - 'struct', - 'switch', - 'table', - 'transition', - 'tuple', - 'typedef', - 'varbit', - 'valueset', - 'void', - "_", - $.identifier, - $.type_identifier, - $.string, - $.integer, - "&&&", - "..", - "<<", - "&&", - "||", - "==", - "!=", - ">=", - "<=", - "++", - "+", - "|+|", - "-", - "|-|", - "*", - "/", - "%", - "|", - "&", - "^", - "~", - "[", - "]", - "{", - "}", - "<", - ">", - "!", - ":", - ",", - "?", - ".", - "=", - ";", - "@", - 'unknown_token', - ), - - member: $ => seq( - $.name, - ), - - prefixed_non_type_name: $ => choice( - $.non_type_name, - seq($.dot_prefix, $.non_type_name), - ), - - lvalue: $ => choice( - $.prefixed_non_type_name, - 'this', - $.lvalue_dot, - $.lvalue_bra, - $.lvalue_double_dot, - ), - lvalue_dot: $ => seq($.lvalue, '.', $.member), - lvalue_bra: $ => seq($.lvalue, '[', $.expression, ']'), - lvalue_double_dot: $ => seq($.lvalue, '[', $.expression, ':', $.expression, ']'), - - bool: $ => choice( - 'true', - 'false' - ), - - expression: $ => choice( - $.integer, - $.bool, - 'this', - $.string, - $.non_type_name, - seq($.dot_prefix, $.non_type_name), - prec.left(1, seq($.expression, '[', $.expression, ']')), - prec.left(1, seq($.expression, '[', $.expression, ':', $.expression, ']')), - prec.left(1, seq('{', optional($.expression_list), '}')), - prec.left(1, seq('{', $.kv_list, '}')), - prec.left(1, seq('(', $.expression, ')')), - prec.right(2, seq('!', $.expression)), - prec.right(2, seq('~', $.expression)), - prec.right(2, seq('-', $.expression)), - prec.right(2, seq('+', $.expression)), - prec.left(1, seq($.type_name, '.', $.member)), - prec.left(1, seq('error', '.', $.member)), - prec.left(1, seq($.expression, '.', $.member)), - prec.left(3, seq($.expression, '*', $.expression)), - prec.left(3, seq($.expression, '/', $.expression)), - prec.left(3, seq($.expression, '%', $.expression)), - prec.left(4, seq($.expression, '+', $.expression)), - prec.left(4, seq($.expression, '-', $.expression)), - prec.left(4, seq($.expression, '|+|', $.expression)), - prec.left(4, seq($.expression, '|-|', $.expression)), - prec.left(5, seq($.expression, '<<', $.expression)), - prec.left(5, seq($.expression, '>>', $.expression)), - prec.left(11, seq($.expression, '<=', $.expression)), //TODO: Double check precedence of <=,<... and == - prec.left(11, seq($.expression, '>=', $.expression)), - prec.left(11, seq($.expression, '<', $.expression)), - prec.left(11, seq($.expression, '>', $.expression)), - prec.left(7, seq($.expression, '!=', $.expression)), - prec.left(7, seq($.expression, '==', $.expression)), - prec.left(8, seq($.expression, '&', $.expression)), - prec.left(9, seq($.expression, '^', $.expression)), - prec.left(10, seq($.expression, '|', $.expression)), - prec.left(1, seq($.expression, '++', $.expression)), - prec.left(12, seq($.expression, '&&', $.expression)), - prec.left(12, seq($.expression, '||', $.expression)), - prec.right(13, seq($.expression, '?', $.expression, ':', $.expression)), - prec.left(1, seq($.expression, '<', $.real_type_argument_list, '>', '(', optional($.argument_list), ')')), - prec.left(1, seq($.expression, '(', optional($.argument_list), ')')), - prec.left(1, seq($.named_type, '(', optional($.argument_list), ')')), - prec.right(2, seq('(', $.type_ref, ')', $.expression)), - ), - - non_brace_expression: $ => choice( - $.integer, - $.string, - $.bool, - 'this', - $.non_type_name, - seq($.dot_prefix, $.non_type_name), - seq($.non_brace_expression, '[', $.expression, ']'), - seq($.non_brace_expression, '[', $.expression, ':', $.expression, ']'), - seq('(', $.expression, ')'), - seq('!', $.expression), - seq('~', $.expression), - seq('-', $.expression), - seq('+', $.expression), - seq($.type_name, '.', $.member), - seq('error', '.', $.member), - seq($.non_brace_expression, '.', $.member), - seq($.non_brace_expression, '*', $.expression), - seq($.non_brace_expression, '/', $.expression), - seq($.non_brace_expression, '%', $.expression), - seq($.non_brace_expression, '+', $.expression), - seq($.non_brace_expression, '-', $.expression), - seq($.non_brace_expression, '|+|', $.expression), - seq($.non_brace_expression, '|-|', $.expression), - seq($.non_brace_expression, '<<', $.expression), - seq($.non_brace_expression, '>>', $.expression), - seq($.non_brace_expression, '<=', $.expression), - seq($.non_brace_expression, '>=', $.expression), - seq($.non_brace_expression, '<', $.expression), - seq($.non_brace_expression, '>', $.expression), - seq($.non_brace_expression, '!=', $.expression), - seq($.non_brace_expression, '==', $.expression), - seq($.non_brace_expression, '&', $.expression), - seq($.non_brace_expression, '^', $.expression), - seq($.non_brace_expression, '|', $.expression), - seq($.non_brace_expression, '++', $.expression), - seq($.non_brace_expression, '&&', $.expression), - seq($.non_brace_expression, '||', $.expression), - seq($.non_brace_expression, '?', $.expression, ':', $.expression), - seq($.non_brace_expression, '<', $.real_type_argument_list, '>', '(', optional($.argument_list), ')'), - seq($.non_brace_expression, '(', optional($.argument_list), ')'), - seq($.named_type, '(', optional($.argument_list), ')'), - seq('(', $.type_ref, ')', $.expression), - ), - - integer: $ => /(\d+([wWsS]))?\d+(([xX][0-9A-Fa-f_]+)|([bB][0-1_]+)|([oO][0-7_]+)|([dD][0-9_]+))?/, - - string: $ => /"(\\.|[^"\\])*"/, - - - prec: $ => $.identifier, - - identifier: $ => /[a-zA-Z_]\w*/, - - type_identifier: $ => $.identifier, - - } -}); \ No newline at end of file From fb0bfc9ea05b5b5a10421e0ee7606943d99b33f1 Mon Sep 17 00:00:00 2001 From: MaelC001 <55336346+MaelC001@users.noreply.github.com> Date: Fri, 14 Jul 2023 11:24:18 -0400 Subject: [PATCH 15/19] Update .gitignore --- .gitignore | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index cb151c4..b607db9 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ /target -**/.DS_Store \ No newline at end of file +**/.DS_Store +grammar.js From cadd844367ce2a0764bd1555ed85d44528db55b1 Mon Sep 17 00:00:00 2001 From: MaelC001 <55336346+MaelC001@users.noreply.github.com> Date: Fri, 14 Jul 2023 12:59:21 -0400 Subject: [PATCH 16/19] don't look at comment --- src/metadata/ast/translator.rs | 176 ++++++++++++++++++++++----------- 1 file changed, 120 insertions(+), 56 deletions(-) diff --git a/src/metadata/ast/translator.rs b/src/metadata/ast/translator.rs index 608543d..49cf109 100644 --- a/src/metadata/ast/translator.rs +++ b/src/metadata/ast/translator.rs @@ -90,7 +90,7 @@ impl TreesitterTranslator { node_id.append(self.new_error_node(&child), &mut self.arena); } else if let Some(t) = self.look_for_preproc_kind(&child) { node_id.append(t, &mut self.arena); - } else { + } else if !self.is_comment(&child) { let child_node_id = self.arena .new_node(Node::new(NodeKind::Method, node, &self.source_code)); @@ -193,7 +193,7 @@ impl TreesitterTranslator { self.arena .new_node(Node::new(NodeKind::ParamType, node, &self.source_code)); - let node_param_type = node.named_child(0)?; + let node_param_type = node.named_child(self.get_named_child(&node, 0)?)?; let mut cursor = node_param_type.walk(); for child in node_param_type.named_children(&mut cursor) { @@ -274,6 +274,52 @@ impl TreesitterTranslator { Some(node_id) } + fn is_comment(&mut self, node: &tree_sitter::Node) -> bool { + let kind = node.kind(); + if kind == "line_comment" && kind == "block_comment" { + return true; + } + return false; + } + fn get_child(&mut self, node: &tree_sitter::Node, index_inital: u32) -> Option { + let mut index = 0; + let mut index_no_comment = 0; + while true{ + let n = node.child(index); + if let Some(x) = n{ + if !self.is_comment(&x){ + if index_no_comment == index_inital{ + return Some(index); + } + index_no_comment += 1; + } + index += 1; + } else{ + return None; + } + } + return None; + } + fn get_named_child(&mut self, node: &tree_sitter::Node, index_inital: u32) -> Option { + let mut index = 0; + let mut index_no_comment = 0; + while true{ + let n = node.named_child(index); + if let Some(x) = n{ + if !self.is_comment(&x){ + if index_no_comment == index_inital{ + return Some(index); + } + index_no_comment += 1; + } + index += 1; + } else{ + return None; + } + } + return None; + } + fn look_for_preproc_kind(&mut self, node: &tree_sitter::Node) -> Option { let kind = node.kind(); if kind == "preproc_include_declaration" { @@ -325,7 +371,7 @@ impl TreesitterTranslator { } // Add name node - let node_name = node.child(3).unwrap(); + let node_name = node.child(self.get_child(&node, 3)?).unwrap(); let name_node = self.arena .new_node(Node::new(NodeKind::Name, &node_name, &self.source_code)); @@ -426,7 +472,7 @@ impl TreesitterTranslator { } // Add name node - let node_name = node.named_child(0).unwrap(); + let node_name = node.named_child(self.get_named_child(&node, 0)?).unwrap(); let name_node = self.arena .new_node(Node::new(NodeKind::Name, &node_name, &self.source_code)); @@ -579,12 +625,14 @@ impl TreesitterTranslator { let mut cursor = node.walk(); for field_child in node.children(&mut cursor) { if field_child.is_error() { - } else { + } else if !self_v.is_comment(&field_child) { let mut loop_child = 1; while loop_child != 0 { match field_child.child(loop_child - 1) { Some(x) => { - name_node = loop_value(node_value, name_node, &x, self_v); + if self_v.is_comment(&x){} else { + name_node = loop_value(node_value, name_node, &x, self_v); + } loop_child += 1; } None => { @@ -1012,10 +1060,10 @@ impl TreesitterTranslator { let mut cursor = node.walk(); for option_child in node.named_children(&mut cursor) { let new_node_id = if option_child.is_error() { - self.new_error_node(&option_child) + Some(self.new_error_node(&option_child)) } else if let Some(t) = self.look_for_preproc_kind(&option_child) { - t - } else { + Some(t) + } else if !self.is_comment(&option_child) { //let node_text = utils::get_node_text(&option_child, &self.source_code); //let text = node_text.as_str().trim(); debug!("{:?}", option_child); // todo-issue @@ -1036,10 +1084,14 @@ impl TreesitterTranslator { &mut self.arena, ); - option_node_id + Some(option_node_id) + } else{ + None }; - - options_node_id.append(new_node_id, &mut self.arena); + + if let Some(x) = new_node_id{ + options_node_id.append(x, &mut self.arena); + } } Some(options_node_id) } @@ -1052,7 +1104,7 @@ impl TreesitterTranslator { ) -> Option { let child: tree_sitter::Node<'_>; if child_bool { - child = node.named_child(0)?; + child = node.named_child(self.get_named_child(&node, 0)?)?; } else { child = node.clone(); } @@ -1099,7 +1151,7 @@ impl TreesitterTranslator { &self.source_code, ))), _ => { - let child_child = child.named_child(0).unwrap(); + let child_child = child.named_child(self.get_named_child(&child, 0)?).unwrap(); let mut node_id: Option = None; if child_child.kind() == "integer" { let size = Some( @@ -1533,11 +1585,15 @@ impl TreesitterTranslator { self.arena .new_node(Node::new(NodeKind::Function, node, &self.source_code)); - if let Some(x) = self.function_prototype(&node.named_child(0)?) { + let mut index = self.get_named_child(&node, 0)?; + + if let Some(x) = self.function_prototype(&node.named_child(index)?) { fn_node_id.append(x, &mut self.arena); } - if let Some(x) = self.parse_block(&node.named_child(1)?) { + index = self.get_named_child(&node, 1)?; + + if let Some(x) = self.parse_block(&node.named_child(index)?) { fn_node_id.append(x, &mut self.arena); } @@ -1707,14 +1763,15 @@ impl TreesitterTranslator { fn parse_name_assignment(&mut self, node_t: &tree_sitter::Node) -> Option { let node_first = *node_t; let mut last_node: Option = None; - if let Some(mut node) = node_t.child(0) { + if let Some(mut node) = node_t.child(self.get_child(&node_t, 0)?) { let mut bool = true; while bool { match node.kind() { "prefixed_non_type_name" => { + let index = self.get_named_child(&node, 0)?; let node_id = self.arena.new_node(Node::new( NodeKind::Type(Type::Name), - &node.named_child(0).unwrap(), + &node.named_child(index).unwrap(), &self.source_code, )); if let Some(new_child) = last_node { @@ -1729,7 +1786,9 @@ impl TreesitterTranslator { &node, &self.source_code, )); - let t = node.named_child(1).unwrap().named_child(0).unwrap(); + let mut t = node.named_child(self.get_named_child(&node, 1)?).unwrap(); + t = t.named_child(self.get_named_child(&t, 0)?).unwrap(); + let node_id_dot = self.arena.new_node(Node::new( NodeKind::ValueSymbol, &t, @@ -1743,7 +1802,8 @@ impl TreesitterTranslator { node_id.append(node_id_dot, &mut self.arena); - if let Some(x) = node.named_child(0).unwrap().named_child(0) { + t = node.named_child(self.get_named_child(&t, 0)?).unwrap(); + if let Some(x) = t.named_child(self.get_named_child(&t, 0)?) { node = x } else { bool = false; @@ -1755,7 +1815,7 @@ impl TreesitterTranslator { &node, &self.source_code, )); - let t = node.named_child(1).unwrap(); + let mut t = node.named_child(self.get_named_child(&node, 1)?).unwrap(); let node_id_expr = self .parse_value(&t) .unwrap_or_else(|| self.new_error_node(&t)); @@ -1767,7 +1827,8 @@ impl TreesitterTranslator { node_id.append(node_id_expr, &mut self.arena); - if let Some(x) = node.named_child(0).unwrap().named_child(0) { + t = node.named_child(self.get_named_child(&node, 0)?).unwrap(); + if let Some(x) = t.named_child(self.get_named_child(&t, 0)?) { node = x } else { bool = false; @@ -1779,14 +1840,14 @@ impl TreesitterTranslator { &node, &self.source_code, )); - let t1 = node.named_child(1).unwrap(); - let t2 = node.named_child(2).unwrap(); + let node_child_1 = node.named_child(self.get_named_child(&node, 1)?).unwrap(); + let node_child_2 = node.named_child(self.get_named_child(&node, 2)?).unwrap(); let node_id_expr1 = self - .parse_value(&t1) - .unwrap_or_else(|| self.new_error_node(&t1)); + .parse_value(&node_child_1) + .unwrap_or_else(|| self.new_error_node(&node_child_1)); let node_id_expr2 = self - .parse_value(&t2) - .unwrap_or_else(|| self.new_error_node(&t2)); + .parse_value(&node_child_2) + .unwrap_or_else(|| self.new_error_node(&node_child_2)); if let Some(new_child) = last_node { node_id.append(new_child, &mut self.arena); @@ -1796,7 +1857,8 @@ impl TreesitterTranslator { node_id.append(node_id_expr1, &mut self.arena); node_id.append(node_id_expr2, &mut self.arena); - if let Some(x) = node.named_child(0).unwrap().named_child(0) { + let mut t = node.named_child(self.get_named_child(&node, 0)?).unwrap(); + if let Some(x) = t.named_child(self.get_named_child(&t, 0)?) { node = x } else { bool = false; @@ -1891,7 +1953,7 @@ impl TreesitterTranslator { } else if let Some(t) = self.look_for_preproc_kind(&syntax_child) { Some(t) } else { - match syntax_child.named_child(0)?.kind() { + match syntax_child.named_child(self.get_named_child(&syntax_child, 0)?)?.kind() { "type_ref" => self.parse_type_ref(&syntax_child, NodeKind::TypeList, true), "non_type_name" => Some(self.arena.new_node(Node::new( NodeKind::TypeList(Type::Name), @@ -2409,7 +2471,7 @@ impl TreesitterTranslator { .append(self.new_error_node(&keys_child), &mut self.arena); } else if let Some(t) = self.look_for_preproc_kind(&keys_child) { keys_node_id.append(t, &mut self.arena); - } else { + } else if !self.is_comment(&keys_child) { // Add name node let key_node_id = self.arena.new_node(Node::new( NodeKind::Key, @@ -2463,7 +2525,7 @@ impl TreesitterTranslator { .append(self.new_error_node(&actions_child), &mut self.arena); } else if let Some(t) = self.look_for_preproc_kind(&actions_child) { actions_node_id.append(t, &mut self.arena); - } else { + } else if !self.is_comment(&actions_child) { // Add name node let action_node_id = self.arena.new_node(Node::new( NodeKind::Action, @@ -2516,7 +2578,7 @@ impl TreesitterTranslator { .append(self.new_error_node(&entries_child), &mut self.arena); } else if let Some(t) = self.look_for_preproc_kind(&entries_child) { entries_node_id.append(t, &mut self.arena); - } else { + } else if !self.is_comment(&entries_child) { // Add name node let entrie_node_id = self.arena.new_node(Node::new( NodeKind::Entrie, @@ -2551,7 +2613,7 @@ impl TreesitterTranslator { } // _keyset_expression - if let Some(x) = entries_child.named_child(0) { + if let Some(x) = entries_child.named_child(self.get_named_child(&entries_child, 0)?) { if x.kind() == "tuple_keyset_expression" { if let Some(y) = x.child_by_field_name("reduce") { entrie_node_id.append( @@ -2560,16 +2622,16 @@ impl TreesitterTranslator { &mut self.arena, ); } else { - let t = x.named_child(0)?; - let tt = x.named_child(1)?; + let node_child_0 = x.named_child(self.get_named_child(&x, 0)?)?; + let node_child_1 = x.named_child(self.get_named_child(&x, 1)?)?; entrie_node_id.append( - self.parse_simple_keyset_expression(&t) - .unwrap_or_else(|| self.new_error_node(&t)), + self.parse_simple_keyset_expression(&node_child_0) + .unwrap_or_else(|| self.new_error_node(&node_child_0)), &mut self.arena, ); entrie_node_id.append( - self.parse_simple_expression_list(&tt) - .unwrap_or_else(|| self.new_error_node(&tt)), + self.parse_simple_expression_list(&node_child_1) + .unwrap_or_else(|| self.new_error_node(&node_child_1)), &mut self.arena, ); } @@ -2607,7 +2669,7 @@ impl TreesitterTranslator { // Add value node if let Some(expr) = table_child.child_by_field_name("expression") { - let value_node = expr.named_child(0).unwrap(); + let value_node = expr.named_child(self.get_named_child(&expr, 0)?).unwrap(); table_kw_node_id.append( self.parse_value(&value_node) .unwrap_or_else(|| self.new_error_node(&value_node)), @@ -2776,7 +2838,7 @@ impl TreesitterTranslator { &mut self.arena, ); } else { - let t = transition_statement.named_child(0)?; + let t = transition_statement.named_child(self.get_named_child(&transition_statement, 0)?)?; // Add keyword node if let Some(type_node) = t.child_by_field_name("KeyWord") { @@ -2790,8 +2852,10 @@ impl TreesitterTranslator { ); } - let select_expression_params = t.named_child(0)?.named_child(0); - let select_expression_body = t.named_child(1)?.named_child(0); + let select_expression_params_temp = t.named_child(self.get_named_child(&t, 0)?)?; + let select_expression_params = select_expression_params_temp.named_child(self.get_named_child(&select_expression_params_temp, 0)?); + let select_expression_body_temp = t.named_child(self.get_named_child(&t, 1)?)?; + let select_expression_body = select_expression_body_temp.named_child(self.get_named_child(&select_expression_body_temp, 0)?); if let Some(select_expression_params_node) = select_expression_params { transition_node.append( @@ -2842,16 +2906,16 @@ impl TreesitterTranslator { &mut self.arena, ); } else { - let t = x.named_child(0)?; - let tt = x.named_child(1)?; + let node_child_0 = x.named_child(self.get_named_child(&x, 0)?)?; + let node_child_1 = x.named_child(self.get_named_child(&x, 1)?)?; transition_node.append( - self.parse_simple_keyset_expression(&t) - .unwrap_or_else(|| self.new_error_node(&t)), + self.parse_simple_keyset_expression(&node_child_0) + .unwrap_or_else(|| self.new_error_node(&node_child_0)), &mut self.arena, ); transition_node.append( - self.parse_simple_expression_list(&tt) - .unwrap_or_else(|| self.new_error_node(&tt)), + self.parse_simple_expression_list(&node_child_1) + .unwrap_or_else(|| self.new_error_node(&node_child_1)), &mut self.arena, ); } @@ -2894,7 +2958,7 @@ impl TreesitterTranslator { node_id.append(self.new_error_node(&child), &mut self.arena); } else if let Some(t) = self.look_for_preproc_kind(&child) { node_id.append(t, &mut self.arena); - } else { + } else if !self.is_comment(&child) { let child_node_id = self.arena .new_node(Node::new(NodeKind::Annotation, node, &self.source_code)); @@ -2951,20 +3015,20 @@ impl TreesitterTranslator { node_id.append(self.new_error_node(&child), &mut self.arena); } else if let Some(t) = self.look_for_preproc_kind(&child) { node_id.append(t, &mut self.arena); - } else { + } else if !self.is_comment(&child) { let child_node_id = self.arena .new_node(Node::new(NodeKind::Kv, node, &self.source_code)); // Add name node - let node_name = child.named_child(0).unwrap(); + let node_name = child.named_child(self.get_named_child(&child, 0)?).unwrap(); let name_node = self.arena .new_node(Node::new(NodeKind::Name, &node_name, &self.source_code)); child_node_id.append(name_node, &mut self.arena); // Add value node - let node_value = child.named_child(1).unwrap(); + let node_value = child.named_child(self.get_named_child(&child, 1)?).unwrap(); child_node_id.append( self.parse_value(&node_value) .unwrap_or_else(|| self.new_error_node(&node_value)), @@ -3024,7 +3088,7 @@ impl TreesitterTranslator { node_id.append(self.new_error_node(&child), &mut self.arena); } else if let Some(t) = self.look_for_preproc_kind(&child) { node_id.append(t, &mut self.arena); - } else { + } else if !self.is_comment(&child) { node_id.append( self.parse_value(&child) .unwrap_or_else(|| self.new_error_node(&child)), @@ -3102,7 +3166,7 @@ impl TreesitterTranslator { node_id.append(self.new_error_node(&child), &mut self.arena); } else if let Some(t) = self.look_for_preproc_kind(&child) { node_id.append(t, &mut self.arena); - } else { + } else if !self.is_comment(&child) { node_id.append( self.parse_simple_keyset_expression(&child) .unwrap_or_else(|| self.new_error_node(&child)), From a87fa0d556e1d25e0ad44a6ca4d6f1a2b7791296 Mon Sep 17 00:00:00 2001 From: MaelC001 <55336346+MaelC001@users.noreply.github.com> Date: Fri, 14 Jul 2023 14:45:01 -0400 Subject: [PATCH 17/19] debug --- src/metadata/ast/translator.rs | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/src/metadata/ast/translator.rs b/src/metadata/ast/translator.rs index 49cf109..2401014 100644 --- a/src/metadata/ast/translator.rs +++ b/src/metadata/ast/translator.rs @@ -4,8 +4,6 @@ use super::tree::{Ast, Direction, Node, NodeKind, TypeDecType}; use crate::metadata::types::{BaseType, Type}; use crate::utils; -// todo : argument_list + annotation + expression value - pub struct TreesitterTranslator { arena: Arena, source_code: String, @@ -197,13 +195,11 @@ impl TreesitterTranslator { let mut cursor = node_param_type.walk(); for child in node_param_type.named_children(&mut cursor) { - if child.kind() == "preproc_include_declaration" { - if let Some(t) = self.parse_preproc_include(&child) { - node_param_type_id.append(t, &mut self.arena); - } + if child.is_error(){ + node_param_type_id.append(self.new_error_node(&child), &mut self.arena); } else if let Some(t) = self.look_for_preproc_kind(&child) { node_param_type_id.append(t, &mut self.arena); - } else { + } else if !self.is_comment(&child) { let child_id = self.arena .new_node(Node::new(NodeKind::Name, &child, &self.source_code)); @@ -371,7 +367,7 @@ impl TreesitterTranslator { } // Add name node - let node_name = node.child(self.get_child(&node, 3)?).unwrap(); + let node_name = node.child(self.get_named_child(&node, 0)?).unwrap(); let name_node = self.arena .new_node(Node::new(NodeKind::Name, &node_name, &self.source_code)); @@ -1613,7 +1609,6 @@ impl TreesitterTranslator { } let type_node = node.child_by_field_name("type").unwrap(); if type_node.kind() == "type_ref" { - // TODO fn_node_id.append( self.parse_type_ref(&type_node, NodeKind::Type, true) .unwrap_or_else(|| self.new_error_node(&type_node)), @@ -1763,7 +1758,7 @@ impl TreesitterTranslator { fn parse_name_assignment(&mut self, node_t: &tree_sitter::Node) -> Option { let node_first = *node_t; let mut last_node: Option = None; - if let Some(mut node) = node_t.child(self.get_child(&node_t, 0)?) { + if let Some(mut node) = node_t.child(self.get_named_child(&node_t, 0)?) { let mut bool = true; while bool { match node.kind() { @@ -2897,7 +2892,7 @@ impl TreesitterTranslator { } if let Some(x) = body_child.child_by_field_name("type") { - // todo - preproc + // // todo-preproc if x.kind() == "tuple_keyset_expression" { if let Some(y) = x.child_by_field_name("reduce") { transition_node.append( From 9822a2f99cabf324ba46fb2d1ce8f3f2b258f885 Mon Sep 17 00:00:00 2001 From: MaelC001 <55336346+MaelC001@users.noreply.github.com> Date: Mon, 17 Jul 2023 14:59:30 -0400 Subject: [PATCH 18/19] debug + add expression to define --- examples/basic.p4 | 21 +- src/metadata/ast/translator.rs | 344 ++++++++++++++++++++++++++++++--- src/metadata/ast/tree.rs | 19 ++ src/metadata/symbol_table.rs | 17 +- src/metadata/types.rs | 1 + 5 files changed, 374 insertions(+), 28 deletions(-) diff --git a/examples/basic.p4 b/examples/basic.p4 index 9d73968..8f036ee 100644 --- a/examples/basic.p4 +++ b/examples/basic.p4 @@ -1,6 +1,6 @@ /* -*- P4_16 -*- */ #include -#include +#include "v1model.p4" const bit<16> TYPE_IPV4 = 0x800; @@ -8,9 +8,16 @@ const bit<16> TYPE_IPV4 = 0x800; *********************** H E A D E R S *********************************** *************************************************************************/ -typedef bit<9> egressSpec_t; +#define KEY 12 +#define KEY4 ( 12 / 2 + 3*(3-4*5+4)-3+KEY + TYPE_IPV4(KEY,KEY)) +#define KEY1 ("aaa") +#define KEY0 (0) +#define KEY2 (u8'afdsfds') +#define KEY3 + typedef bit<48> macAddr_t; -typedef bit<32> ip4Addr_t; +typedef bit egressSpec_t; +typedef bit ip4Addr_t; header ethernet_t { macAddr_t dstAddr; @@ -31,6 +38,7 @@ header ipv4_t { bit<16> hdrChecksum; ip4Addr_t srcAddr; ip4Addr_t dstAddr; + #define KEY23 12 } struct metadata { @@ -49,11 +57,13 @@ struct headers { parser MyParser(packet_in packet, out headers hdr, inout metadata meta, + #define KEY4 inout standard_metadata_t standard_metadata) { bit<16> test = TYPE_IPV4; egressSpec_t test2 = 1; bit<16> test3 = 0x80; bit<16> test4 = 0x50; + #define KEY64 state start { transition parse_ethernet; @@ -63,6 +73,7 @@ parser MyParser(packet_in packet, packet.extract(hdr.ethernet); transition select(hdr.ethernet.etherType) { TYPE_IPV4: parse_ipv4; + #define KEY641 default: accept; } } @@ -121,10 +132,12 @@ control MyIngress(inout headers hdr, key = { hdr.ipv4.dstAddr: lpm; } + #define KEY64 actions = { ipv4_forward; drop; NoAction; + #define KEY64 } size = 1024; default_action = drop(); @@ -191,6 +204,8 @@ MyParser(), MyVerifyChecksum(), MyIngress(), MyEgress(), + + #define KEY64 MyComputeChecksum(), MyDeparser() ) main; diff --git a/src/metadata/ast/translator.rs b/src/metadata/ast/translator.rs index 2401014..6a17f67 100644 --- a/src/metadata/ast/translator.rs +++ b/src/metadata/ast/translator.rs @@ -43,7 +43,6 @@ impl TreesitterTranslator { let tree = self.tree.clone(); let mut cursor = tree.walk(); for child in tree.root_node().named_children(&mut cursor) { - debug!("{:?}", child); let new_child = if child.is_error() { Some(self.new_error_node(&child)) } else { @@ -60,7 +59,7 @@ impl TreesitterTranslator { "extern_declaration" => self.parse_extern(&child), "preproc_include_declaration" => self.parse_preproc_include(&child), - "preproc_define_declaration" | "preproc_define_declaration_macro" => { + "preproc_define_declaration" => { self.parse_preproc_define(&child) } "preproc_undef_declaration" => self.parse_preproc_undef(&child), @@ -320,7 +319,7 @@ impl TreesitterTranslator { let kind = node.kind(); if kind == "preproc_include_declaration" { return self.parse_preproc_include(&node); - } else if kind == "preproc_define_declaration" || kind == "preproc_define_declaration_macro" + } else if kind == "preproc_define_declaration" { return self.parse_preproc_define(&node); } else if kind == "preproc_undef_declaration" { @@ -334,10 +333,9 @@ impl TreesitterTranslator { let mut cursor = node.walk(); for child in node.named_children(&mut cursor) { - debug!("{:?}", child); let new_child = match child.kind() { "preproc_include_declaration" => self.parse_preproc_include(&child), - "preproc_define_declaration" | "preproc_define_declaration_macro" => { + "preproc_define_declaration" => { self.parse_preproc_define(&child) } "preproc_undef_declaration" => self.parse_preproc_undef(&child), @@ -395,19 +393,12 @@ impl TreesitterTranslator { .new_node(Node::new(NodeKind::Name, &node_name, &self.source_code)); node_id.append(name_node, &mut self.arena); - // Add param node - if let Some(param_node) = node.child_by_field_name("param") { - node_id.append( - self.parse_params_define(¶m_node) - .unwrap_or_else(|| self.new_error_node(¶m_node)), - &mut self.arena, - ); - } + // Add body node if let Some(node_body) = node.child_by_field_name("body") { node_id.append( - self.parse_value(&node_body) + self.parse_value_preproc(&node_body) .unwrap_or_else(|| self.new_error_node(&node_body)), &mut self.arena, ); @@ -420,11 +411,316 @@ impl TreesitterTranslator { .new_node(Node::new(NodeKind::Body, &node_body, &self.source_code)), &mut self.arena, ); + + // Add param node + if let Some(param_node) = node.child_by_field_name("param") { + node_id.append( + self.parse_params_define(¶m_node) + .unwrap_or_else(|| self.new_error_node(¶m_node)), + &mut self.arena, + ); + } else if let Some(param_node) = node.child_by_field_name("dont_know") { + node_id.append( + self.parse_params_define(¶m_node) + .unwrap_or_else(|| self.new_error_node(¶m_node)), + &mut self.arena, + ); + } + } else if let Some(value_node) = node.child_by_field_name("dont_know") { + node_id.append( + self.parse_value_preproc(&value_node) + .unwrap_or_else(|| self.new_error_node(&value_node)), + &mut self.arena, + ); } Some(node_id) } + fn parse_value_preproc(&mut self, node: &tree_sitter::Node) -> Option { + // todo-preproc + fn loop_value( + node_value: &mut NodeId, + last_node: NodeId, + node: &tree_sitter::Node, + self_v: &mut TreesitterTranslator, + ) -> NodeId { + let kind = node.kind(); + //debug!("{}", kind); + let mut name_node: NodeId = last_node; + match kind { + "bool" => { + name_node = self_v.arena.new_node(Node::new( + NodeKind::Type(Type::Base(BaseType::Bool)), + node, + &self_v.source_code, + )); + node_value.append(name_node, &mut self_v.arena); + } + "number_preproc" => { + name_node = self_v.arena.new_node(Node::new( + NodeKind::Type(Type::Base(BaseType::Num)), + node, + &self_v.source_code, + )); + node_value.append(name_node, &mut self_v.arena); + } + "string_for_preproc" => { + name_node = self_v.arena.new_node(Node::new( + NodeKind::Type(Type::Base(BaseType::String)), + node, + &self_v.source_code, + )); + node_value.append(name_node, &mut self_v.arena); + } + "identifier" => { + name_node = self_v.arena.new_node(Node::new( + NodeKind::Type(Type::Name), + node, + &self_v.source_code, + )); + node_value.append(name_node, &mut self_v.arena); + } + "null_value" => { + name_node = self_v.arena.new_node(Node::new( + NodeKind::Type(Type::Base(BaseType::Null)), + node, + &self_v.source_code, + )); + node_value.append(name_node, &mut self_v.arena); + } + + "preproc_call_expression" => { + let expression_node = self_v.arena.new_node(Node::new( + NodeKind::ExpressionCall, + node, + &self_v.source_code, + )); + let name_function_node = self_v.arena.new_node(Node::new( + NodeKind::Type(Type::Name), + &node.child_by_field_name("function").unwrap(), + &self_v.source_code, + )); + expression_node.append(name_function_node, &mut self_v.arena); + + let t = node.child_by_field_name("arguments").unwrap(); + let args_function_node = self_v.arena.new_node(Node::new( + NodeKind::Args, + &t, + &self_v.source_code, + )); + + let mut cursor = t.walk(); + for syntax_child in t.named_children(&mut cursor) { + if syntax_child.is_error() { + args_function_node.append(self_v.new_error_node(&syntax_child), &mut self_v.arena); + } else if syntax_child.kind() == "preproc_expression" { + let arg_function_node = self_v.arena.new_node(Node::new( + NodeKind::Arg, + &syntax_child, + &self_v.source_code, + )); + let t = loop_value( + &mut arg_function_node.clone(), + arg_function_node.clone(), + &syntax_child, + self_v, + ); + + //arg_function_node.append(t, &mut self_v.arena); + args_function_node.append(arg_function_node, &mut self_v.arena); + } + } + + expression_node.append(args_function_node, &mut self_v.arena); + + name_node = expression_node; + + node_value.append(name_node, &mut self_v.arena); + + } + + "preproc_expression_1" => { + name_node = self_v.arena.new_node(Node::new( + NodeKind::Expression, + node, + &self_v.source_code, + )); + + let t = loop_value( + &mut name_node.clone(), + name_node.clone(), + &node.named_child(self_v.get_named_child(node, 0).unwrap()).unwrap(), + self_v, + ); + name_node.append(t, &mut self_v.arena); + + node_value.append(name_node, &mut self_v.arena); + } + "preproc_expression" => { + name_node = self_v.arena.new_node(Node::new( + NodeKind::Expression, + node, + &self_v.source_code, + )); + + let t = loop_value( + &mut name_node.clone(), + name_node.clone(), + &node.named_child(self_v.get_named_child(node, 0).unwrap()).unwrap(), + self_v, + ); + name_node.append(t, &mut self_v.arena); + + node_value.append(name_node, &mut self_v.arena); + } + "preproc_unary_expression" => { + name_node = self_v.arena.new_node(Node::new( + NodeKind::ExpressionUnary, + node, + &self_v.source_code, + )); + + let name_function_node = self_v.arena.new_node(Node::new( + NodeKind::Operator, + &node.child_by_field_name("operator").unwrap(), + &self_v.source_code, + )); + name_node.append(name_function_node, &mut self_v.arena); + + let t = node.child_by_field_name("argument").unwrap(); + let args_function_node = self_v.arena.new_node(Node::new( + NodeKind::Body, + &t, + &self_v.source_code, + )); + loop_value( + &mut args_function_node.clone(), + args_function_node.clone(), + &t, + self_v, + ); + //args_function_node.append(t, &mut self_v.arena); + name_node.append(args_function_node, &mut self_v.arena); + + node_value.append(name_node, &mut self_v.arena); + } + "preproc_binary_expression" => { + name_node = self_v.arena.new_node(Node::new( + NodeKind::ExpressionBinary, + node, + &self_v.source_code, + )); + + let mut t = node.child_by_field_name("operator").unwrap(); + let operator_node = self_v.arena.new_node(Node::new( + NodeKind::Operator, + &t, + &self_v.source_code, + )); + name_node.append(operator_node, &mut self_v.arena); + + let mut t = node.child_by_field_name("left").unwrap(); + let left_node = self_v.arena.new_node(Node::new( + NodeKind::ExpressionBinaryLeft, + &t, + &self_v.source_code, + )); + loop_value( + &mut left_node.clone(), + left_node.clone(), + &t, + self_v, + ); + name_node.append(left_node, &mut self_v.arena); + + t = node.child_by_field_name("right").unwrap(); + let right_node = self_v.arena.new_node(Node::new( + NodeKind::ExpressionBinaryRight, + &t, + &self_v.source_code, + )); + loop_value( + &mut right_node.clone(), + right_node.clone(), + &t, + self_v, + ); + name_node.append(right_node, &mut self_v.arena); + + node_value.append(name_node, &mut self_v.arena); + } + + /* + preproc_binary_expression: $ => { + const table = [ + ['+', PREC.ADD], + ['-', PREC.ADD], + ['*', PREC.MULTIPLY], + ['/', PREC.MULTIPLY], + ['%', PREC.MULTIPLY], + ['||', PREC.LOGICAL_OR], + ['&&', PREC.LOGICAL_AND], + ['|', PREC.INCLUSIVE_OR], + ['^', PREC.EXCLUSIVE_OR], + ['&', PREC.BITWISE_AND], + ['==', PREC.EQUAL], + ['!=', PREC.EQUAL], + ['>', PREC.RELATIONAL], + ['>=', PREC.RELATIONAL], + ['<=', PREC.RELATIONAL], + ['<', PREC.RELATIONAL], + ['<<', PREC.SHIFT], + ['>>', PREC.SHIFT], + ]; + + return choice(...table.map(([operator, precedence]) => { + return prec.left(precedence, seq( + field('left', $.preproc_expression), + // @ts-ignore + field('operator', operator), + field('right', $.preproc_expression), + )); + })); + }, */ + "preproc_parenthesized_expression" => { + name_node = self_v.arena.new_node(Node::new( + NodeKind::ExpressionParenthesized, + node, + &self_v.source_code, + )); + + let t = node.named_child(self_v.get_named_child(node, 0).unwrap()).unwrap(); + loop_value( + &mut name_node.clone(), + name_node.clone(), + &t, + self_v, + ); + node_value.append(name_node, &mut self_v.arena); + } + _ => {} + } + name_node + } + + let mut node_value = + self.arena + .new_node(Node::new(NodeKind::Value, node, &self.source_code)); + + let kind = node.kind(); + let child: tree_sitter::Node<'_>; + if kind == "preproc_expression_paranthesis" { + child = node.named_child(self.get_named_child(&node, 0)?)?; + } else { + child = node.clone(); + } + + let last_node = node_value; + loop_value(&mut node_value, last_node, &child, self); + + Some(node_value) + } fn parse_params_define(&mut self, node: &tree_sitter::Node) -> Option { let params_node_id = self.arena @@ -1327,7 +1623,7 @@ impl TreesitterTranslator { "parser_state" => self.parse_state(&syntax_child), "preproc_include_declaration" => self.parse_preproc_include(&syntax_child), - "preproc_define_declaration" | "preproc_define_declaration_macro" => { + "preproc_define_declaration" => { self.parse_preproc_define(&syntax_child) } "preproc_undef_declaration" => self.parse_preproc_undef(&syntax_child), @@ -1413,7 +1709,7 @@ impl TreesitterTranslator { "block_statement" => self.parse_block(&syntax_child), "preproc_include_declaration" => self.parse_preproc_include(&syntax_child), - "preproc_define_declaration" | "preproc_define_declaration_macro" => { + "preproc_define_declaration" => { self.parse_preproc_define(&syntax_child) } "preproc_undef_declaration" => self.parse_preproc_undef(&syntax_child), @@ -1562,7 +1858,7 @@ impl TreesitterTranslator { "instantiation" => self.instantiation(&syntax_child), "preproc_include_declaration" => self.parse_preproc_include(&syntax_child), - "preproc_define_declaration" | "preproc_define_declaration_macro" => { + "preproc_define_declaration" => { self.parse_preproc_define(&syntax_child) } "preproc_undef_declaration" => self.parse_preproc_undef(&syntax_child), @@ -1674,7 +1970,7 @@ impl TreesitterTranslator { "switch_statement" => self.switch_statement(&syntax_child), "preproc_include_declaration" => self.parse_preproc_include(&syntax_child), - "preproc_define_declaration" | "preproc_define_declaration_macro" => { + "preproc_define_declaration" => { self.parse_preproc_define(&syntax_child) } "preproc_undef_declaration" => self.parse_preproc_undef(&syntax_child), @@ -1868,7 +2164,7 @@ impl TreesitterTranslator { } } } - "preproc_define_declaration" | "preproc_define_declaration_macro" => { + "preproc_define_declaration" => { if let Some(t) = self.parse_preproc_define(&node) { if let Some(x) = last_node { x.append(t, &mut self.arena); @@ -1957,7 +2253,7 @@ impl TreesitterTranslator { ))), "preproc_include_declaration" => self.parse_preproc_include(&syntax_child), - "preproc_define_declaration" | "preproc_define_declaration_macro" => { + "preproc_define_declaration" => { self.parse_preproc_define(&syntax_child) } "preproc_undef_declaration" => self.parse_preproc_undef(&syntax_child), @@ -2057,7 +2353,7 @@ impl TreesitterTranslator { "conditional_statement" => self.parse_state_conditional(&body_child), "preproc_include_declaration" => self.parse_preproc_include(&body_child), - "preproc_define_declaration" | "preproc_define_declaration_macro" => { + "preproc_define_declaration" => { self.parse_preproc_define(&body_child) } "preproc_undef_declaration" => self.parse_preproc_undef(&body_child), @@ -2152,7 +2448,7 @@ impl TreesitterTranslator { "switch_statement" => self.switch_statement(&body_child), "preproc_include_declaration" => self.parse_preproc_include(&body_child), - "preproc_define_declaration" | "preproc_define_declaration_macro" => { + "preproc_define_declaration" => { self.parse_preproc_define(&body_child) } "preproc_undef_declaration" => self.parse_preproc_undef(&body_child), @@ -2677,7 +2973,7 @@ impl TreesitterTranslator { "preproc_include_declaration" => { child_node_id = self.parse_preproc_include(&table_child) } - "preproc_define_declaration" | "preproc_define_declaration_macro" => { + "preproc_define_declaration" => { child_node_id = self.parse_preproc_define(&table_child) } "preproc_undef_declaration" => { @@ -2785,7 +3081,7 @@ impl TreesitterTranslator { "conditional_statement" => self.parse_state_conditional(&body_child), "preproc_include_declaration" => self.parse_preproc_include(&body_child), - "preproc_define_declaration" | "preproc_define_declaration_macro" => { + "preproc_define_declaration" => { self.parse_preproc_define(&body_child) } "preproc_undef_declaration" => self.parse_preproc_undef(&body_child), diff --git a/src/metadata/ast/tree.rs b/src/metadata/ast/tree.rs index a8d3d7d..f9fdec6 100644 --- a/src/metadata/ast/tree.rs +++ b/src/metadata/ast/tree.rs @@ -53,6 +53,13 @@ pub enum NodeKind { Direction(Direction), TypeDec(TypeDecType), Expression, + ExpressionCall, + ExpressionUnary, + ExpressionBinary, + ExpressionBinaryLeft, + ExpressionBinaryRight, + ExpressionParenthesized, + Operator, Name, Param, Params, @@ -166,6 +173,7 @@ pub trait Visitable { fn get_subscopes(&self) -> Vec; fn get_type_node(&self) -> Option; fn get_value_node(&self) -> Option; + fn get_expression_node(&self) -> Option; fn get_value_symbol_node(&self) -> Option; fn get_type(&self) -> Option; fn get_node_at_position(&self, position: Position) -> Option; @@ -240,6 +248,17 @@ impl Visitable for VisitNode<'_> { }) } + fn get_expression_node(&self) -> Option { + self.get_children().into_iter().find_map(|child| { + let node = child.get(); + if matches!(node.kind, NodeKind::Expression) { + Some(VisitNode::new(self.arena, child.id)) + } else { + None + } + }) + } + fn get_value_symbol_node(&self) -> Option { self.get_children().into_iter().find_map(|child| { let node = child.get(); diff --git a/src/metadata/symbol_table.rs b/src/metadata/symbol_table.rs index f83a5ab..04a82ea 100644 --- a/src/metadata/symbol_table.rs +++ b/src/metadata/symbol_table.rs @@ -358,7 +358,7 @@ impl SymbolTable { symbol.usages.push(node_symbol.range); if bool_preproc{ if let Some(type_symbol) = symbol.type_.get_name() { - if type_symbol == Type::Base(BaseType::Int) { + if type_symbol == Type::Base(BaseType::Num){ } else { self.error_list.push(node_symbol.range) } @@ -632,15 +632,30 @@ impl ScopeSymbolTable { let type_ = if value_type { let type_node = child_visit_node.get_value_node(); let mut temp: Option = None; + let mut bool = true; if let Some(value_node) = type_node { for child in value_node.get_children() { let type_node = child.get(); if let Some(x) = child.get_type() { node = Some(type_node.clone()); temp = Some(x); + bool = false; break; } } + if bool{ + let expression_node = value_node.get_expression_node(); + if let Some(expression_node) = expression_node { + for child in expression_node.get_children() { + let type_node = child.get(); + if let Some(x) = child.get_type() { + node = Some(type_node.clone()); + temp = Some(x); + break; + } + } + } + } } temp } else { diff --git a/src/metadata/types.rs b/src/metadata/types.rs index c9a5560..a24f07a 100644 --- a/src/metadata/types.rs +++ b/src/metadata/types.rs @@ -7,6 +7,7 @@ pub enum BaseType { MatchKind, String, Int, + Num, Bit, Varbit, Null, From 9dc4b43487b30d81e363d55e85966d9030059de5 Mon Sep 17 00:00:00 2001 From: MaelC001 <55336346+MaelC001@users.noreply.github.com> Date: Mon, 17 Jul 2023 15:10:51 -0400 Subject: [PATCH 19/19] small debug to get the value from define expression --- src/metadata/ast/translator.rs | 39 +--------------------------------- 1 file changed, 1 insertion(+), 38 deletions(-) diff --git a/src/metadata/ast/translator.rs b/src/metadata/ast/translator.rs index 6a17f67..29810ff 100644 --- a/src/metadata/ast/translator.rs +++ b/src/metadata/ast/translator.rs @@ -650,39 +650,6 @@ impl TreesitterTranslator { node_value.append(name_node, &mut self_v.arena); } - - /* - preproc_binary_expression: $ => { - const table = [ - ['+', PREC.ADD], - ['-', PREC.ADD], - ['*', PREC.MULTIPLY], - ['/', PREC.MULTIPLY], - ['%', PREC.MULTIPLY], - ['||', PREC.LOGICAL_OR], - ['&&', PREC.LOGICAL_AND], - ['|', PREC.INCLUSIVE_OR], - ['^', PREC.EXCLUSIVE_OR], - ['&', PREC.BITWISE_AND], - ['==', PREC.EQUAL], - ['!=', PREC.EQUAL], - ['>', PREC.RELATIONAL], - ['>=', PREC.RELATIONAL], - ['<=', PREC.RELATIONAL], - ['<', PREC.RELATIONAL], - ['<<', PREC.SHIFT], - ['>>', PREC.SHIFT], - ]; - - return choice(...table.map(([operator, precedence]) => { - return prec.left(precedence, seq( - field('left', $.preproc_expression), - // @ts-ignore - field('operator', operator), - field('right', $.preproc_expression), - )); - })); - }, */ "preproc_parenthesized_expression" => { name_node = self_v.arena.new_node(Node::new( NodeKind::ExpressionParenthesized, @@ -710,7 +677,7 @@ impl TreesitterTranslator { let kind = node.kind(); let child: tree_sitter::Node<'_>; - if kind == "preproc_expression_paranthesis" { + if kind == "preproc_expression_paranthesis" || kind == "preproc_define_declaration_param_1" { child = node.named_child(self.get_named_child(&node, 0)?)?; } else { child = node.clone(); @@ -743,10 +710,6 @@ impl TreesitterTranslator { } } - for node_preproc in self.look_for_preproc(&node) { - params_node_id.append(node_preproc, &mut self.arena); - } - Some(params_node_id) } fn parse_preproc_undef(&mut self, node: &tree_sitter::Node) -> Option {