
الگوی طراحـــــــــی Interpreter
الگوی طراحی Interpreter یک الگوی رایج در برنامهنویسی است که برای تفسیر یک زبان خاص و اجرای دستورات آن استفاده میشود. این الگو اجازه میدهد تا یک گرامر را به صورت شیءگرا نمایندهسازی کنید و از آن برای اجرای دستورات و عملیاتهای مربوط به آن گرامر استفاده کنید.
سختش نکنیم! همانطور که Hello در زبان انگلیسی با سلام در زبان فارسی یک معنی میدهد، میتوانیم کدهایی را به نحوی اجرا کنیم که برامون تفاوتی نداشته باشه که چه کاری قراره انجام بدن.
مفهوم الگوی Interpreter به این صورت است که هر دستور یا عبارت در زبان موردنظر با استفاده از شیءها یا کلاسها به شکل درختی (AST: Abstract Syntax Tree) تجسم میشود. درخت AST حاوی نودهای مختلف است که هرکدام نمایندهی یک عملیات یا دستور در گرامر هستند. اجرای دستورات و عملیاتها با پیمایش ویژگیهای این درخت AST انجام میشود.
یک مثال واقعی از الگوی Interpreter میتواند برای تبدیل عبارات ریاضی به مقدار عددی باشد:
1. AbstractExpression (ترکیبپذیر ویژگی):
1public interface IExpression
2{
3 int Interpret();
4}
2. TerminalExpression (ترکیبپذیر ویژگیها):
1public class NumberExpression : IExpression
2{
3 private int _number;
4
5 public NumberExpression(int number)
6 {
7 _number = number;
8 }
9
10 public int Interpret()
11 {
12 return _number;
13 }
14}
3. NonTerminalExpression (غیرترکیبپذیر ویژگیها):
1public class AddExpression : IExpression
2{
3 private IExpression _leftExpression;
4 private IExpression _rightExpression;
5
6 public AddExpression(IExpression leftExpression, IExpression rightExpression)
7 {
8 _leftExpression = leftExpression;
9 _rightExpression = rightExpression;
10 }
11
12 public int Interpret()
13 {
14 return _leftExpression.Interpret() + _rightExpression.Interpret();
15 }
16}
17
18public class SubtractExpression : IExpression
19{
20 private IExpression _leftExpression;
21 private IExpression _rightExpression;
22
23 public SubtractExpression(IExpression leftExpression, IExpression rightExpression)
24 {
25 _leftExpression = leftExpression;
26 _rightExpression = rightExpression;
27 }
28
29 public int Interpret()
30 {
31 return _leftExpression.Interpret() - _rightExpression.Interpret();
32 }
33}
4. Context (متن منبع یا محیط):
1public class Context
2{
3 // در این مثال، متن منبع به صورت عبارت ریاضی است که باید تفسیر شود.
4 public string Source { get; set; }
5
6 public Context(string source)
7 {
8 Source = source;
9 }
10}
5. Client (کلاینت):
1public class Program
2{
3 public static void Main()
4 {
5 // ساختن یک محیط با عبارت ریاضی
6 Context context = new Context("1 + 2 - 3");
7
8 // ترجمه عبارت ریاضی به درخت AST
9 IExpression expression = ParseExpression(context);
10
11 // اجرای عبارت ریاضی
12 int result = expression.Interpret();
13
14 Console.WriteLine($"Result: {result}"); // خروجی: "Result: 0"
15 }
16
17 // تابع تجزیه و تحلیل عبارت ریاضی و تولید درخت AST
18 public static IExpression ParseExpression(Context context)
19 {
20 // پیمایش عبارت منبع و تولید درخت AST
21 // این قسمت برای اجزای مختلف گرامر ریاضی تعمیمپذیر است.
22 // در این مثال، فقط پشتیبانی از اعمال جمع و تفریق انجام میشود.
23
24 string[] tokens = context.Source.Split(' ');
25
26 Stack<IExpression> expressionStack = new Stack<IExpression>();
27
28 foreach (string token in tokens)
29 {
30 if (int.TryParse(token, out int number))
31 {
32 expressionStack.Push(new NumberExpression(number));
33 }
34 else if (token == "+")
35 {
36 IExpression rightExpression = expressionStack.Pop();
37 IExpression leftExpression = expressionStack.Pop();
38 expressionStack.Push(new AddExpression(leftExpression, rightExpression));
39 }
40 else if (token == "-")
41 {
42 IExpression rightExpression = expressionStack.Pop();
43 IExpression leftExpression = expressionStack.Pop();
44 expressionStack.Push(new SubtractExpression(leftExpression, rightExpression));
45 }
46 // اگر عبارتهای دیگری نیز وجود داشته باشد، میتوان اینجا به آنها پشتیبانی کرد.
47 }
48
49 return expressionStack.Pop();
50 }
51}
در این مثال، با استفاده از الگوی Interpreter، ما عبارت ریاضی "1 + 2 - 3" را تفسیر کرده و به مقدار عددی 0 تبدیل کردیم. به عنوان نمونه از یک گرامر ریاضی ساده، فقط پشتیبانی از اعمال جمع و تفریق انجام شده است. در واقع، الگوی Interpreter قابلیت تفسیر و اجرای گرامرهای پیچیدهتر را نیز دارد و به ما امکان تعریف یک زبان خاص و پیادهسازی معنای آن را میدهد.