Рефераты. Интерактивный интерпретатор

return new EndifOperator();

} else if (firsttoken == "loop") {

if (p.MoveNext())

throw new SyntaxErrorException("Синтаксическая ошибка");

return new LoopOperator();

} else if (firsttoken == "return") {

if (p.MoveNext())

throw new SyntaxErrorException("Синтаксическая ошибка");

return new ReturnOperator();

} else if (firsttoken == "error") {

if (p.MoveNext())

throw new SyntaxErrorException("Синтаксическая ошибка");

return new ErrorOperator();

}

Expression expr = new Expression(p);

if (firsttoken == "print")

return new PrintCommand(expr);

else if (firsttoken == "println")

return new PrintLnCommand(expr);

else if (firsttoken == "call")

return new CallCommand(expr);

else if (firsttoken == "while")

return new WhileOperator(expr);

else if (firsttoken == "if")

return new IfOperator(expr);

else if (firsttoken == "elseif")

return new ElseifOperator(expr);

else

throw new SyntaxErrorException("Синтаксическая ошибка");

} catch (SyntaxErrorException ex) {

throw ex;

} catch (Exception ex) {

throw new SyntaxErrorException(ex.Message);

}

}

private static IOperator ParseForStatement(string str) {

str = str.Substring(3);

int assignpos = str.IndexOf(":=");

if (assignpos < 0)

throw new SyntaxErrorException("Неправильный синтаксис оператора for");

string countername = str.Substring(0, assignpos).Trim();

if (!Parser.IsID(countername))

throw new SyntaxErrorException("Неправильный синтаксис оператора for");

str = str.Substring(assignpos + 2);

int colonpos = str.IndexOf(":");

if (colonpos < 0)

throw new SyntaxErrorException("Неправильный синтаксис оператора for");

string expr1str = str.Substring(0, colonpos);

string expr2str = str.Substring(colonpos + 1);

Expression expr1 = new Expression(expr1str);

Expression expr2 = new Expression(expr2str);

return new ForOperator(countername, expr1, expr2);

}

}

}

12. Интерфейс IOperator.

namespace interpr.logic.operators {

public enum OperatorKind {

Plain,

If,

Elseif,

Else,

Endif,

While,

Loop,

For,

Next,

Return

}

public interface IOperator {

void Execute(Subroutine.Moment pos);

OperatorKind GetKind();

}

}

13. Класс Command.

namespace interpr.logic.operators {

public abstract class Command : IOperator {

public abstract void Execute();

public void Execute(Subroutine.Moment pos) {

Execute();

pos.Next();

}

public OperatorKind GetKind() {

return OperatorKind.Plain;

}

}

}

14. Класс ForOperator.

using interpr.logic.vartypes;

namespace interpr.logic.operators {

public class ForOperator : IOperator {

private int m_next_pos = -1;

private string m_counter_var = null;

private Expression m_begin = null;

private Expression m_end = null;

private IntVar m_end_res = null;

public ForOperator(string counter, Expression beg, Expression end) {

m_counter_var = counter;

m_begin = beg;

m_end = end;

}

public int NextPos {

get {

if (m_next_pos < 0)

throw new OtherException("Error in LoopOperator.NextPos");

return m_next_pos;

}

set { m_next_pos = value; }

}

public void Step(Subroutine.Moment pos, int forpos) {

Namespace cn = InterprEnvironment.Instance.CurrentNamespace;

VarBase res = cn[m_counter_var];

if (!res.IsInt())

throw new CalcException("Тип переменной - счетчика цикла был изменен");

int resval = (res as IntVar).Val;

resval++;

res = new IntVar(resval);

cn[m_counter_var] = res;

if (resval > m_end_res.Val)

pos.GoTo(m_next_pos + 1);

else

pos.GoTo(forpos + 1);

}

public void Execute(Subroutine.Moment pos) {

VarBase resb, rese;

resb = m_begin.Calculate();

if (!resb.IsInt())

throw new CalcException("Границы изменения счетчика должны быть целыми");

IntVar resbi = resb as IntVar;

Namespace cn = InterprEnvironment.Instance.CurrentNamespace;

cn[m_counter_var] = resb;

rese = m_end.Calculate();

if (!rese.IsInt())

throw new CalcException("Границы изменения счетчика должны быть целыми");

m_end_res = rese as IntVar;

if (resbi.Val > m_end_res.Val)

pos.GoTo(m_next_pos + 1);

else

pos.Next();

}

public OperatorKind GetKind() {

return OperatorKind.For;

}

}

}

15. Класс NextOperator

namespace interpr.logic.operators {

public class NextOperator : IOperator {

private int m_for_pos = -1;

private ForOperator m_for_op = null;

public NextOperator() {}

public int ForPos {

get {

if (m_for_pos < 0)

throw new OtherException("Error in NextOperator.ForPos");

return m_for_pos;

}

set { m_for_pos = value; }

}

public ForOperator ForOp {

get { return m_for_op; }

set { m_for_op = value; }

}

public void Execute(interpr.logic.Subroutine.Moment pos) {

m_for_op.Step(pos, m_for_pos);

}

public interpr.logic.operators.OperatorKind GetKind() {

return OperatorKind.Next;

}

}

}

16. Класс Subroutine.

using System;

using System.Collections;

using System.Threading;

using interpr.logic.vartypes;

using interpr.logic.operators;

namespace interpr.logic {

public sealed class Subroutine {

private void AnalyseHeader(string str) {

Parser header_p = new Parser(str);

if (!header_p.MoveNext())

throw new SyntaxErrorException("Ошибка в заголовке функции");

if ((header_p.Current as System.String) != m_name)

throw new SyntaxErrorException("Имя функции не совпадает с именем файла");

if ((!header_p.MoveNext()) || ((header_p.Current as String) != "["))

throw new SyntaxErrorException("Ошибка в заголовке функции");

if ((!header_p.MoveNext()))

throw new SyntaxErrorException("Ошибка в заголовке функции");

if ((header_p.Current as System.String != "]")) {

string readstr;

while (true) {

readstr = (header_p.Current as System.String);

if (!Parser.IsID(readstr))

throw new SyntaxErrorException("Ошибка в заголовке функции");

m_args.Add(readstr);

if (!header_p.MoveNext())

throw new SyntaxErrorException("Ошибка в заголовке функции");

readstr = (header_p.Current as System.String);

if (readstr == ",") {

if (!header_p.MoveNext())

throw new SyntaxErrorException("Ошибка в заголовке функции");

}

else if (readstr == "]")

break;

else

throw new SyntaxErrorException("Ошибка в заголовке функции");

}

}

if (header_p.MoveNext())

throw new SyntaxErrorException("Ошибка в заголовке функции");

if (m_args.IndexOf("result") >= 0)

throw new SyntaxErrorException("Параметр функции не может иметь имя \"result\"");

}

public Subroutine(string[] code, string name) {

m_name = name;

if (code.Length == 0)

throw new SyntaxErrorException("Файл функции пуст");

AnalyseHeader(code[0]);

int clen = code.Length;

int i = 0;

try {

Stack stk = new Stack();

m_operators.Add(new EmptyCommand()); //чтобы индексация начиналась с единицы

for (i = 1; i < clen; i++) {

Страницы: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17



2012 © Все права защищены
При использовании материалов активная ссылка на источник обязательна.