Files
OSN-grammar/grammar.js

55 lines
2.8 KiB
JavaScript

module.exports = grammar({
name: 'OpenScenarioNext',
extras: $ => [ /\s/, $.comment ],
word: $ => $.identifier,
rules: {
// The production rules of the context-free grammar
source_file: $ => $.scenario,
scenario: $ => seq( 'Scenario', $.identifier, ':', repeat($.act), optional($.prototypes), optional($.resources)),
act: $ => seq( 'Act', $.identifier, ':', repeat1($.rule)),
rule: $ => prec.left(seq( '@', $.condition, optional( $.modifier), ':', repeat1($.action))),
modifier: $ => seq( '%', $.identifier),
condition: $ => choice( $.predicate, $.relation_expr, $.binary_expr ),
relation_expr: $ => seq( $.scalar_expr, $.relation_op, $.scalar_expr ),
relation_op: $ => choice( '<', '>', '<=', '>=', '==', '!=' ),
binary_expr: $ => choice( $.and_expr, $.or_expr),
and_expr: $ => prec.left(2, seq( $.condition, 'and', $.condition )),
or_expr: $ => prec.left(1, seq( $.condition, 'or', $.condition )),
predicate: $ => choice( $.atomic_predicate, $.function_application ),
atomic_predicate: $ => choice( $.init_predicate, $.start_predicate, $.stop_predicate),
init_predicate: $ => 'init',
start_predicate: $ => 'start',
stop_predicate: $ => 'stop',
action: $ => $.function_application,
function_application: $ => seq( $.identifier, '(', optional( seq( $.argument, repeat(seq(',',$.argument)))) , ')' ),
argument: $ => choice( $.arg_expr, $.named_arg ),
arg_expr: $ => choice( $.scalar_expr, $.coordinate_expr ),
scalar_expr: $ => choice( $.identifier, $.record_expr, $.literal, $.function_application, $.arithmetic_expr ),
named_arg: $ => seq( $.identifier, '=', $.arg_expr ),
record_expr: $ => prec.left(seq( $.identifier, '.', $.identifier )),
arithmetic_expr: $ => choice( $.product_expr, $.sum_expr),
product_expr: $ => prec.left(2, seq( $.scalar_expr, choice('*','/'), $.scalar_expr )),
sum_expr: $ => prec.left(1, seq( $.scalar_expr, choice('+','-'), $.scalar_expr )),
coordinate_expr: $ => seq( $.scalar_expr, '|', $.scalar_expr, '|', $.scalar_expr ),
prototypes: $ => seq( 'Prototypes:', repeat($.prototype)),
prototype: $ => seq( $.identifier, ':', $.function_application),
resources: $ => seq( 'Resources:', repeat($.resource)),
resource: $ => seq( $.identifier, ':', $.function_application),
literal: $ => choice ( $.numeric_literal, $.unit_literal, $.string_literal ),
numeric_literal: $ => /[-+]?[0-9]+([.][0-9]+)?([eE][-+]?[0-9]+)?/,
unit_literal: $ => seq( $.numeric_literal, $.unit ),
unit: $ => choice( 'm', 'km', 'cm', 'mm', 'km/h', 'm/s', 'min', 'h', 's' ),
string_literal: $ => token(seq('"', /[^"]*/, '"')),
identifier: $ => /[A-Za-z][A-Za-z0-9_]*/,
comment: $ => token(choice(seq('//', /.*/),
seq('/*', /[^*]*\*+([^/*][^*]*\*+)*/, '/')))
}
});