47083 (608070), страница 3

Файл №608070 47083 (Интерактивный интерпретатор) 3 страница47083 (608070) страница 32016-07-30СтудИзба
Просмтор этого файла доступен только зарегистрированным пользователям. Но у нас супер быстрая регистрация: достаточно только электронной почты!

Текст из файла (страница 3)

VarBase arg2 = al.Get();

if(!(arg1.IsSingle()&&arg2.IsSingle()))

throw new CalcException("Неверные типы операндов");

return (arg1 as SingleVar).and(arg2 as SingleVar);

}

}

.......................................................................................

}

}

10. Класс Parser.

using System;

using System.Collections;

namespace interpr.logic {

public class Parser : IEnumerable, IEnumerator {

private char[] m_a;

private int m_len;

private int m_cur = 0;

private int m_new_cur = -1;

private bool m_at_begin;

private static readonly string[] s_keywords =

new string[] {

"if",

"else",

"elseif",

"endif",

"while",

"loop",

"return",

"call",

"print",

"println",

"readln",

"clear",

"for",

"next",

"error"

};

private static readonly int s_keywords_length = s_keywords.Length;

private static bool IsLD(char c) {

return ((c >= 'a') && (c = 'A') && (c <= 'Z')) || (c == '0')

|| ((c >= '1') && (c <= '9')) || (c == '_');

}

private static bool IsSp(char c) {

return (c == ' ') || (c == '\t');

}

public static bool IsID(string str) {

int l = str.Length;

if (l == 0)

return false;

if (char.IsDigit(str[0]) || (!IsLD(str[0])))

return false;

int i;

for (i = 1; i < str.Length; i++)

if (!IsLD(str[i]))

return false;

for (i = 0; i < s_keywords_length; i++)

if (str == s_keywords[i])

return false;

return true;

}

public void Reset() {

m_cur = 0;

m_new_cur = -1;

m_at_begin = true;

}

public string GetString() {

return new String(m_a, 0, m_len);

}

public bool HasMore() {

return m_cur < m_len;

}

public Parser(string str) {

char[] a = str.ToCharArray();

int n = a.Length;

int i = 0;

int j = 0;

m_a = new char[n];

while (i < n) {

if (a[i] == '#') {

break;

} else if (a[i] == '\"') {

m_a[j] = '\"';

i++;

j++;

while ((i < n) && (a[i] != '\"')) {

m_a[j] = a[i];

i++;

j++;

}

if (i == n)

throw new SyntaxErrorException("Не закрытая строковая константа");

else {

m_a[j] = '\"';

i++;

j++;

}

} else if (IsSp(a[i])) {

bool flag = false;

if ((i > 0) && (IsLD(a[i - 1]))) {

m_a[j] = ' ';

j++;

flag = true;

}

while ((i < n) && IsSp(a[i]))

i++;

if (((i == n) || (!IsLD(a[i]))) && flag)

j--;

} else {

m_a[j] = a[i];

i++;

j++;

}

}

m_len = j;

Reset();

}

private string GetCurrent() {

int cur = m_cur;

int beg = m_cur;

int end = m_len;

string res = null;

bool flag = true;

if ((m_a[cur] == '.') && ((cur < end - 1) && (!char.IsDigit(m_a[cur + 1]))) || (cur == end - 1)) {

flag = true;

} else if (char.IsDigit(m_a[cur]) || (m_a[cur] == '.')) {

flag = false;

while ((cur < end) && char.IsDigit(m_a[cur]))

cur++;

if (cur == end) {

res = new String(m_a, beg, cur - beg);

} else if ((m_a[cur] == 'e') || (m_a[cur] == 'E')) {

cur++;

if (cur == end) {

cur--;

res = new String(m_a, beg, cur - beg);

} else if ((m_a[cur] == '+') || (m_a[cur] == '-')) {

cur++;

if ((cur == end) || (!char.IsDigit(m_a[cur]))) {

cur -= 2;

res = new String(m_a, beg, cur - beg);

}

while ((cur < end) && char.IsDigit(m_a[cur]))

cur++;

res = new String(m_a, beg, cur - beg);

} else if (char.IsDigit(m_a[cur])) {

while ((cur < end) && char.IsDigit(m_a[cur]))

cur++;

res = new String(m_a, beg, cur - beg);

} else {

cur--;

res = new String(m_a, beg, cur - beg);

}

} else if (m_a[cur] == '.') {

cur++;

if ((cur == end) || (!char.IsDigit(m_a[cur]))) {

cur--;

res = new String(m_a, beg, cur - beg);

} else {

while ((cur < end) && char.IsDigit(m_a[cur]))

cur++;

if (cur == end)

res = new String(m_a, beg, cur - beg);

else if ((m_a[cur] == 'e') || (m_a[cur] == 'E')) {

cur++;

if (cur == end) {

cur--;

res = new String(m_a, beg, cur - beg);

} else if ((m_a[cur] == '+') || (m_a[cur] == '-')) {

cur++;

if ((cur == end) || (!char.IsDigit(m_a[cur]))) {

cur -= 2;

res = new String(m_a, beg, cur - beg);

}

while ((cur < end) && char.IsDigit(m_a[cur]))

cur++;

res = new String(m_a, beg, cur - beg);

} else if (char.IsDigit(m_a[cur])) {

while ((cur < end) && char.IsDigit(m_a[cur]))

cur++;

res = new String(m_a, beg, cur - beg);

} else {

cur--;

res = new String(m_a, beg, cur - beg);

}

} else

res = new String(m_a, beg, cur - beg);

}

} else

res = new String(m_a, beg, cur - beg);

}

if (flag) {

if (IsLD(m_a[cur])) {

while ((cur < end) && IsLD(m_a[cur]))

cur++;

res = new String(m_a, beg, cur - beg);

} else if (m_a[cur] == '\"') {

do {

cur++;

if (m_a[cur] == '\"') {

if ((cur < end - 1) && (m_a[cur + 1] == '\"'))

cur++;

else

break;

}

} while (true);

cur++;

res = new String(m_a, beg, cur - beg);

} else if (cur < end - 1) {

switch (m_a[cur]) {

case ':':

{

cur++;

if (m_a[cur] == '=') {

cur++;

res = ":=";

} else

res = ":";

break;

}

case '~':

{

cur++;

if (m_a[cur] == '=') {

cur++;

res = "~=";

} else

res = "~";

break;

}

case '>':

{

cur++;

if (m_a[cur] == '=') {

cur++;

res = ">=";

} else

res = ">";

break;

}

case '<':

{

cur++;

switch (m_a[cur]) {

case '=':

{

cur++;

res = "<=";

break;

}

case '>':

{

cur++;

res = "<>";

break;

}

default:

{

res = "<";

break;

}

}

break;

}

default:

{

res = m_a[cur].ToString();

cur++;

break;

}

}

} else {

res = m_a[cur].ToString();

cur++;

}

}

if ((cur < end) && IsSp(m_a[cur]))

cur++;

m_new_cur = cur;

return res;

}

public object Current {

get { return GetCurrent(); }

}

public bool MoveNext() {

if (m_at_begin) {

m_at_begin = false;

return HasMore();

}

if (m_new_cur < 0)

GetCurrent();

m_cur = m_new_cur;

m_new_cur = -1;

return HasMore();

}

public IEnumerator GetEnumerator() {

return this;

}

public static bool IsUserID(string name) {

if (!IsID(name))

return false;

if (name == "abs")

return false;

if (name == "cos")

return false;

if (name == "sin")

return false;

if (name == "tg")

return false;

if (name == "arccos")

return false;

if (name == "arcsin")

return false;

if (name == "arctg")

return false;

if (name == "exp")

return false;

if (name == "pow")

return false;

if (name == "ln")

return false;

if (name == "lg")

return false;

if (name == "log")

return false;

if (name == "sqrt")

return false;

if (name == "pi")

return false;

if (name == "idiv")

return false;

if (name == "iff")

return false;

if (name == "imod")

return false;

if (name == "random")

return false;

if (name == "substr")

return false;

if (name == "strlen")

return false;

if (name == "strpos")

return false;

if (name == "toint")

return false;

if (name == "toreal")

return false;

if (name == "tostring")

return false;

if (name == "isarray")

return false;

if (name == "issingle")

return false;

if (name == "isstring")

return false;

if (name == "isnum")

return false;

if (name == "isreal")

return false;

if (name == "isint")

return false;

if (name == "size")

return false;

return true;

}

}

}

