Các bước thi hành chương trình viết bằng Sen Trắng

Một phần của tài liệu ThongDich ppsx (Trang 75 - 87)

• Nhận tập mã lệnh, tách ra từng dòng. • Tiến hành các bước khởi tạo cần thiết.

• Vòng lặp qua từng dòng lệnh nếu chưa gặp lỗi: o Phân tích dòng lệnh, tạo cấu trúc ngữ nghĩa.

o Tùy thuộc phân loại ngữ nghĩa mà gọi hàm thi hành tương ứng.

d. Viết mã lệnh

Syntax: [ Download ] [ Hide ] [ Select ] [ Contract ]

Using csharp Syntax Highlighting

using System;

using System.Collections.Generic;

namespace BieuThuc.LienHoa {

class Interpreter {

// Các ủy thác hàm nhập xuất

public delegate string stdinDelegate();

public delegate void stdoutDelegate(string s);

public delegate void stderrDelegate(string s);

#region Các biến toàn cục

// Các lớp hỗ trợ

private Parser mParser;

private Lexer mLexer;

private Error mError;

// Các hàm nhập xuất

private stdinDelegate stdin;

private stdoutDelegate stdout;

private stderrDelegate stderr;

// Ngăn xếp các đối số

private Stack<Memory.Record> FunctionArguments;

// Mảng các lệnh

private string[] CodeLines;

// Chỉ mục dòng lệnh

public int CurrentLine;

// Cờ lỗi

public bool NoError;

// Dấu xuống dòng

public string LineTerminator = "\r\n";

#endregion

#region Các hàm chính

public Interpreter(stdinDelegate i, stdoutDelegate o, stderrDelegate e) {

this.stdin = i;

this.stdout = o;

this.stderr = e;

this.mError = new Error(this, e);

this.mMemory = new Memory(this.mError);

this.mLexer = new Lexer(this.mError);

this.mParser = new Parser(this.mLexer, this.mError);

this.FunctionArguments = new Stack<Memory.Record>();

this.NoError = true;

this.FuncTable = new FuncDelegate[] {

f_sqrt, f_abs, f_sin, f_cos, f_tan, f_asin, f_acos, f_atan, f_left, f_mid, f_right, f_chr, f_ord, f_len, f_toint, f_tofloat,

f_readln, f_print, f_println };

}

public bool Run(string code) {

int LinesCount;

Parser.Semantics sem = new Parser.Semantics();

string[] sep = new string[] { "\n" };

CodeLines = code.Replace("\r\n", "\n").Split(sep, StringSplitOptions.None);

LinesCount = CodeLines.Length;

Init();

while (NoError && CurrentLine < LinesCount) {

if (mParser.Parse(CodeLines[CurrentLine+ +], ref sem) == false)return false;

switch (sem.Class) {

case Parser.SemanticsClass.Declare:

if (ExecuteDeclare(sem) == false) return false;

break;

case Parser.SemanticsClass.DeclareEx:

if (ExecuteDeclareEx(sem) == false) return false;

break;

case Parser.SemanticsClass.Assign:

if (ExecuteAssign(sem) == false) return false;

break;

case Parser.SemanticsClass.FunctionCall:

if (ExecuteFunctionCall(sem) == false) returnfalse;

break; default: break; } } return true; }

private void Init() {

CurrentLine = 0;

mMemory.ClearMemory();

}

private bool ExecuteDeclare(Parser.Semantics sem) {

Memory.Record r = new Memory.Record();

switch ((Lexer.KeywordClass)sem.TokenList[0].IntValue) {

case Lexer.KeywordClass.INT:

r.IntValue = 0;

break;

case Lexer.KeywordClass.FLOAT:

r.FloatValue = 0f;

break;

case Lexer.KeywordClass.STRING:

r.StringValue = string.Empty;

break;

}

if (mMemory.AddRecord(sem.Identifier, r) == false) return false;

return true;

}

private bool ExecuteDeclareEx(Parser.Semantics sem) {

Memory.Record r = new Memory.Record();

switch ((Lexer.KeywordClass)sem.TokenList[0].IntValue) {

case Lexer.KeywordClass.INT:

r.IntValue = 0;

break;

case Lexer.KeywordClass.FLOAT:

r.FloatValue = 0f;

break;

case Lexer.KeywordClass.STRING:

r.StringValue = string.Empty;

break;

}

if (Evaluate(sem, 1, ref r) == false) return false;

if (mMemory.AddRecord(sem.Identifier, r) == false) return false;

}

private bool ExecuteAssign(Parser.Semantics sem) {

Memory.Record r = new Memory.Record();

if (Evaluate(sem, 0, ref r) == false) return false;

if (mMemory.ModifyRecord(sem.Identifier, r) == false) return false;

return true;

}

private bool ExecuteFunctionCall(Parser.Semantics sem) {

Memory.Record r = new Memory.Record();

if (Evaluate(sem, 0, ref r) == false) return false;

return true;

}

private bool Evaluate(Parser.Semantics sem, int startpos, ref Memory.Record r) {

Stack<Memory.Record> res = new Stack<Memory.Record>();

Lexer.Token tmp;

Memory.Record a = new Memory.Record();

Memory.Record b = new Memory.Record();

int total = sem.TokenList.Count;

int argcount = 0;

for (int i = startpos; i < total; ++i) {

tmp = sem.TokenList[i ];

switch (tmp.Class) {

case Lexer.TokenClass.NumInt:

res.Push(new Memory.Record(tmp.IntValue));

break;

case Lexer.TokenClass.NumFloat:

res.Push(new Memory.Record(tmp.FloatValue));

break;

case Lexer.TokenClass.String:

res.Push(new Memory.Record(tmp.StringValue));

break;

case Lexer.TokenClass.Ident:

res.Push(a);

break;

case Lexer.TokenClass.Plus:

b = res.Pop();

a = res.Pop();

res.Push(a + b);

break;

case Lexer.TokenClass.Minus:

b = res.Pop();

a = res.Pop();

res.Push(a - b);

break;

case Lexer.TokenClass.Mul:

b = res.Pop();

a = res.Pop();

res.Push(a * b);

break;

case Lexer.TokenClass.Div:

b = res.Pop();

a = res.Pop();

if (b.IntValue == 0) {

mError.RaiseError(Error.ErrorConstant.DivisionByZero);

return false; } else { res.Push(a / b); } break;

case Lexer.TokenClass.Mod:

b = res.Pop();

a = res.Pop();

if (b.IntValue == 0) {

mError.RaiseError(Error.ErrorConstant.DivisionByZero);

return false; } else { res.Push(a % b); } break;

case Lexer.TokenClass.Pow:

b = res.Pop();

res.Push(a.Pow(b));

break;

case Lexer.TokenClass.UMinus:

res.Push(-res.Pop());

break;

case Lexer.TokenClass.Func:

// Tính số lượng đối số cần lấy

argcount = mParser.FunctionArgCount[tmp.IntValue];

// Lấy các đối số từ ngăn xếp

for (int k = 0; k < argcount; ++k)

FunctionArguments.Push(res.Pop());

// Gọi hàm

if (FuncTable[tmp.IntValue] (ref a) == false)return false;

// Lưu kết quả res.Push(a); break; } //switch } //while r = res.Pop(); return true; } #endregion

#region Các hàm cho sẵn của chương trình

private delegate bool FuncDelegate(ref Memory.Record r);

private FuncDelegate[] FuncTable;

private bool f_sqrt(ref Memory.Record r) {

Memory.Record a = FunctionArguments.Pop();

switch (a.Type) {

case Memory.DataType.Int:

case Memory.DataType.Float:

r.FloatValue = (float)Math.Sqrt(a.FloatValue);

break; default: r.FloatValue = 0f; break; } return true; }

private bool f_abs(ref Memory.Record r) {

Memory.Record a = FunctionArguments.Pop();

switch (a.Type) {

case Memory.DataType.Int:

r.IntValue = Math.Abs(a.IntValue);

break;

case Memory.DataType.Float:

r.FloatValue = Math.Abs(a.FloatValue);

break; default: r.IntValue = 0; break; } return true; }

private bool f_sin(ref Memory.Record r) {

Memory.Record a = FunctionArguments.Pop();

switch (a.Type) {

case Memory.DataType.Int:

case Memory.DataType.Float:

r.FloatValue = (float)Math.Sin(a.FloatValue);

break; default: r.FloatValue = 0f; break; } return true; }

private bool f_cos(ref Memory.Record r) {

Memory.Record a = FunctionArguments.Pop();

switch (a.Type) {

case Memory.DataType.Int:

case Memory.DataType.Float:

r.FloatValue = (float)Math.Cos(a.FloatValue);

break; default: r.FloatValue = 0f; break; } return true;

}

private bool f_tan(ref Memory.Record r) {

Memory.Record a = FunctionArguments.Pop();

switch (a.Type) {

case Memory.DataType.Int:

case Memory.DataType.Float:

r.FloatValue = (float)Math.Tan(a.FloatValue);

break; default: r.FloatValue = 0f; break; } return true; }

private bool f_asin(ref Memory.Record r) {

Memory.Record a = FunctionArguments.Pop();

switch (a.Type) {

case Memory.DataType.Int:

case Memory.DataType.Float:

r.FloatValue = (float)Math.Asin(a.FloatValue);

break; default: r.FloatValue = 0f; break; } return true; }

private bool f_acos(ref Memory.Record r) {

Memory.Record a = FunctionArguments.Pop();

switch (a.Type) {

case Memory.DataType.Int:

case Memory.DataType.Float:

r.FloatValue = (float)Math.Acos(a.FloatValue);

break; default: r.FloatValue = 0f; break; } return true;

}

private bool f_atan(ref Memory.Record r) {

Memory.Record a = FunctionArguments.Pop();

switch (a.Type) {

case Memory.DataType.Int:

case Memory.DataType.Float:

r.FloatValue = (float)Math.Atan(a.FloatValue);

break; default: r.FloatValue = 0f; break; } return true; }

private bool f_left(ref Memory.Record r) {

string a1s = FunctionArguments.Pop().StringValue;

Memory.Record a2 = FunctionArguments.Pop();

try

{

r.StringValue = a1s.Substring(0, a2.IntValue);

} catch (ArgumentOutOfRangeException) { r.StringValue = a1s; } return true; }

private bool f_mid(ref Memory.Record r) {

string a1s = FunctionArguments.Pop().StringValue;

Memory.Record a2 = FunctionArguments.Pop();

Memory.Record a3 = FunctionArguments.Pop();

try

{

r.StringValue = a1s.Substring(a2.IntValue, a3.IntValue);

}

catch (ArgumentOutOfRangeException) {

r.StringValue = a1s;

return true;

}

private bool f_right(ref Memory.Record r) {

string a1s = FunctionArguments.Pop().StringValue;

Memory.Record a2 = FunctionArguments.Pop();

try

{

r.StringValue = a1s.Substring(a1s.Length - a2.IntValue);

} catch (ArgumentOutOfRangeException) { r.StringValue = a1s; } return true; }

private bool f_chr(ref Memory.Record r) {

Memory.Record a = FunctionArguments.Pop();

switch (a.Type) {

case Memory.DataType.Int:

case Memory.DataType.Float:

try

{

r.StringValue = ((char)a.IntValue).ToString();

}

catch (ArgumentOutOfRangeException) {

r.StringValue = string.Empty;

} break;

default:

r.StringValue = string.Empty;

break;

}

return true;

}

private bool f_ord(ref Memory.Record r) {

Memory.Record a = FunctionArguments.Pop();

try

{

} catch (IndexOutOfRangeException) { r.IntValue = 0; } return true; }

private bool f_len(ref Memory.Record r) {

Memory.Record a = FunctionArguments.Pop();

r.IntValue = a.StringValue.Length;

return true;

}

private bool f_toint(ref Memory.Record r) {

Memory.Record a = FunctionArguments.Pop();

int i;

float f;

if (a.Type == Memory.DataType.String) {

float.TryParse(a.StringValue, out f);

i = (int)f; } else { i = a.IntValue; } r.IntValue = i; return true; }

private bool f_tofloat(ref Memory.Record r) {

Memory.Record a = FunctionArguments.Pop();

float f;

if (a.Type == Memory.DataType.String)

float.TryParse(a.StringValue, out f);

else

f = a.FloatValue;

r.FloatValue = f;

return true;

private bool f_readln(ref Memory.Record r) { string s = stdin(); r.StringValue = s; return true; }

private bool f_print(ref Memory.Record r) {

string s = FunctionArguments.Pop().StringValue;

r.IntValue = s.Length;

stdout(s);

return true;

}

private bool f_println(ref Memory.Record r) {

string s = FunctionArguments.Pop().StringValue;

r.IntValue = s.Length; stdout(s + LineTerminator); return true; } #endregion } }

Parsed in 0.092 seconds, using GeSHi 1.0.8.4

7. Giao diện

Một phần của tài liệu ThongDich ppsx (Trang 75 - 87)

Tải bản đầy đủ (DOCX)

(98 trang)
w