tree-sitter-plpgsql/grammar.js

74 lines
2.0 KiB
JavaScript
Raw Normal View History

2021-08-21 20:15:42 +03:00
module.exports = grammar({
2021-08-28 13:46:32 +03:00
name: "plpgsql",
2023-01-06 23:52:08 +03:00
extras: ($) => [/\s\n/, /\s/, $.comment, $.marginalia],
2023-01-06 23:52:08 +03:00
word: ($) => $._identifier,
2023-01-06 23:52:08 +03:00
rules: {
source_file: ($) => repeat(choice($.statement)),
2023-01-06 23:52:08 +03:00
statement: ($) => seq(optional($._ddl_statement), ";"),
2023-01-06 23:52:08 +03:00
_ddl_statement: ($) => choice($._create_statement),
2023-01-06 23:52:08 +03:00
_create_statement: ($) => choice($.create_table),
2023-01-06 23:52:08 +03:00
// References: https://www.postgresql.org/docs/15/sql-createtable.html
create_table: ($) =>
seq(
2023-01-06 23:52:08 +03:00
$.keyword_create,
optional(choice($.keyword_temporary, $.keyword_unlogged)),
$.keyword_table,
optional($._if_not_exists),
$.table_reference,
$.column_definitions
),
2023-01-06 23:52:08 +03:00
table_reference: ($) =>
seq(
2023-01-06 23:52:08 +03:00
optional(seq(field("schema", $.identifier), ".")),
field("name", $.identifier)
),
2023-01-06 23:52:08 +03:00
column_definitions: ($) =>
seq(
"(",
2023-01-06 23:52:08 +03:00
optional(commaSepRepeat1(choice($.column_definition /*$.constraint*/))),
")"
),
2023-01-06 23:52:08 +03:00
column_definition: ($) => seq(field("name", $.identifier)),
2023-01-05 23:37:44 +03:00
2023-01-06 23:52:08 +03:00
//constraint: $ => seq(),
2023-01-05 23:37:44 +03:00
2023-01-06 23:52:08 +03:00
// keywords
keyword_create: (_) => mkKeyword("create"),
keyword_table: (_) => mkKeyword("table"),
keyword_temporary: (_) => choice(mkKeyword("temporary"), mkKeyword("temp")),
keyword_unlogged: (_) => mkKeyword("unlogged"),
keyword_if: (_) => mkKeyword("if"),
keyword_not: (_) => mkKeyword("not"),
keyword_exists: (_) => mkKeyword("exists"),
2023-01-05 23:37:44 +03:00
2023-01-06 23:52:08 +03:00
_if_not_exists: ($) => seq($.keyword_if, $.keyword_not, $.keyword_exists),
// -------
2023-01-05 23:37:44 +03:00
2023-01-06 23:52:08 +03:00
comment: (_) => seq("--", /.*\n/),
// https://stackoverflow.com/questions/13014947/regex-to-match-a-c-style-multiline-comment
marginalia: (_) => seq("/*", /[^*]*\*+(?:[^/*][^*]*\*+)*/, "/"),
2023-01-05 23:37:44 +03:00
2023-01-06 23:52:08 +03:00
identifier: ($) => choice($._identifier, seq('"', $._identifier, '"')),
2023-01-05 23:37:44 +03:00
2023-01-06 23:52:08 +03:00
_identifier: (_) => /([a-zA-Z_][0-9a-zA-Z_]*)/,
},
2021-08-21 20:15:42 +03:00
});
2023-01-06 23:52:08 +03:00
function mkKeyword(word) {
return new RegExp(word + "|" + word.toUpperCase());
}
function commaSepRepeat1(field) {
return seq(field, repeat(seq(",", field)));
}