11. Класс LineCompiler.

using System;

using interpr.logic.operators;

namespace interpr.logic {

public class LineCompiler {

private LineCompiler() {}

public static Command CompileCommand(string str) {

Parser p = new Parser(str);

if (!p.HasMore()) {

return new EmptyCommand();

}

String pstr = p.GetString();

int posa = pstr.IndexOf(":=");

if (posa >= 0) {

int cq = 0;

for (int iq = 0; iq < posa; iq++)

if (pstr[iq] == '\"')

cq++;

if (cq%2 == 0) {

try {

if (posa == 0)

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

try {

if (pstr[posa - 1] == '}') {

int posob = pstr.IndexOf('{');

if ((posob posa))

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

return new AssignCommand(pstr.Substring(0, posob),

pstr.Substring(posob + 1, posa - posob - 2),

pstr.Substring(posa + 2));

} else {

return new AssignCommand(pstr.Substring(0, posa),

pstr.Substring(posa + 2));

}

} catch {

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

}

} catch (CalcException ex) {

throw new SyntaxErrorException(ex.Message);

}

}

}

p.MoveNext();

string firsttoken = (p.Current as String);

try {

if (firsttoken == "clear") {

if (!p.MoveNext())

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

Command cc = new ClearCommand(p.Current as String);

if (p.MoveNext())

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

return cc;

}

if (firsttoken == "print") {

Expression expr = new Expression(p);

return new PrintCommand(expr);

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

Expression expr = new Expression(p);

return new PrintLnCommand(expr);

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

Expression expr = new Expression(p);

return new CallCommand(expr);

} else {

p.Reset();

Expression expr1 = new Expression(p);

return new PrintLnCommand(expr1);

}

} catch (SyntaxErrorException ex) {

throw ex;

} catch (Exception ex) {

throw new SyntaxErrorException(ex.Message);

}

}

public static IOperator CompileOperator(string str) {

Parser p = new Parser(str);

if (!p.HasMore()) {

return new EmptyCommand();

}

String pstr = p.GetString();

p.MoveNext();

string firsttoken = (p.Current as String);

if (firsttoken == "for") {

try {

return ParseForStatement(p.GetString());

} catch (SyntaxErrorException ex) {

throw ex;

} catch (Exception ex) {

throw new SyntaxErrorException(ex.Message);

}

}

int posa = pstr.IndexOf(":=");

if (posa >= 0) {

int cq = 0;

for (int iq = 0; iq < posa; iq++)

if (pstr[iq] == '\"')

cq++;

if (cq%2 == 0) {

try {

if (posa == 0)

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

try {

if (pstr[posa - 1] == '}') {

int posob = pstr.IndexOf('{');

if ((posob posa))

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

return new AssignCommand(pstr.Substring(0, posob),

pstr.Substring(posob + 1, posa - posob - 2),

pstr.Substring(posa + 2));

} else {

return new AssignCommand(pstr.Substring(0, posa),

pstr.Substring(posa + 2));

}

} catch {

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

}

} catch (CalcException ex) {

throw new SyntaxErrorException(ex.Message);

}

}

}

try {

if (firsttoken == "clear") {

if (!p.MoveNext())

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

Command cc = new ClearCommand(p.Current as String);

if (p.MoveNext())

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

return cc;

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

if (p.MoveNext())

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

return new NextOperator();

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

if (p.MoveNext())

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

return new ElseOperator();

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

if (p.MoveNext())

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

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++) {

IOperator op = LineCompiler.CompileOperator(code[i]);

if (op == null)

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

m_operators.Add(op);

switch (op.GetKind()) {

case OperatorKind.If:

case OperatorKind.While:

case OperatorKind.For:

{

stk.Push(i);

break;

}

case OperatorKind.Elseif:

{

if (stk.Count == 0)

throw new SyntaxErrorException("Лишнее elseif");

int j = (int) stk.Pop();

switch ((m_operators[j] as IOperator).GetKind()) {

case OperatorKind.If:

{

(m_operators[j] as IfOperator).NextPos = i;

break;

}

case OperatorKind.Elseif:

{

(m_operators[j] as ElseifOperator).NextPos = i;

break;

}

default:

throw new SyntaxErrorException("Лишнее elseif");

}

stk.Push(i);

break;

}

case OperatorKind.Else:

{

if (stk.Count == 0)

throw new SyntaxErrorException("Лишнее else");

int j = (int) stk.Pop();

stk.Push(i);

switch ((m_operators[j] as IOperator).GetKind()) {

case OperatorKind.If:

{

(m_operators[j] as IfOperator).NextPos = i;

break;

}

case OperatorKind.Elseif:

{

(m_operators[j] as ElseifOperator).NextPos = i;

break;

}

default:

throw new SyntaxErrorException("Лишнее else");

}

break;

}

case OperatorKind.Endif:

{

if (stk.Count == 0)

throw new SyntaxErrorException("Лишнее endif");

int j = (int) stk.Pop();

switch ((m_operators[j] as IOperator).GetKind()) {

case OperatorKind.If:

{

(m_operators[j] as IfOperator).NextPos = i;

break;

}

case OperatorKind.Elseif:

{

(m_operators[j] as ElseifOperator).NextPos = i;

break;

}

case OperatorKind.Else:

{

(m_operators[j] as ElseOperator).NextPos = i;

break;

}

default:

throw new SyntaxErrorException("Лишнее endif");

}

break;

}

case OperatorKind.Loop:

{

if (stk.Count == 0)

throw new SyntaxErrorException("Лишнее loop");

int j = (int) stk.Pop();

if ((m_operators[j] as IOperator).GetKind() != OperatorKind.While)

throw new SyntaxErrorException("Лишнее loop");

(m_operators[i] as LoopOperator).WhilePos = j;

(m_operators[j] as WhileOperator).LoopPos = i;

break;

}

case OperatorKind.Next:

{

if (stk.Count == 0)

throw new SyntaxErrorException("Лишнее next");

int j = (int) stk.Pop();

if ((m_operators[j] as IOperator).GetKind() != OperatorKind.For)

throw new SyntaxErrorException("Лишнее next");

(m_operators[i] as NextOperator).ForPos = j;

(m_operators[i] as NextOperator).ForOp = (m_operators[j] as ForOperator);

(m_operators[j] as ForOperator).NextPos = i;

break;

}

}

}

if (stk.Count != 0)

throw new SyntaxErrorException("Не закрытый блок");

}

catch (SyntaxErrorException ex) {

throw new LineSyntaxException(ex.Message, m_name, i + 1);

}

m_count = m_operators.Count;

}

private string m_name;

private ArrayList m_args = new ArrayList();

private ArrayList m_operators = new ArrayList();

private int m_count;

public int ReqCount {

get { return m_args.Count; }

}

public VarBase Perform(ArgList al) {

Namespace ns = new Namespace(InterprEnvironment.Instance.CurrentNamespace);

ns["result"] = new IntVar(0);

int argc = m_args.Count;

if (al.Count != argc)

throw new CalcException("Неверное число параметров");

al.Reset();

for (int i = 0; i < argc; i++) {

ns[m_args[i] as System.String] = al.Get();

}

InterprEnvironment.Instance.CurrentNamespace = ns;

Moment moment = new Moment(this);

if (m_count > 1) {

try {

moment.Run();

}

catch (SyntaxErrorException ex) {

throw ex;

}

catch (CalcException ex) {

throw new CalcException("Ошибка в функции " + m_name + "[] в строке " + (moment.Pos + 1) + " : " + ex.Message);

}

}

VarBase res = ns["result"];

InterprEnvironment.Instance.CurrentNamespace = ns.PreviousNamespace;

if (res == null)

throw new CalcException("Ошибка в функции " + m_name + "[] : переменная result не определена на момент выхода");

return res;

}

public class Moment {

private Subroutine m_sub;

private int m_pos;

private static int s_break = 0;

public static void Break() {

Interlocked.Exchange(ref s_break, 1);

}

public int Pos {

get { return m_pos; }

}

public Moment(Subroutine sub) {

m_sub = sub;

m_pos = 1;

s_break = 0;

}

public void GoTo(int to) {

m_pos = to;

}

public void Next() {

m_pos++;

}

public void Run() {

while (m_pos < m_sub.m_count) {

if (s_break == 1)

throw new CalcException("Прервано пользователем");

(m_sub.m_operators[m_pos] as IOperator).Execute(this);

}

}

public void Return() {

m_pos = m_sub.m_count;

}

public IOperator Current {

get { return m_sub.m_operators[m_pos] as IOperator; }

}

}

}

}

