Skip to content

Commit 2a43b4d

Browse files
committed
fluent indented while unit tests
1 parent ca859c6 commit 2a43b4d

File tree

3 files changed

+730
-1
lines changed

3 files changed

+730
-1
lines changed

src/samples/IndentedWhile/parser/IndentedWhileParserGeneric.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -317,7 +317,7 @@ public WhileAST binaryAndExpression(WhileAST left, Token<IndentedWhileTokenGener
317317
}
318318

319319
[Operation((int) IndentedWhileTokenGeneric.NOT, Affix.PreFix, Associativity.Right, 100)]
320-
public WhileAST binaryOrExpression(Token<IndentedWhileTokenGeneric> operatorToken, WhileAST value)
320+
public WhileAST unaryNotExpression(Token<IndentedWhileTokenGeneric> operatorToken, WhileAST value)
321321
{
322322
return new Not(value as Expression);
323323
}
Lines changed: 258 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,258 @@
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

Comments
 (0)