1
+ using System ;
2
+ using System . Collections . Generic ;
3
+ using csly . indentedWhileLang . parser ;
4
+ using csly . whileLang . model ;
5
+ using sly . buildresult ;
6
+ using sly . lexer ;
7
+ using sly . lexer . fluent ;
8
+ using sly . parser ;
9
+ using sly . parser . generator ;
10
+ using sly . parser . parser ;
11
+
12
+ namespace ParserTests . samples ;
13
+
14
+ public class FluentIndentedWhileParserBuilder {
15
+
16
+ public IFluentLexemeBuilder < IndentedWhileTokenGeneric > GetLexer ( )
17
+ {
18
+ var lexer = FluentLexerBuilder < IndentedWhileTokenGeneric > . NewBuilder ( )
19
+ . IgnoreEol ( true )
20
+ . IgnoreWhiteSpace ( true )
21
+ . IsIndentationAware ( true )
22
+ . IgnoreKeywordCase ( true )
23
+ . AlphaNumDashId ( IndentedWhileTokenGeneric . IDENTIFIER )
24
+ . WithModes ( ModeAttribute . DefaultLexerMode , "fstringExpression" )
25
+ . Keyword ( IndentedWhileTokenGeneric . IF , "if" )
26
+ . Keyword ( IndentedWhileTokenGeneric . THEN , "then" )
27
+ . Keyword ( IndentedWhileTokenGeneric . ELSE , "else" )
28
+ . Keyword ( IndentedWhileTokenGeneric . WHILE , "while" )
29
+ . Keyword ( IndentedWhileTokenGeneric . DO , "do" )
30
+ . Keyword ( IndentedWhileTokenGeneric . TRUE , "true" )
31
+ . Keyword ( IndentedWhileTokenGeneric . FALSE , "false" )
32
+ . Keyword ( IndentedWhileTokenGeneric . NOT , "not" )
33
+ . Keyword ( IndentedWhileTokenGeneric . AND , "and" )
34
+ . Keyword ( IndentedWhileTokenGeneric . OR , "or" )
35
+ . Keyword ( IndentedWhileTokenGeneric . PRINT , "print" )
36
+ . Keyword ( IndentedWhileTokenGeneric . RETURN , "return" )
37
+ . Keyword ( IndentedWhileTokenGeneric . SKIP , "skip" )
38
+ . Int ( IndentedWhileTokenGeneric . INT )
39
+ . Sugar ( IndentedWhileTokenGeneric . GREATER , ">" )
40
+ . WithModes ( ModeAttribute . DefaultLexerMode , "fstringExpression" )
41
+ . Sugar ( IndentedWhileTokenGeneric . LESSER , "<" ) . WithModes ( ModeAttribute . DefaultLexerMode , "fstringExpression" )
42
+ . Sugar ( IndentedWhileTokenGeneric . EQUALS , "==" )
43
+ . WithModes ( ModeAttribute . DefaultLexerMode , "fstringExpression" )
44
+ . Sugar ( IndentedWhileTokenGeneric . DIFFERENT , "!=" )
45
+ . WithModes ( ModeAttribute . DefaultLexerMode , "fstringExpression" )
46
+ . Sugar ( IndentedWhileTokenGeneric . CONCAT , "." ) . WithModes ( ModeAttribute . DefaultLexerMode , "fstringExpression" )
47
+ . Sugar ( IndentedWhileTokenGeneric . PLUS , "+" ) . WithModes ( ModeAttribute . DefaultLexerMode , "fstringExpression" )
48
+ . Sugar ( IndentedWhileTokenGeneric . MINUS , "-" ) . WithModes ( ModeAttribute . DefaultLexerMode , "fstringExpression" )
49
+ . Sugar ( IndentedWhileTokenGeneric . TIMES , "*" ) . WithModes ( ModeAttribute . DefaultLexerMode , "fstringExpression" )
50
+ . Sugar ( IndentedWhileTokenGeneric . DIVIDE , "/" ) . WithModes ( ModeAttribute . DefaultLexerMode , "fstringExpression" )
51
+ . Sugar ( IndentedWhileTokenGeneric . QUESTION , "?" ) . WithModes ( "fstringExpression" )
52
+ . Sugar ( IndentedWhileTokenGeneric . ARROW , "->" ) . WithModes ( ModeAttribute . DefaultLexerMode , "fstringExpression" )
53
+ . Sugar ( IndentedWhileTokenGeneric . OPEN_PAREN , "(" )
54
+ . WithModes ( ModeAttribute . DefaultLexerMode , "fstringExpression" )
55
+ . Sugar ( IndentedWhileTokenGeneric . CLOSE_PAREN , ")" )
56
+ . WithModes ( ModeAttribute . DefaultLexerMode , "fstringExpression" )
57
+ . Sugar ( IndentedWhileTokenGeneric . SEMICOLON , ";" )
58
+ . Sugar ( IndentedWhileTokenGeneric . COLON , "|" ) . WithModes ( ModeAttribute . DefaultLexerMode , "fstringExpression" )
59
+ . SingleLineComment ( IndentedWhileTokenGeneric . COMMENT , "#" )
60
+
61
+ . Sugar ( IndentedWhileTokenGeneric . OPEN_FSTRING_EXPPRESSION , "{" ) . WithModes ( "fstring" ) . PushToMode ( "fstringExpression" )
62
+ . Sugar ( IndentedWhileTokenGeneric . CLOSE_FSTRING_EXPPRESSION , "}" ) . WithModes ( "fstringExpression" ) . PopMode ( )
63
+ . Sugar ( IndentedWhileTokenGeneric . OPEN_FSTRING , "$\" " ) . WithModes ( ModeAttribute . DefaultLexerMode , "fstringExpression" ) . PushToMode ( "fstring" )
64
+ . Sugar ( IndentedWhileTokenGeneric . CLOSE_FSTRING , "\" " ) . WithModes ( "fstring" ) . PopMode ( )
65
+ . UpTo ( IndentedWhileTokenGeneric . FSTRING_CONTENT , "{" , "\" " ) . WithModes ( "fstring" )
66
+ . Sugar ( IndentedWhileTokenGeneric . ASSIGN , ":=" ) ;
67
+ return lexer ;
68
+ }
69
+
70
+ public BuildResult < Parser < IndentedWhileTokenGeneric , WhileAST > > GetParser ( )
71
+ {
72
+ var instance = new IndentedWhileParserGeneric ( ) ;
73
+ var builder = FluentEBNFParserBuilder < IndentedWhileTokenGeneric , WhileAST > . NewBuilder ( instance , "program" , "en" ) ;
74
+
75
+ var binary = ( Func < WhileAST , Token < IndentedWhileTokenGeneric > , WhileAST , WhileAST > instanceCallback ) =>
76
+ {
77
+ Func < object [ ] , WhileAST > callback = ( object [ ] args ) =>
78
+ {
79
+ WhileAST left = ( WhileAST ) args [ 0 ] ;
80
+ Token < IndentedWhileTokenGeneric > op = ( Token < IndentedWhileTokenGeneric > ) args [ 1 ] ;
81
+ WhileAST right = ( WhileAST ) args [ 2 ] ;
82
+ return instanceCallback ( left , op , right ) ;
83
+ } ;
84
+ return callback ;
85
+ } ;
86
+
87
+ var prefix = ( Func < Token < IndentedWhileTokenGeneric > , WhileAST , WhileAST > instanceCallback ) =>
88
+ {
89
+ Func < object [ ] , WhileAST > callback = ( object [ ] args ) =>
90
+ {
91
+ Token < IndentedWhileTokenGeneric > op = ( Token < IndentedWhileTokenGeneric > ) args [ 0 ] ;
92
+ WhileAST right = ( WhileAST ) args [ 1 ] ;
93
+ return instanceCallback ( op , right ) ;
94
+ } ;
95
+ return callback ;
96
+ } ;
97
+
98
+ var postfix = ( Func < WhileAST , Token < IndentedWhileTokenGeneric > , WhileAST > instanceCallback ) =>
99
+ {
100
+ Func < object [ ] , WhileAST > callback = ( object [ ] args ) =>
101
+ {
102
+ Token < IndentedWhileTokenGeneric > op = ( Token < IndentedWhileTokenGeneric > ) args [ 0 ] ;
103
+ WhileAST right = ( WhileAST ) args [ 1 ] ;
104
+ return instanceCallback ( right , op ) ;
105
+ } ;
106
+ return callback ;
107
+ } ;
108
+
109
+ var comparisonCallback = binary ( ( left , op , right ) =>
110
+ {
111
+ return instance . binaryComparisonExpression ( left , op , right ) ;
112
+ } ) ;
113
+
114
+ var stringCallback = binary ( ( left , op , right ) =>
115
+ {
116
+ return instance . binaryStringExpression ( left , op , right ) ;
117
+ } ) ;
118
+ var factorCallback = binary ( ( left , op , right ) =>
119
+ {
120
+ return instance . binaryFactorNumericExpression ( left , op , right ) ;
121
+ } ) ;
122
+ var termCallback = binary ( ( left , op , right ) =>
123
+ {
124
+ return instance . binaryTermNumericExpression ( left , op , right ) ;
125
+ } ) ;
126
+
127
+
128
+ var parser = builder
129
+ . UseAutoCloseIndentations ( true )
130
+ . UseMemoization ( true )
131
+ // expressions
132
+ . Right ( IndentedWhileTokenGeneric . LESSER , 50 , comparisonCallback )
133
+ . Right ( IndentedWhileTokenGeneric . GREATER , 50 , comparisonCallback )
134
+ . Right ( IndentedWhileTokenGeneric . EQUALS , 50 , comparisonCallback )
135
+ . Right ( IndentedWhileTokenGeneric . DIFFERENT , 50 , comparisonCallback )
136
+ . Right ( IndentedWhileTokenGeneric . CONCAT , 50 , stringCallback )
137
+ . Right ( IndentedWhileTokenGeneric . PLUS , 10 , termCallback )
138
+ . Right ( IndentedWhileTokenGeneric . MINUS , 10 , termCallback )
139
+ . Right ( IndentedWhileTokenGeneric . TIMES , 50 , factorCallback )
140
+ . Right ( IndentedWhileTokenGeneric . DIVIDE , 50 , factorCallback )
141
+ . Prefix ( IndentedWhileTokenGeneric . MINUS , 100 ,
142
+ prefix ( ( op , value ) => instance . unaryNumericExpression ( op , value ) ) )
143
+ . Right ( IndentedWhileTokenGeneric . OR , 10 ,
144
+ binary ( ( left , op , right ) => instance . binaryOrExpression ( left , op , right ) ) )
145
+ . Right ( IndentedWhileTokenGeneric . AND , 50 ,
146
+ binary ( ( left , op , right ) => instance . binaryAndExpression ( left , op , right ) ) )
147
+ . Prefix ( IndentedWhileTokenGeneric . NOT , 100 , prefix ( ( op , value ) => instance . unaryNotExpression ( op , value ) ) )
148
+ // operands
149
+ . Production ( "primary : INT" , ( args ) =>
150
+ {
151
+ return instance . PrimaryInt ( ( Token < IndentedWhileTokenGeneric > ) args [ 0 ] ) ;
152
+ } )
153
+ . Production ( "primary : IDENTIFIER" , ( args ) =>
154
+ {
155
+ return instance . PrimaryId ( ( Token < IndentedWhileTokenGeneric > ) args [ 0 ] ) ;
156
+ } )
157
+ . Production ( "primary : [TRUE|FALSE]" , ( args ) =>
158
+ {
159
+ return instance . PrimaryBool ( ( Token < IndentedWhileTokenGeneric > ) args [ 0 ] ) ;
160
+ } )
161
+ . Production ( "primary : OPEN_PAREN[d] IndentedWhileParserGeneric_expressions CLOSE_PAREN[d]" , args =>
162
+ {
163
+ return ( WhileAST ) args [ 0 ] ;
164
+ } )
165
+ . Production (
166
+ "primary : QUESTION[d] IndentedWhileParserGeneric_expressions ARROW[d] IndentedWhileParserGeneric_expressions COLON[d] IndentedWhileParserGeneric_expressions" ,
167
+ args =>
168
+ {
169
+ var condition = ( WhileAST ) args [ 0 ] ;
170
+ var ifTrue = ( WhileAST ) args [ 1 ] ;
171
+ var ifFalse = ( WhileAST ) args [ 2 ] ;
172
+ return instance . TernaryQuestion ( condition , ifTrue , ifFalse ) ;
173
+ } )
174
+ . Operand ( "operand: primary" , ( args ) =>
175
+ {
176
+ return ( WhileAST ) args [ 0 ] ;
177
+ } )
178
+ // fstrings
179
+ . Production ( "primary : OPEN_FSTRING[d] fstring_element* CLOSE_FSTRING[d]" , args =>
180
+ {
181
+ var elements = ( List < WhileAST > ) args [ 0 ] ;
182
+ return instance . fstring ( elements ) ;
183
+ ;
184
+ } )
185
+ . Production ( "fstring_element : FSTRING_CONTENT" , args =>
186
+ {
187
+ return instance . FStringContent ( ( Token < IndentedWhileTokenGeneric > ) args [ 0 ] ) ;
188
+ } )
189
+ . Production (
190
+ "fstring_element : OPEN_FSTRING_EXPPRESSION[d] IndentedWhileParserGeneric_expressions CLOSE_FSTRING_EXPPRESSION[d]" ,
191
+ args =>
192
+ {
193
+ return ( WhileAST ) args [ 0 ] ;
194
+ } )
195
+ // main
196
+ . Production ( "program: sequence" , args =>
197
+ {
198
+ return ( WhileAST ) args [ 0 ] ;
199
+ } )
200
+ . Production ( "block : INDENT[d] sequence UINDENT[d]" , args =>
201
+ {
202
+ return ( WhileAST ) args [ 0 ] ;
203
+ } )
204
+ // statements
205
+ . Production ( "statement : block" , args =>
206
+ {
207
+ return ( WhileAST ) args [ 0 ] ;
208
+ } )
209
+ . Production ( "sequence: statement*" , args =>
210
+ {
211
+ return instance . sequence ( ( List < WhileAST > ) args [ 0 ] ) ;
212
+ } )
213
+ . Production ( "statement: IF[d] IndentedWhileParserGeneric_expressions THEN[d] block (ELSE[d] block)?" ,
214
+ args =>
215
+ {
216
+ var condition = ( WhileAST ) args [ 0 ] ;
217
+ var ifTrue = ( WhileAST ) args [ 1 ] ;
218
+ var ifFalse = ( ValueOption < Group < IndentedWhileTokenGeneric , WhileAST > > ) args [ 2 ] ;
219
+ return instance . ifStmt ( condition , ifTrue , ifFalse ) ;
220
+ } )
221
+ . Production ( "statement: WHILE[d] IndentedWhileParserGeneric_expressions DO[d] block" , args =>
222
+ {
223
+ var condition = ( WhileAST ) args [ 0 ] ;
224
+ var block = ( WhileAST ) args [ 1 ] ;
225
+ return instance . whileStmt ( condition , block ) ;
226
+ } )
227
+ . Production ( "statement: IDENTIFIER ASSIGN[d] IndentedWhileParserGeneric_expressions" , args =>
228
+ {
229
+ var id = ( Token < IndentedWhileTokenGeneric > ) args [ 0 ] ;
230
+ var value = ( Expression ) args [ 1 ] ;
231
+ return instance . assignStmt ( id , value ) ;
232
+ } )
233
+ . Production ( "statement: SKIP[d]" , args =>
234
+ {
235
+ return new SkipStatement ( ) ;
236
+ } )
237
+ . Production ( "statement: RETURN[d] IndentedWhileParserGeneric_expressions" , args =>
238
+ {
239
+ var value = ( Expression ) args [ 0 ] ;
240
+ return new ReturnStatement ( value ) ;
241
+ } )
242
+ . Production ( "statement: PRINT[d] IndentedWhileParserGeneric_expressions" , args =>
243
+ {
244
+ var value = ( Expression ) args [ 0 ] ;
245
+ return new PrintStatement ( value ) ;
246
+ } )
247
+ . WithLexerbuilder ( GetLexer ( ) )
248
+ . BuildParser ( ) ;
249
+
250
+
251
+ return parser ;
252
+
253
+
254
+
255
+ }
256
+
257
+
258
+ }
0 commit comments