17. Класс Facade.

using System.Threading;

using interpr.logic;

using interpr.logic.operators;

namespace interpr {

public class Facade {

private static Facade s_instance = null;

public static void Create(IConsole console) {

if (s_instance == null)

s_instance = new Facade(console);

}

public static Facade Instance {

get { return s_instance; }

}

private IConsole m_console;

private InterprEnvironment m_env;

private string m_cmd;

private bool m_doing = false;

private Facade(IConsole console) {

m_console = console;

m_env = InterprEnvironment.Instance;

m_env.CurrentConsole = m_console;

}

public delegate void CommandDoneHandler();

public event CommandDoneHandler Done;

private void ThrStart() {

m_doing = true;

Command cmd;

do {

try {

cmd = LineCompiler.CompileCommand(m_cmd);

}

catch (SyntaxErrorException ex) {

m_env.CurrentConsole.PrintLn("Ошибка : " + ex.Message);

break;

}

try {

cmd.Execute();

}

catch (CalcException ex) {

m_env.CurrentConsole.PrintLn("Ошибка : " + ex.Message);

m_env.CurrentNamespace = m_env.ConsoleNamespace;

break;

}

} while (false);

Done();

m_doing = false;

}

public void ExecuteCommand(string cmd) {

if (m_doing)

throw new OtherException("Error in Bridge.ExecuteCommand()");

m_cmd = cmd;

new Thread(new ThreadStart(ThrStart)).Start();

}

private void DoRestart() {

if (m_doing)

Subroutine.Moment.Break();

while (m_doing) {}

InterprEnvironment.Reset();

m_env = InterprEnvironment.Instance;

m_env.CurrentConsole = m_console;

m_env.LoadSubs();

}

public void Restart() {

new Thread(new ThreadStart(DoRestart)).Start();

}

public bool Busy {

get { return m_doing; }

}

public void SaveVariables() {

m_env.SaveVars();

}

public void LoadSubs() {

m_env.LoadSubs();

}

public ConsoleNamespace.VariableReport[] GetVariables() {

return m_env.GetGlobalVarsList();

}

public string[] GetSubs() {

return m_env.LoadedSubs;

}

public void DeleteVariable(string name) {

m_env.ConsoleNamespace.Remove(name);

}

public bool LoadSub(string name) {

return m_env.LoadSub(name);

}

public void UnloadSub(string name) {

m_env.UnloadSub(name);

}

public bool NotRestored {

get {

return m_env.NotRestored;

}

}

}

}

