84 lines
1.7 KiB
JavaScript
84 lines
1.7 KiB
JavaScript
|
function kw(keyword, aliasAsWord = true) {
|
||
|
let result = new RegExp(keyword
|
||
|
.split('')
|
||
|
.map(l => l !== l.toUpperCase() ? `[${l}${l.toUpperCase()}]` : l)
|
||
|
.join('')
|
||
|
);
|
||
|
if (aliasAsWord) {
|
||
|
result = alias(result, keyword);
|
||
|
}
|
||
|
return result;
|
||
|
}
|
||
|
|
||
|
function delimited(left, rule, right = left) {
|
||
|
return seq(left, rule, right)
|
||
|
}
|
||
|
|
||
|
function separated(separator, rule) {
|
||
|
return choice(
|
||
|
optional(rule),
|
||
|
seq(rule, repeat1(seq(",", rule))))
|
||
|
}
|
||
|
|
||
|
module.exports = grammar({
|
||
|
name: 'plpgsql',
|
||
|
|
||
|
rules: {
|
||
|
source_file: $ => repeat($._statement),
|
||
|
|
||
|
_statement: $ => seq(
|
||
|
choice(
|
||
|
$.create_function_statement,
|
||
|
),
|
||
|
";"
|
||
|
),
|
||
|
|
||
|
create_function_statement: $ => seq(
|
||
|
kw("CREATE"), optional($.or_replace), kw("FUNCTION"),
|
||
|
$.function_signature,
|
||
|
optional(seq(kw("RETURNS"), $.identifier)),
|
||
|
kw("AS"), $.block,
|
||
|
kw("LANGUAGE"), $.identifier,
|
||
|
optional($.function_volatility)
|
||
|
),
|
||
|
|
||
|
function_volatility: $ => choice(
|
||
|
kw("IMMUTABLE"),
|
||
|
kw("STABLE"),
|
||
|
kw("VOLATILE"),
|
||
|
),
|
||
|
|
||
|
block: $ => seq(
|
||
|
$.dollar_quote,
|
||
|
$.dollar_quote,
|
||
|
),
|
||
|
|
||
|
dollar_quote: $ => delimited("$", optional($.identifier)),
|
||
|
|
||
|
function_signature: $ => seq(
|
||
|
$.identifier,
|
||
|
$.function_parameters,
|
||
|
),
|
||
|
|
||
|
function_parameters: $ => seq(
|
||
|
"(",
|
||
|
separated(",", $.function_parameter),
|
||
|
")"
|
||
|
),
|
||
|
|
||
|
function_parameter: $ => seq(
|
||
|
field("name", $.identifier),
|
||
|
field("type", $._type),
|
||
|
),
|
||
|
|
||
|
or_replace: $ => seq("OR", "REPLACE"),
|
||
|
|
||
|
_type: $ => choice(
|
||
|
$.identifier,
|
||
|
seq($._type, "[", "]"),
|
||
|
),
|
||
|
|
||
|
identifier: $ => /[a-zA-Z0-9_]+[.a-zA-Z0-9_]*/,
|
||
|
}
|
||
|
});
|