Skip to content

Commit e21a7c2

Browse files
authored
Merge pull request #34 from b3b00/whileParserUsingExpressionGenerator
- while parser using expression parser generator
2 parents 0525f22 + 5507a4b commit e21a7c2

File tree

2 files changed

+138
-86
lines changed

2 files changed

+138
-86
lines changed

samples/while/parser/WhileParser.cs

Lines changed: 101 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,12 @@ public class WhileParser
1313
#region statements
1414

1515
[Production("statement : LPAREN statement RPAREN ")]
16-
public WhileAST block(Token<WhileToken> discardLpar, Statement statement ,Token<WhileToken> discardRpar)
16+
public WhileAST block(Token<WhileToken> discardLpar, Statement statement, Token<WhileToken> discardRpar)
1717
{
1818
return statement;
1919
}
2020

21-
[Production("statement : sequence")]
21+
[Production("statement : sequence")]
2222
public WhileAST statementSequence(WhileAST sequence)
2323
{
2424
return sequence;
@@ -27,8 +27,8 @@ public WhileAST statementSequence(WhileAST sequence)
2727
[Production("sequence : statementPrim additionalStatements*")]
2828
public WhileAST sequenceStatements(WhileAST first, List<WhileAST> next)
2929
{
30-
SequenceStatement seq = new SequenceStatement(first as Statement);
31-
seq.AddRange(next.Cast<Statement>().ToList<Statement>()) ;
30+
SequenceStatement seq = new SequenceStatement(first as Statement);
31+
seq.AddRange(next.Cast<Statement>().ToList<Statement>());
3232
return seq;
3333
}
3434

@@ -38,21 +38,21 @@ public WhileAST additional(Token<WhileToken> semi, WhileAST statement)
3838
return statement;
3939
}
4040

41-
[Production("statementPrim: IF expression THEN statement ELSE statement")]
42-
public WhileAST ifStmt(Token<WhileToken> discardIf, WhileAST cond, Token<WhileToken> dicardThen, WhileAST thenStmt, Token<WhileToken> dicardElse, Statement elseStmt)
41+
[Production("statementPrim: IF WhileParser_expressions THEN statement ELSE statement")]
42+
public WhileAST ifStmt(Token<WhileToken> discardIf, WhileAST cond, Token<WhileToken> dicardThen, WhileAST thenStmt, Token<WhileToken> dicardElse, Statement elseStmt)
4343
{
4444
IfStatement stmt = new IfStatement(cond as Expression, thenStmt as Statement, elseStmt);
4545
return stmt;
4646
}
47-
48-
[Production("statementPrim: WHILE expression DO statement")]
47+
48+
[Production("statementPrim: WHILE WhileParser_expressions DO statement")]
4949
public WhileAST whileStmt(Token<WhileToken> discardWhile, WhileAST cond, Token<WhileToken> dicardDo, WhileAST blockStmt)
5050
{
5151
WhileStatement stmt = new WhileStatement(cond as Expression, blockStmt as Statement);
5252
return stmt;
5353
}
5454

55-
[Production("statementPrim: IDENTIFIER ASSIGN expression")]
55+
[Production("statementPrim: IDENTIFIER ASSIGN WhileParser_expressions")]
5656
public WhileAST assignStmt(Token<WhileToken> variable, Token<WhileToken> discardAssign, Expression value)
5757
{
5858
AssignStatement assign = new AssignStatement(variable.StringWithoutQuotes, value);
@@ -65,7 +65,7 @@ public WhileAST skipStmt(Token<WhileToken> discard)
6565
return new SkipStatement();
6666
}
6767