18. Класс SourceBox.

using System;

using System.ComponentModel;

using System.Drawing;

using System.Windows.Forms;

namespace interpr {

public class SourceBox : UserControl {

private RichTextBox m_tb;

private TextBox m_tb_2;

....................................................................

private int m_curline = 0;//текущая строка

private int m_lincount = 0;//общее число строк

private HighlightParser m_hp = new HighlightParser();

private static Font s_nfont =

new Font("Lucida Console", 10, FontStyle.Regular);

private static Font s_cfont =

new Font("Lucida Console", 12, FontStyle.Bold);

private int GetCurrentLine() {

return m_tb.GetLineFromCharIndex(m_tb.SelectionStart);

}

private int GetLinesCount() {

return m_tb.Lines.Length;

}

private String GetLine(int index) {

return m_tb.Lines[index];

}

private void m_tb_KeyPress(object sender, KeyPressEventArgs e) {

if (e.KeyChar == '\r') {

string txt = m_tb.Text;

int i = m_tb.SelectionStart - 2;

int j;

while (i >= 0) {

if (txt[i] == '\n')

return;

else if (txt[i] == '\t') {

j = 0;

while ((i >= 0) && (txt[i] == '\t')) {

j++;

i--;

}

if ((i < 0) || (txt[i] == '\n')) {

m_tb.SelectedText = new String('\t', j);

return;

}

}

i--;

}

}

}

private bool GetLinePos(int index, out int beg, out int len) {

if ((index = GetLinesCount())) {

beg = len = 0;

return false;

}

int i;

string[] ls = m_tb.Lines;

beg = 0;

for (i = 0; i < index; i++)

beg += ls[i].Length + 1;

len = ls[index].Length;

return true;

}

private void SelectLine(int index) {

int beg, len;

if (!GetLinePos(index, out beg, out len))

throw new IndexOutOfRangeException();

m_tb.SelectionStart = beg;

m_tb.SelectionLength = len;

}

private void HighlightLine(int index) {

int beg, len;

int curbeg = m_tb.SelectionStart;

int curlen = m_tb.SelectionLength;

GetLinePos(index, out beg, out len);

string str = m_tb.Lines[index];

m_hp.Reset(str);

while (m_hp.HasMore()) {

int tbeg, tlen;

HighlightParser.TokenType type;

m_hp.GetNext(out tbeg, out tlen, out type);

m_tb.SelectionStart = beg + tbeg;

m_tb.SelectionLength = tlen;

switch (type) {

case HighlightParser.TokenType.Comment:

{

m_tb.SelectionColor = Color.DarkGreen;

break;

}

case HighlightParser.TokenType.Identifier:

{

m_tb.SelectionColor = Color.Purple;

break;

}

case HighlightParser.TokenType.Keyword:

{

m_tb.SelectionColor = Color.Blue;

break;

}

case HighlightParser.TokenType.Number:

{

m_tb.SelectionColor = Color.Red;

break;

}

case HighlightParser.TokenType.String:

{

m_tb.SelectionColor = Color.Brown;

break;

}

case HighlightParser.TokenType.Other:

{

m_tb.SelectionColor = Color.Black;

break;

}

}

}

m_tb.SelectionStart = curbeg;

m_tb.SelectionLength = curlen;

}

public enum LineState {

ErrorLine,

CurrentLine,

NormalLine

}

private void ColorLine(int index, LineState state) {

int curbeg = m_tb.SelectionStart;

int curlen = m_tb.SelectionLength;

SelectLine(index);

switch (state) {

case LineState.ErrorLine:

{

m_tb.SelectionColor = Color.Red;

break;

}

case LineState.CurrentLine:

{

m_tb.SelectionFont = s_cfont;

break;

}

case LineState.NormalLine:

{

m_tb.SelectionFont = s_nfont;

HighlightLine(index);

break;

}

}

m_tb.SelectionStart = curbeg;

m_tb.SelectionLength = curlen;

}

private void HighlightText(bool anyway) {

int l = GetCurrentLine();

int lc = GetLinesCount();

if ((l != m_curline) || (lc != m_lincount) || anyway) {

m_tb_2.Focus();

m_curline = l;

m_lincount = lc;

int bi = m_tb.GetCharIndexFromPosition(new Point(0, 0));

int ei = m_tb.GetCharIndexFromPosition(new Point(m_tb.Size));

int bl = m_tb.GetLineFromCharIndex(bi);

int el = m_tb.GetLineFromCharIndex(ei);

if (bl > 0) bl--;

if (el < lc) el++;

for (int i = bl; i < el; i++)

HighlightLine(i);

m_tb.Focus();

}

}

private void m_tb_KeyUp(object sender, KeyEventArgs e) {

HighlightText(false);

}

private void m_tb_MouseUp(object sender, MouseEventArgs e) {

if (e.Button == MouseButtons.Left)

HighlightText(true);

}

public string[] Lines {

get { return (string[]) m_tb.Lines.Clone(); }

}

public bool LoadFile(string filename) {

try {

m_tb.LoadFile(filename, RichTextBoxStreamType.PlainText);

HighlightText(true);

return true;

}

catch {

return false;

}

}

public bool SaveFile(string filename) {

try {

m_tb.SaveFile(filename, RichTextBoxStreamType.PlainText);

return true;

}

catch {

return false;

}

}

public int CurrentLine {

get { return m_tb.GetLineFromCharIndex(m_tb.SelectionStart); }

}

private class HighlightParser {

private char[] m_a;

private int m_len;

private int m_cur;

public enum TokenType {

String,

Number,

Keyword,

Comment,

Identifier,

Other

}

public void Reset(string str) {

m_a = str.ToCharArray();

m_len = str.Length;

m_cur = 0;

while ((m_cur < m_len) && Char.IsWhiteSpace(m_a[m_cur]))

m_cur++;

}

public bool HasMore() {

return m_cur < m_len;

}

private bool IsKeyword(string str) {

return

(str == "if") ||

(str == "else") ||

(str == "elseif") ||

(str == "endif") ||

(str == "while") ||

(str == "loop") ||

(str == "return") ||

(str == "result") ||

(str == "call") ||

(str == "print") ||

(str == "println") ||

(str == "readln") ||

(str == "clear") ||

(str == "for") ||

(str == "next") ||

(str == "error");

}

public void GetNext(out int beg, out int len, out TokenType type) {

if (m_cur >= m_len)

throw new IndexOutOfRangeException();

beg = m_cur;

if (m_a[m_cur] == '\"') {

m_cur++;

while ((m_cur < m_len) && (m_a[m_cur] != '\"'))

m_cur++;

if (m_cur < m_len)

m_cur++;

len = m_cur - beg;

type = TokenType.String;

}

else if (isL(m_a[m_cur])) {

m_cur++;

while ((m_cur < m_len) && isLD(m_a[m_cur]))

m_cur++;

len = m_cur - beg;

if (IsKeyword(new string(m_a, beg, len)))

type = TokenType.Keyword;

else

type = TokenType.Identifier;

}

else if (m_a[m_cur] == '#') {

len = m_len - m_cur;

m_cur = m_len;

type = TokenType.Comment;

}

else if (m_a[m_cur] == '.') {

if (GetNumber()) {

len = m_cur - beg;

type = TokenType.Number;

}

else {

m_cur = beg + 1;

len = 1;

type = TokenType.Other;

}

}

else if (char.IsDigit(m_a[m_cur])) {

GetNumber();

len = m_cur - beg;

type = TokenType.Number;

}

else {

m_cur++;

len = 1;

type = TokenType.Other;

}

while ((m_cur < m_len) && Char.IsWhiteSpace(m_a[m_cur]))

m_cur++;

}

private bool GetNumber() {

if (!((m_a[m_cur] == '.') || char.IsDigit(m_a[m_cur])))

return false;

while ((m_cur < m_len) && char.IsDigit(m_a[m_cur]))

m_cur++;

if (m_cur == m_len)

return true;

else if (m_a[m_cur] == '.') {

m_cur++;

while ((m_cur < m_len) && char.IsDigit(m_a[m_cur]))

m_cur++;

if (m_cur == m_len)

return true;

else if ((m_a[m_cur] == 'e') || (m_a[m_cur] == 'E')) {

int p1 = m_cur;

m_cur++;

if (m_cur == m_len) {

m_cur = p1;

return true;

}

else if ((m_a[m_cur] == '-') || (m_a[m_cur] == '+')) {

m_cur++;

if ((m_cur == m_len) || !char.IsDigit(m_a[m_cur])) {

m_cur = p1;

return true;

}

while ((m_cur < m_len) && char.IsDigit(m_a[m_cur]))

m_cur++;

return true;

}

else if (char.IsDigit(m_a[m_cur])) {

while ((m_cur < m_len) && char.IsDigit(m_a[m_cur]))

m_cur++;

return true;

}

else {

m_cur = p1;

return true;

}

}

else

return true;

}

else if ((m_a[m_cur] == 'e') || (m_a[m_cur] == 'E')) {

int p1 = m_cur;

m_cur++;

if (m_cur == m_len) {

m_cur = p1;

return true;

}

else if ((m_a[m_cur] == '-') || (m_a[m_cur] == '+')) {

m_cur++;

if ((m_cur == m_len) || !char.IsDigit(m_a[m_cur])) {

m_cur = p1;

return true;

}

while ((m_cur < m_len) && char.IsDigit(m_a[m_cur]))

m_cur++;

return true;

}

else if (char.IsDigit(m_a[m_cur])) {

while ((m_cur < m_len) && char.IsDigit(m_a[m_cur]))

m_cur++;

return true;

}

else {

m_cur = p1;

return true;

}

}

else

return true;

}

private static bool isLD(char c) {

return ((c >= 'a') && (c = 'A') && (c <= 'Z')) || (c == '0')

|| ((c >= '1') && (c <= '9')) || (c == '_');

}

private static bool isL(char c) {

return ((c >= 'a') && (c = 'A') && (c <= 'Z')) || (c == '_');

}

}

}

}

