11const kdl = require ( "tree-sitter-kdl/grammar" ) ;
22
3- const nodeShape = ( $ , nameRule , childrenRule ) =>
3+ const PURE_MATH_NODE_NAMES = [
4+ "expression" ,
5+ "minimize" ,
6+ "maximize" ,
7+ "expr" ,
8+ "filter" ,
9+ "if" ,
10+ "lower" ,
11+ "upper" ,
12+ ] ;
13+
14+ const nodeShape = ( $ , { nameRule, childrenRule, fieldRule = $ . node_field } ) =>
415 seq (
516 alias ( optional ( seq ( "/-" , repeat ( $ . _node_space ) ) ) , $ . node_comment ) ,
617 optional ( $ . type ) ,
718 nameRule ,
8- repeat ( seq ( repeat1 ( $ . _node_space ) , $ . node_field ) ) ,
19+ repeat ( seq ( repeat1 ( $ . _node_space ) , fieldRule ) ) ,
920 optional (
1021 seq (
1122 repeat ( $ . _node_space ) ,
@@ -17,6 +28,19 @@ const nodeShape = ($, nameRule, childrenRule) =>
1728 $ . _node_terminator ,
1829 ) ;
1930
31+ const mathChildren = ( $ , mathRule ) =>
32+ prec (
33+ 2 ,
34+ seq (
35+ optional (
36+ seq ( alias ( "/-" , $ . node_children_comment ) , repeat ( $ . _node_space ) ) ,
37+ ) ,
38+ "{" ,
39+ choice ( field ( "math" , mathRule ) , seq ( repeat ( $ . _linespace ) ) ) ,
40+ "}" ,
41+ ) ,
42+ ) ;
43+
2044module . exports = grammar ( kdl , {
2145 name : "arco_kdl" ,
2246
@@ -27,6 +51,22 @@ module.exports = grammar(kdl, {
2751 _node_terminator : ( $ , previous ) =>
2852 choice ( previous , $ . _implicit_terminator ) ,
2953
54+ string : ( $ , previous ) =>
55+ choice ( previous , $ . _multiline_string ) ,
56+
57+ _multiline_string : ( $ ) =>
58+ seq (
59+ '"""' ,
60+ optional ( $ . _newline ) ,
61+ repeat (
62+ choice (
63+ alias ( token . immediate ( prec ( 1 , / [ ^ " ] + / ) ) , $ . string_fragment ) ,
64+ alias ( token . immediate ( '"' ) , $ . string_fragment ) ,
65+ ) ,
66+ ) ,
67+ '"""' ,
68+ ) ,
69+
3070 value : ( $ ) =>
3171 seq (
3272 optional ( $ . type ) ,
@@ -36,83 +76,57 @@ module.exports = grammar(kdl, {
3676 bare_identifier : ( $ ) => $ . _bare_identifier ,
3777
3878 node : ( $ ) =>
39- choice ( $ . arco_pure_math_node , $ . arco_constraint_node , $ . kdl_node ) ,
79+ choice (
80+ $ . arco_pure_math_node ,
81+ $ . arco_constraint_node ,
82+ $ . kdl_node ,
83+ ) ,
4084
41- kdl_node : ( $ ) => prec ( 1 , nodeShape ( $ , $ . identifier , $ . node_children ) ) ,
85+ kdl_node : ( $ ) =>
86+ prec (
87+ 1 ,
88+ nodeShape ( $ , {
89+ nameRule : $ . identifier ,
90+ childrenRule : $ . node_children ,
91+ } ) ,
92+ ) ,
4293
4394 // Nodes whose { } body is always algebra text.
4495 arco_pure_math_node : ( $ ) =>
4596 prec (
4697 2 ,
47- nodeShape (
48- $ ,
49- field (
50- "name" ,
51- choice (
52- "expression" ,
53- "minimize" ,
54- "maximize" ,
55- "expr" ,
56- "filter" ,
57- "if" ,
58- "lower" ,
59- "upper" ,
60- ) ,
61- ) ,
62- $ . arco_pure_math_children ,
63- ) ,
98+ nodeShape ( $ , {
99+ nameRule : field ( "name" , choice ( ...PURE_MATH_NODE_NAMES ) ) ,
100+ childrenRule : $ . arco_pure_math_children ,
101+ } ) ,
64102 ) ,
65103
66104 // Constraint nodes can have either KDL children or a math body.
67105 arco_constraint_node : ( $ ) =>
68106 prec (
69107 2 ,
70- nodeShape (
71- $ ,
72- field ( "name" , "constraint" ) ,
73- choice ( $ . arco_constraint_math_children , $ . node_children ) ,
74- ) ,
108+ nodeShape ( $ , {
109+ nameRule : field ( "name" , "constraint" ) ,
110+ childrenRule : choice ( $ . arco_constraint_math_children , $ . node_children ) ,
111+ } ) ,
75112 ) ,
76113
77114 // Math body for nodes whose braces are always algebra text.
78115 arco_pure_math_children : ( $ ) =>
79- prec (
80- 2 ,
81- seq (
82- optional (
83- seq ( alias ( "/-" , $ . node_children_comment ) , repeat ( $ . _node_space ) ) ,
84- ) ,
85- "{" ,
86- choice ( field ( "math" , $ . arco_math_text ) , seq ( repeat ( $ . _linespace ) ) ) ,
87- "}" ,
88- ) ,
89- ) ,
116+ mathChildren ( $ , $ . arco_math_text ) ,
90117
91118 // Constraint math body remains stricter so child-node bodies keep parsing
92119 // as KDL instead of being swallowed as free-form math text.
93120 arco_constraint_math_children : ( $ ) =>
94- prec (
95- 2 ,
96- seq (
97- optional (
98- seq ( alias ( "/-" , $ . node_children_comment ) , repeat ( $ . _node_space ) ) ,
99- ) ,
100- "{" ,
101- choice (
102- field ( "math" , $ . arco_constraint_math_text ) ,
103- seq ( repeat ( $ . _linespace ) ) ,
104- ) ,
105- "}" ,
106- ) ,
107- ) ,
121+ mathChildren ( $ , $ . arco_constraint_math_text ) ,
108122
109123 // Single opaque token for free-form algebra text in expression/minimize/
110124 // maximize/filter/if/lower/upper nodes.
111- arco_math_text : ( _ ) => token ( prec ( 10 , / [ ^ { } " ' ] + / ) ) ,
125+ arco_math_text : ( _ ) => token ( prec ( 10 , / [ ^ { } ] + / ) ) ,
112126
113127 // Constraint math must include an operator or bracket so bare KDL child
114128 // nodes like `if { ... }` still parse through node_children.
115129 arco_constraint_math_text : ( _ ) =>
116- token ( prec ( 10 , / [ ^ { } " ' ] * [ < > = ! + \- * \/ \[ \] ] [ ^ { } " ' ] * / ) ) ,
130+ token ( prec ( 10 , / [ ^ { } ] * [ < > = ! + \- * \/ \[ \] ] [ ^ { } ] * / ) ) ,
117131 } ,
118132} ) ;
0 commit comments