68-
[Production("statementPrim: PRINT expression")]
68+
[Production("statementPrim: PRINT WhileParser_expressions")]
6969
public WhileAST skipStmt(Token<WhileToken> discard, WhileAST expression)
7070
{
7171
return new PrintStatement(expression as Expression);
@@ -77,9 +77,8 @@ public WhileAST skipStmt(Token<WhileToken> discard, WhileAST expression)
7777

7878
#endregion
7979

80-
#region expression
81-
8280

81+
#region OPERANDS
8382

8483
[Production("primary: INT")]
8584
public WhileAST PrimaryInt(Token<WhileToken> intToken)
@@ -106,14 +105,19 @@ public WhileAST PrimaryId(Token<WhileToken> varToken)
106105
return new Variable(varToken.StringWithoutQuotes);
107106
}
108107

108+
[Operand]
109+
[Production("operand: primary")]
110+
public WhileAST Operand(WhileAST prim)
111+
{
112+
return prim;
113+
}
109114

115+
#endregion
110116

111-
112-
[Production("expression : term PLUS expression")]
113-
[Production("expression : term MINUS expression")]
114-
[Production("expression : term CONCAT expression")]
115-
116-
public WhileAST Expression(WhileAST left, Token<WhileToken> operatorToken, WhileAST right)
117+
#region NUMERIC OPERATIONS
118+
[Operation((int)WhileToken.PLUS, 2, Associativity.Right, 10)]
119+
[Operation((int)WhileToken.MINUS, 2, Associativity.Right, 10)]
120+
public WhileAST binaryTermNumericExpression(WhileAST left, Token<WhileToken> operatorToken, WhileAST right)
117121
{
118122
BinaryOperator oper = BinaryOperator.ADD;
119123

@@ -129,11 +133,6 @@ public WhileAST Expression(WhileAST left, Token<WhileToken> operatorToken, While
129133
oper = BinaryOperator.SUB;
130134
break;
131135
}
132-
case WhileToken.CONCAT:
133-
{
134-
oper = BinaryOperator.CONCAT;
135-
break;
136-
}
137136
default:
138137
{
139138
break;
@@ -143,48 +142,94 @@ public WhileAST Expression(WhileAST left, Token<WhileToken> operatorToken, While
143142
return operation;
144143
}
145144

146-
[Production("expression : term")]
147-
public WhileAST Expression_Term(WhileAST termValue)
145+
[Operation((int)WhileToken.TIMES, 2, Associativity.Right, 50)]
146+
[Operation((int)WhileToken.DIVIDE, 2, Associativity.Right, 50)]
147+
public WhileAST binaryFactorNumericExpression(WhileAST left, Token<WhileToken> operatorToken, WhileAST right)
148148
{
149-
return termValue;
150-
}
151-
152-
[Production("term : factor TIMES term")]
153-
[Production("term : factor DIVIDE term")]
154-
[Production("term : factor AND term")]
155-
[Production("term : factor LESSER term")]
156-
[Production("term : factor GREATER term")]
157-
[Production("term : factor EQUALS term")]
158-
[Production("term : factor DIFFERENT term")]
159-
public WhileAST Term(WhileAST left, Token<WhileToken> operatorToken, WhileAST right)
160-
{
161-
BinaryOperator oper = BinaryOperator.MULTIPLY;
149+
BinaryOperator oper = BinaryOperator.ADD;
162150

163151
switch (operatorToken.TokenID)
164152
{
165-
case WhileToken.TIMES:
153+
case WhileToken.PLUS:
166154
{
167-
oper = BinaryOperator.MULTIPLY;
155+
oper = BinaryOperator.ADD;
168156
break;
169157
}
170-
case WhileToken.DIVIDE:
158+
case WhileToken.MINUS:
171159
{
172-
oper = BinaryOperator.DIVIDE;
160+
oper = BinaryOperator.SUB;
173161
break;
174162
}
175-
case WhileToken.AND:
163+
default:
176164
{
177-
oper = BinaryOperator.AND;
178165
break;
179166
}
180-
case WhileToken.GREATER:
167+
}
168+
BinaryOperation operation = new BinaryOperation(left as Expression, oper, right as Expression);
169+
return operation;
170+
}
171+
172+
[Operation((int)WhileToken.MINUS, 1, Associativity.Right, 100)]
173+
public WhileAST unaryNumericExpression(Token<WhileToken> operation, WhileAST value)
174+
{
175+
return new Neg(value as Expression);
176+
}
177+
178+
179+
#endregion
180+
181+
182+
183+
#region BOOLEAN OPERATIONS
184+
185+
[Operation((int)WhileToken.OR, 2, Associativity.Right, 10)]
186+
public WhileAST binaryOrExpression(WhileAST left, Token<WhileToken> operatorToken, WhileAST right)
187+
{
188+
BinaryOperator oper = BinaryOperator.OR;
189+
190+
191+
BinaryOperation operation = new BinaryOperation(left as Expression, oper, right as Expression);
192+
return operation;
193+
}
194+
195+
[Operation((int)WhileToken.AND, 2, Associativity.Right, 50)]
196+
public WhileAST binaryAndExpression(WhileAST left, Token<WhileToken> operatorToken, WhileAST right)
197+
{
198+
BinaryOperator oper = BinaryOperator.AND;
199+
200+
201+
BinaryOperation operation = new BinaryOperation(left as Expression, oper, right as Expression);
202+
return operation;
203+
}
204+
205+
[Operation((int)WhileToken.NOT, 1, Associativity.Right, 100)]
206+
public WhileAST binaryOrExpression(Token<WhileToken> operatorToken, WhileAST value)
207+
{
208+
209+
return new Not(value as Expression);
210+
}
211+
#endregion
212+
213+
#region COMPARISON OPERATIONS
214+
215+
[Operation((int)WhileToken.LESSER, 2, Associativity.Right, 50)]
216+
[Operation((int)WhileToken.GREATER, 2, Associativity.Right, 50)]
217+
[Operation((int)WhileToken.EQUALS, 2, Associativity.Right, 50)]
218+
[Operation((int)WhileToken.DIFFERENT, 2, Associativity.Right, 50)]
219+
public WhileAST binaryComparisonExpression(WhileAST left, Token<WhileToken> operatorToken, WhileAST right)
220+
{
221+
BinaryOperator oper = BinaryOperator.ADD;
222+
223+
switch (operatorToken.TokenID)
224+
{
225+
case WhileToken.LESSER:
181226
{
182-
oper = BinaryOperator.GREATER;
227+
oper = BinaryOperator.LESSER;
183228
break;
184229
}
185-
case WhileToken.LESSER:
230+
case WhileToken.GREATER:
186231
{
187-
oper = BinaryOperator.LESSER;
232+
oper = BinaryOperator.GREATER;
188233
break;
189234
}
190235
case WhileToken.EQUALS:
@@ -206,54 +251,28 @@ public WhileAST Term(WhileAST left, Token<WhileToken> operatorToken, WhileAST ri
206251
return operation;
207252
}
208253

209-
[Production("term : factor")]
210-
public WhileAST Term_Factor(WhileAST factorValue)
211-
{
212-
return factorValue;
213-
}
214254

215-
[Production("factor : primary")]
216-
public WhileAST primaryFactor(WhileAST primValue)
217-
{
218-
return primValue;
219-
}
220-
[Production("factor : MINUS factor")]
221-
public WhileAST negFactor(Token<WhileToken> discardedMinus, WhileAST factorValue)
222-
{
223-
return new Neg(factorValue as Expression);
224-
}
255+
#endregion
256+
257+
#region STRING OPERATIONS
225258

226-
[Production("factor : NOT factor")]
227-
public WhileAST notFactor(Token<WhileToken> discardedMinus, WhileAST factorValue)
259+
[Operation((int)WhileToken.CONCAT, 2, Associativity.Right, 10)]
260+
public WhileAST binaryStringExpression(WhileAST left, Token<WhileToken> operatorToken, WhileAST right)
228261
{
229-
return new Not(factorValue as Expression);
262+
BinaryOperator oper = BinaryOperator.CONCAT;
263+
BinaryOperation operation = new BinaryOperation(left as Expression, oper, right as Expression);
264+
return operation;
230265
}
231-
232-
233-
234266
#endregion
235267

236268

237269

238270

239271

240-
#region string expression
241272

242273

243-
//[Production("string_expression : expression CONCAT expression")]
244-
//public WhileAST String_Term(Expression left, Token<WhileToken> discard, Expression right)
245-
//{
246-
// WhileAST result = new BinaryOperation(left, BinaryOperator.CONCAT, right);
247-
// return result;
248-
//}
249274

250-
[Production("string_expression : STRING")]
251-
public WhileAST String_constantFactor(Token<WhileToken> value)
252-
{
253-
return new StringConstant(value.StringWithoutQuotes);
254-
}
255275

256-
#endregion
257276

258277

259278
}

sly/parser/generator/EBNFSyntaxTreeVisitor.cs

Lines changed: 37 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
using System.Collections.Generic;
33
using sly.parser.syntax;
44
using sly.lexer;
5+
using System.Reflection;
56

67
namespace sly.parser.generator
78
{
@@ -44,11 +45,17 @@ protected override SyntaxVisitorResult<IN,OUT> Visit(ISyntaxNode<IN> n)
4445

4546
private SyntaxVisitorResult<IN, OUT> Visit(SyntaxNode<IN> node)
4647
{
47-
OUT result = default(OUT);
48-
if (Configuration.Functions.ContainsKey(node.Name))
48+
SyntaxVisitorResult < IN, OUT > result = SyntaxVisitorResult<IN, OUT>.NoneResult();
49+
if (Configuration.Functions.ContainsKey(node.Name) || node.Visitor != null || node.IsByPassNode)
4950
{
5051
List<object> args = new List<object>();
5152
int i = 0;
53+
54+
if (node.Name == "statementPrim__IDENTIFIER_ASSIGN_WhileParser_expressions")
55+
{
56+
;
57+
}
58+
5259
foreach (ISyntaxNode<IN> n in node.Children)
5360
{
5461
SyntaxVisitorResult<IN, OUT> v = Visit(n);
@@ -74,9 +81,35 @@ private SyntaxVisitorResult<IN, OUT> Visit(SyntaxNode<IN> node)
7481
i++;
7582
}
7683

77-
result = (OUT) (Configuration.Functions[node.Name].Invoke(ParserVsisitorInstance, args.ToArray()));
84+
if (node.IsByPassNode)
85+
{
86+
result = SyntaxVisitorResult<IN, OUT>.NewValue((OUT)args[0]);
87+
}
88+
else
89+
{
90+
MethodInfo method = null;
91+
try
92+
{
93+
bool found = Configuration.Functions.TryGetValue(node.Name, out method);
94+
if (method == null && !found)
95+
{
96+
method = node.Visitor;
97+
}
98+
object t = (method.Invoke(ParserVsisitorInstance, args.ToArray()));
99+
//string typename = t.GetType().Name;
100+
OUT res = (OUT)t;
101+
result = SyntaxVisitorResult<IN, OUT>.NewValue(res);
102+
}
103+
catch (Exception e)
104+
{
105+
Console.WriteLine($"OUTCH {e.Message} calling {node.Name} => {method.Name}");
106+
}
107+
}
108+
109+
110+
//result = (OUT) (Configuration.Functions[node.Name].Invoke(ParserVsisitorInstance, args.ToArray()));
78111
}
79-
return SyntaxVisitorResult<IN, OUT>.NewValue(result);
112+
return result;
80113
}
81114

82115
private SyntaxVisitorResult<IN, OUT> Visit(ManySyntaxNode<IN> node)

0 commit comments

Comments
 (0)