19. Класс Form1.

using System;

using System.ComponentModel;

using System.Windows.Forms;

namespace interpr {

public class Form1 : Form {

private Panel panel1;

private Button button1;

private Button button2;

private Button button3;

private Button button4;

private Button button5;

private ConsoleBox consoleBox1;

private Facade m_fasade;

private void Form1_Load(object sender, EventArgs e) {

Facade.Create(consoleBox1);

m_fasade = Facade.Instance;

if (m_fasade.NotRestored) {

MessageBox.Show("Ошибка! Переменные не были успешно восстановлены.");

}

m_fasade.Done += new Facade.CommandDoneHandler(EndExec);

m_fasade.LoadSubs();

consoleBox1.Prompt();

}

private void EndExec() {

consoleBox1.Prompt();

}

private void button1_Click(object sender, EventArgs e) {

if (m_fasade.Busy) {

MessageBox.Show("Не могу открыть окно функций во время выполнения комманды!");

return;

}

FunctionsForm ff = new FunctionsForm(m_fasade);

ff.ShowDialog();

EditorForm ef = ff.LastOpenedEditorForm;

if (ef != null) {

ef.Activate();

ff.SetLastEditorFormNull();

}

else

consoleBox1.Focus();

}

private void button2_Click(object sender, EventArgs e) {

if (m_fasade.Busy) {

MessageBox.Show("Не могу открыть окно переменных во время выполнения комманды!");

return;

}

VariablesForm vf = new VariablesForm(m_fasade);

vf.ShowDialog();

consoleBox1.Focus();

}

private void consoleBox1_GetCommand(object sender, ConsoleBoxGetCommandEventArgs e) {

if (e.Command.Length > 0)

m_fasade.ExecuteCommand(e.Command);

else

consoleBox1.Prompt();

}

private void button3_Click(object sender, EventArgs e) {

m_fasade.Restart();

if (m_fasade.NotRestored) {

MessageBox.Show("Ошибка! Переменные не были успешно восстановлены.");

}

consoleBox1.Focus();

}

private void button5_Click(object sender, EventArgs e) {

if (m_fasade.Busy) {

MessageBox.Show("Не могу сохранить переменные во время выполнения программы");

return;

}

m_fasade.SaveVariables();

consoleBox1.Focus();

}

private void Form1_Closing(object sender, CancelEventArgs e) {

if (EditorForm.ThereAreOpened()) {

MessageBox.Show("Сначала закройте все окна редактора кода.");

e.Cancel = true;

return;

}

m_fasade.SaveVariables();

}

private void button4_Click(object sender, EventArgs e) {

this.Close();

}

}

}


