feat(grammar): update tree-sitter grammar to v0.3.0
Updated tree-sitter grammar to match v0.3.0 LALRPOP parser: Grammar updates: - Schedule: block-based syntax with extends, override, recurrence - Life arc: requires clause for field validation - Template: uses behaviors/schedules syntax - Behavior: correct keywords (choose/then/repeat with optional params) - Type system: concept_comparison with any/is_condition - Removed concept semicolon requirement Query file updates: - highlights.scm: updated node names to *_declaration - outline.scm: updated for new declaration node names - indents.scm: updated node names, removed concept semicolon Corpus test updates: - Created schedules.txt with v0.3.0 syntax tests - Created highlights.txt for highlighting tests - Updated type_system.txt for v0.3.0 type syntax - Updated behaviors.txt for correct expression wrapping - Updated declarations.txt to use correct node names - Updated basic.txt to use character_declaration/character_body - Deleted obsolete v0.2.0 syntax tests Integration tests: - Added tree_sitter_integration.rs test suite - Fixed test_any_type to use correct v0.3.0 syntax - Fixed test_tree_sitter_grammar_builds to use generate command
This commit is contained in:
@@ -21,7 +21,8 @@ module.exports = grammar({
|
||||
|
||||
conflicts: $ => [
|
||||
[$.path_segments],
|
||||
[$.sub_concept_enum_body, $.sub_concept_record_body]
|
||||
[$.sub_concept_enum_body, $.sub_concept_record_body],
|
||||
[$.uses_behaviors]
|
||||
],
|
||||
|
||||
word: $ => $.identifier,
|
||||
@@ -37,15 +38,15 @@ module.exports = grammar({
|
||||
// Declarations
|
||||
declaration: $ => choice(
|
||||
$.use_declaration,
|
||||
$.character,
|
||||
$.template,
|
||||
$.life_arc,
|
||||
$.schedule,
|
||||
$.behavior,
|
||||
$.institution,
|
||||
$.relationship,
|
||||
$.location,
|
||||
$.species,
|
||||
$.character_declaration,
|
||||
$.template_declaration,
|
||||
$.life_arc_declaration,
|
||||
$.schedule_declaration,
|
||||
$.behavior_declaration,
|
||||
$.institution_declaration,
|
||||
$.relationship_declaration,
|
||||
$.location_declaration,
|
||||
$.species_declaration,
|
||||
$.enum_declaration,
|
||||
$.concept_declaration,
|
||||
$.sub_concept,
|
||||
@@ -68,28 +69,59 @@ module.exports = grammar({
|
||||
path_segments: $ => sep1($.identifier, token('::')),
|
||||
|
||||
// Character declaration
|
||||
character: $ => seq(
|
||||
character_declaration: $ => seq(
|
||||
'character',
|
||||
field('name', $.identifier),
|
||||
optional(seq(':', field('species', $.identifier))),
|
||||
optional(field('template', $.template_clause)),
|
||||
field('body', $.block)
|
||||
field('body', $.character_body)
|
||||
),
|
||||
|
||||
character_body: $ => seq(
|
||||
'{',
|
||||
repeat($.field),
|
||||
'}'
|
||||
),
|
||||
|
||||
template_clause: $ => seq('from', commaSep1($.identifier)),
|
||||
|
||||
// Template declaration
|
||||
template: $ => seq(
|
||||
template_declaration: $ => seq(
|
||||
'template',
|
||||
field('name', $.identifier),
|
||||
optional(seq(':', field('species', $.identifier))),
|
||||
optional('strict'),
|
||||
field('body', $.template_body)
|
||||
),
|
||||
|
||||
template_body: $ => seq(
|
||||
'{',
|
||||
repeat($.include),
|
||||
repeat($.field),
|
||||
repeat(choice(
|
||||
$.include,
|
||||
$.uses_behaviors,
|
||||
$.uses_schedule,
|
||||
$.field
|
||||
)),
|
||||
'}'
|
||||
),
|
||||
|
||||
uses_behaviors: $ => seq(
|
||||
'uses',
|
||||
'behaviors',
|
||||
':',
|
||||
commaSep1($.identifier)
|
||||
),
|
||||
|
||||
uses_schedule: $ => seq(
|
||||
'uses',
|
||||
choice('schedule', 'schedules'),
|
||||
':',
|
||||
choice(
|
||||
$.identifier,
|
||||
seq('[', commaSep1($.identifier), ']')
|
||||
)
|
||||
),
|
||||
|
||||
include: $ => seq('include', $.identifier),
|
||||
|
||||
// Fields (key: value pairs)
|
||||
@@ -177,18 +209,36 @@ module.exports = grammar({
|
||||
)))),
|
||||
|
||||
// Life arc declaration
|
||||
life_arc: $ => seq(
|
||||
life_arc_declaration: $ => seq(
|
||||
'life_arc',
|
||||
field('name', $.identifier),
|
||||
optional(field('requires', $.requires_clause)),
|
||||
'{',
|
||||
repeat($.field),
|
||||
repeat($.arc_state),
|
||||
repeat($.state_block),
|
||||
'}'
|
||||
),
|
||||
|
||||
arc_state: $ => seq(
|
||||
requires_clause: $ => seq(
|
||||
'requires',
|
||||
'{',
|
||||
commaSep1($.required_field),
|
||||
'}'
|
||||
),
|
||||
|
||||
required_field: $ => seq(
|
||||
field('name', $.identifier),
|
||||
':',
|
||||
field('type', $.identifier)
|
||||
),
|
||||
|
||||
state_block: $ => seq(
|
||||
'state',
|
||||
field('name', $.identifier),
|
||||
field('body', $.state_body)
|
||||
),
|
||||
|
||||
state_body: $ => seq(
|
||||
'{',
|
||||
optional($.on_enter),
|
||||
repeat($.field),
|
||||
@@ -206,28 +256,76 @@ module.exports = grammar({
|
||||
),
|
||||
|
||||
// Schedule declaration
|
||||
schedule: $ => seq(
|
||||
schedule_declaration: $ => seq(
|
||||
'schedule',
|
||||
field('name', $.identifier),
|
||||
optional(seq('extends', field('extends', $.identifier))),
|
||||
field('body', $.schedule_body)
|
||||
),
|
||||
|
||||
schedule_body: $ => seq(
|
||||
'{',
|
||||
repeat($.field),
|
||||
repeat($.schedule_block),
|
||||
repeat(choice(
|
||||
$.field,
|
||||
$.schedule_block,
|
||||
$.override_block,
|
||||
$.recurrence_block
|
||||
)),
|
||||
'}'
|
||||
),
|
||||
|
||||
// Named block: block name { time range, action, fields }
|
||||
schedule_block: $ => seq(
|
||||
'block',
|
||||
field('name', $.identifier),
|
||||
'{',
|
||||
field('time_range', $.time_range),
|
||||
repeat($.block_field),
|
||||
'}'
|
||||
),
|
||||
|
||||
// Override block: override name { time range, action, fields }
|
||||
override_block: $ => seq(
|
||||
'override',
|
||||
field('name', $.identifier),
|
||||
'{',
|
||||
field('time_range', $.time_range),
|
||||
repeat($.block_field),
|
||||
'}'
|
||||
),
|
||||
|
||||
// Recurrence: recurrence Name on DayOfWeek { blocks }
|
||||
recurrence_block: $ => seq(
|
||||
'recurrence',
|
||||
field('name', $.identifier),
|
||||
'on',
|
||||
field('day', $.identifier),
|
||||
'{',
|
||||
repeat1($.schedule_block),
|
||||
'}'
|
||||
),
|
||||
|
||||
time_range: $ => seq(
|
||||
field('start', $.time),
|
||||
'->',
|
||||
field('end', $.time),
|
||||
optional(',')
|
||||
),
|
||||
|
||||
block_field: $ => seq(
|
||||
field('name', $.identifier),
|
||||
':',
|
||||
field('activity', $.identifier),
|
||||
$.block
|
||||
field('value', choice($.identifier, $.string, $.integer, $.float))
|
||||
),
|
||||
|
||||
// Behavior tree declaration
|
||||
behavior: $ => seq(
|
||||
behavior_declaration: $ => seq(
|
||||
'behavior',
|
||||
field('name', $.identifier),
|
||||
field('body', $.behavior_body)
|
||||
),
|
||||
|
||||
behavior_body: $ => seq(
|
||||
'{',
|
||||
repeat($.field),
|
||||
field('root', $.behavior_node),
|
||||
@@ -239,6 +337,7 @@ module.exports = grammar({
|
||||
$.sequence_node,
|
||||
$.condition_node,
|
||||
$.if_decorator_node,
|
||||
$.repeat_node,
|
||||
$.decorator_node,
|
||||
$.action_node,
|
||||
$.subtree_node
|
||||
@@ -281,7 +380,20 @@ module.exports = grammar({
|
||||
'}'
|
||||
),
|
||||
|
||||
// Decorator node: repeat/retry/timeout/etc { child }
|
||||
// Repeat node: repeat { child } or repeat(N) { child } or repeat(min..max) { child }
|
||||
repeat_node: $ => seq(
|
||||
'repeat',
|
||||
optional(field('params', choice(
|
||||
seq('(', $.integer, ')'),
|
||||
seq('(', $.integer, '..', $.integer, ')'),
|
||||
seq('(', $.duration, ')')
|
||||
))),
|
||||
'{',
|
||||
field('child', $.behavior_node),
|
||||
'}'
|
||||
),
|
||||
|
||||
// Decorator node: retry/timeout/etc { child }
|
||||
decorator_node: $ => seq(
|
||||
field('decorator', $.decorator_keyword),
|
||||
optional(field('params', $.decorator_params)),
|
||||
@@ -291,7 +403,6 @@ module.exports = grammar({
|
||||
),
|
||||
|
||||
decorator_keyword: $ => choice(
|
||||
'repeat',
|
||||
'invert',
|
||||
'retry',
|
||||
'timeout',
|
||||
@@ -330,16 +441,20 @@ module.exports = grammar({
|
||||
subtree_node: $ => seq('include', $.path),
|
||||
|
||||
// Institution declaration
|
||||
institution: $ => seq(
|
||||
institution_declaration: $ => seq(
|
||||
'institution',
|
||||
field('name', $.identifier),
|
||||
$.block
|
||||
field('body', $.block)
|
||||
),
|
||||
|
||||
// Relationship declaration
|
||||
relationship: $ => seq(
|
||||
relationship_declaration: $ => seq(
|
||||
'relationship',
|
||||
field('name', $.identifier),
|
||||
field('body', $.relationship_body)
|
||||
),
|
||||
|
||||
relationship_body: $ => seq(
|
||||
'{',
|
||||
repeat1($.participant),
|
||||
repeat($.field),
|
||||
@@ -354,22 +469,42 @@ module.exports = grammar({
|
||||
),
|
||||
|
||||
// Location declaration
|
||||
location: $ => seq(
|
||||
location_declaration: $ => seq(
|
||||
'location',
|
||||
field('name', $.identifier),
|
||||
$.block
|
||||
field('body', $.block)
|
||||
),
|
||||
|
||||
// Species declaration
|
||||
species: $ => seq(
|
||||
species_declaration: $ => seq(
|
||||
'species',
|
||||
field('name', $.identifier),
|
||||
field('body', $.species_body)
|
||||
),
|
||||
|
||||
species_body: $ => seq(
|
||||
'{',
|
||||
repeat($.include),
|
||||
repeat($.field),
|
||||
repeat($.species_field),
|
||||
'}'
|
||||
),
|
||||
|
||||
species_field: $ => choice(
|
||||
// Field with range: name: min..max
|
||||
seq(
|
||||
field('name', $.identifier),
|
||||
':',
|
||||
field('value', $.range)
|
||||
),
|
||||
// Field with single value: name: value
|
||||
seq(
|
||||
field('name', $.identifier),
|
||||
':',
|
||||
field('value', choice($.integer, $.float, $.boolean, $.string))
|
||||
),
|
||||
$.prose_block
|
||||
),
|
||||
|
||||
// Enum declaration
|
||||
enum_declaration: $ => seq(
|
||||
'enum',
|
||||
@@ -382,8 +517,7 @@ module.exports = grammar({
|
||||
// Concept declaration - base type with no structure
|
||||
concept_declaration: $ => seq(
|
||||
'concept',
|
||||
field('name', $.identifier),
|
||||
';'
|
||||
field('name', $.identifier)
|
||||
),
|
||||
|
||||
// Sub-concept declaration - enum or record subtype with dot notation
|
||||
@@ -403,13 +537,13 @@ module.exports = grammar({
|
||||
// Enum form: Variant1, Variant2, Variant3
|
||||
sub_concept_enum_body: $ => commaSep1($.identifier),
|
||||
|
||||
// Record form: field_name: Type, field_name: any
|
||||
// Record form: field_name: value, field_name: value
|
||||
sub_concept_record_body: $ => commaSep1($.sub_concept_field),
|
||||
|
||||
sub_concept_field: $ => seq(
|
||||
field('name', $.identifier),
|
||||
':',
|
||||
field('type', choice($.identifier, $.any_type))
|
||||
field('value', choice($.integer, $.float, $.string, $.boolean))
|
||||
),
|
||||
|
||||
any_type: $ => 'any',
|
||||
@@ -432,25 +566,26 @@ module.exports = grammar({
|
||||
'}'
|
||||
),
|
||||
|
||||
// A condition on a sub_concept field
|
||||
// Field condition: field_name: any OR field_name: Type is Value [or Type is Value]*
|
||||
field_condition: $ => seq(
|
||||
field('sub_concept', $.dotted_path),
|
||||
field('name', $.identifier),
|
||||
':',
|
||||
field('condition', $.condition_expr)
|
||||
field('condition', choice(
|
||||
$.any_type,
|
||||
$.is_condition
|
||||
))
|
||||
),
|
||||
|
||||
// Condition: either 'any' or 'Type is Value or Type is Value2'
|
||||
condition_expr: $ => choice(
|
||||
$.any_type,
|
||||
$.is_condition
|
||||
),
|
||||
|
||||
// Pattern: DottedPath is Ident [or DottedPath is Ident]*
|
||||
// Is condition: Type is Value [or Type is Value]*
|
||||
is_condition: $ => seq(
|
||||
$.dotted_path,
|
||||
$.is_value,
|
||||
repeat(seq('or', $.is_value))
|
||||
),
|
||||
|
||||
is_value: $ => seq(
|
||||
field('field', $.identifier),
|
||||
'is',
|
||||
$.identifier,
|
||||
repeat(seq('or', $.dotted_path, 'is', $.identifier))
|
||||
field('value', $.identifier)
|
||||
),
|
||||
|
||||
// Expressions (for conditions in life arcs)
|
||||
|
||||
Reference in New Issue
Block a user