Использованная литература и документация.

  1. А. Ахо, Дж. Хопкрофт, Д. Ульман. Структуры данных и алгоритмы – М. «Вильямс», 2003.

  2. Э. Гамма, Р. Хелм, Р. Джонсон, Дж. Влиссидес. Приемы объектно-ориентированного проектирования: паттерны проектирования – СПб., «Питер», 2001.

  3. Д. Грис. Конструирование компиляторов для цифровых вычислительных машин – М. «Мир», 1975.

  4. Г. Корнелл, Дж. Моррисон. Программирование на VB.NET. Учебный курс – СПб., «Питер», 2002.

  5. Э. Троелсен. C# и платформа .NET – СПб., «Питер», 2004.

  6. MSDN Library – April 2003.


Характеристики

Тип файла
Документ
Размер
5,11 Mb
Тип материала
Учебное заведение
Неизвестно

Список файлов курсовой работы

Свежие статьи
Популярно сейчас
Как Вы думаете, сколько людей до Вас делали точно такое же задание? 99% студентов выполняют точно такие же задания, как и их предшественники год назад. Найдите нужный учебный материал на СтудИзбе!
Ответы на популярные вопросы
Да! Наши авторы собирают и выкладывают те работы, которые сдаются в Вашем учебном заведении ежегодно и уже проверены преподавателями.
Да! У нас любой человек может выложить любую учебную работу и зарабатывать на её продажах! Но каждый учебный материал публикуется только после тщательной проверки администрацией.
Вернём деньги! А если быть более точными, то автору даётся немного времени на исправление, а если не исправит или выйдет время, то вернём деньги в полном объёме!
Да! На равне с готовыми студенческими работами у нас продаются услуги. Цены на услуги видны сразу, то есть Вам нужно только указать параметры и сразу можно оплачивать.
Отзывы студентов
Ставлю 10/10
Все нравится, очень удобный сайт, помогает в учебе. Кроме этого, можно заработать самому, выставляя готовые учебные материалы на продажу здесь. Рейтинги и отзывы на преподавателей очень помогают сориентироваться в начале нового семестра. Спасибо за такую функцию. Ставлю максимальную оценку.
Лучшая платформа для успешной сдачи сессии
Познакомился со СтудИзбой благодаря своему другу, очень нравится интерфейс, количество доступных файлов, цена, в общем, все прекрасно. Даже сам продаю какие-то свои работы.
Студизба ван лав ❤
Очень офигенный сайт для студентов. Много полезных учебных материалов. Пользуюсь студизбой с октября 2021 года. Серьёзных нареканий нет. Хотелось бы, что бы ввели подписочную модель и сделали материалы дешевле 300 рублей в рамках подписки бесплатными.
Отличный сайт
Лично меня всё устраивает - и покупка, и продажа; и цены, и возможность предпросмотра куска файла, и обилие бесплатных файлов (в подборках по авторам, читай, ВУЗам и факультетам). Есть определённые баги, но всё решаемо, да и администраторы реагируют в течение суток.
Маленький отзыв о большом помощнике!
Студизба спасает в те моменты, когда сроки горят, а работ накопилось достаточно. Довольно удобный сайт с простой навигацией и огромным количеством материалов.
Студ. Изба как крупнейший сборник работ для студентов
Тут дофига бывает всего полезного. Печально, что бывают предметы по которым даже одного бесплатного решения нет, но это скорее вопрос к студентам. В остальном всё здорово.
Спасательный островок
Если уже не успеваешь разобраться или застрял на каком-то задание поможет тебе быстро и недорого решить твою проблему.
Всё и так отлично
Всё очень удобно. Особенно круто, что есть система бонусов и можно выводить остатки денег. Очень много качественных бесплатных файлов.
Отзыв о системе "Студизба"
Отличная платформа для распространения работ, востребованных студентами. Хорошо налаженная и качественная работа сайта, огромная база заданий и аудитория.
Отличный помощник
Отличный сайт с кучей полезных файлов, позволяющий найти много методичек / учебников / отзывов о вузах и преподователях.
Отлично помогает студентам в любой момент для решения трудных и незамедлительных задач
Хотелось бы больше конкретной информации о преподавателях. А так в принципе хороший сайт, всегда им пользуюсь и ни разу не было желания прекратить. Хороший сайт для помощи студентам, удобный и приятный интерфейс. Из недостатков можно выделить только отсутствия небольшого количества файлов.
Спасибо за шикарный сайт
Великолепный сайт на котором студент за не большие деньги может найти помощь с дз, проектами курсовыми, лабораторными, а также узнать отзывы на преподавателей и бесплатно скачать пособия.
Популярные преподаватели
Добавляйте материалы
и зарабатывайте!
Продажи идут автоматически
7027
Авторов
на СтудИзбе
260
Средний доход
с одного платного файла
Обучение Подробнее