Visual Basic, .NET, ASP, VBScript
 

   
   
     

Форум - .NET

Страница: 1 |

 

  Вопрос: Не могу понять... Добавлено: 26.07.05 10:44  

Автор вопроса:  GlooM | Web-сайт: newlc.info | ICQ: 348453688 
/*Этот модуль содержит рекурсивный нисходящий
  анализатор, который распознает переменные
*/

using System;
//Класс исключений для ошибок анализатора
class ParserException : ApplicationException
{
public ParserException(string str) : base(str){}
public override string ToString()
{
return Message;
}
}

class Parser
{
enum Types {NONE, DELIMITER, VARIABLE, NUMBER};//Перичисляем типы лексем
enum Errors {SYNTAX, UNBALPARENS, NOEXP, DIVBYZERO};//Перечисляем типы ошибок

string exp;// Ссылка на строку выражения
int expIdx;//Текущий индекс в выражении
string token;//Текущая лексема

Types tokType;//Тип лексемы

//Массив для переменных
double[] vars = new double[26];

public Parser()
{
//Инициализируем переменные нулевыми значениями
for(int i=0;i<vars.Length;i++)
vars[i]=0.0;
}

//Входная точка
public double Evaluate(string expstr)
{
double result;

exp=expstr;
expIdx=0;

try
{
GetToken();
if(token=="")
{
SyntaxErr(Errors.NOEXP);//Выражение отсутствует
return 0.0;
}
EvalExp1(out result);/*В этом варианте анализатора
  * сначала вызывается метод
  * EvalExp1()*/
if(token != "")//Последняя лексема должна быть нулевой
SyntaxErr(Errors.SYNTAX);
return result;}
catch(ParserException exc)
{
//Можно добавить тут обработку ошибок
Console.WriteLine(exc);
return 0.0;
}
}

//Обработка присвоения
void EvalExp1(out double result)
{
int varIdx;
Types ttokType;
string temptoken;

if(tokType==Types.VARIABLE)
{
//Сохраняем старую лексему
temptoken=string.Copy(token);
ttokType=tokType;
//Вычисляем индекс переменной
varIdx=Char.ToUpper(token[0])-'A';

GetToken();

if(token != "=")
{
PutBack();/*Возвращаем текущую лексему в поток
   * и восстанавливаем старую,
   * посколько отсутствует присвоение*/
token=String.Copy(temptoken);
tokType=ttokType;
}
else
{
GetToken();//Получаем след. часть выражения exc
EvalExp2(out result);
vars[varIdx]=result;
return;
}
}
EvalExp2(out result);
}

//Складываем или вычитаем два члена выражения
void EvalExp2(out double result)
{
string op;
double partialResult;
EvalExp3(out result);
while((op=token) == "+" || op == "-")
{
GetToken();
EvalExp3(out partialResult);
switch(op)
{
case "-":
result = result - partialResult;
break;
case "+":
result = result + partialResult;
break;
}
}
}

//Выполняем умножение или деление двух множителей
void EvalExp3(out double result)
{
string op;
double partialResult=0.0;

EvalExp4(out result);
while((op=token) == "*" || op == "/" || op == "%")
{
GetToken();
EvalExp4(out partialResult);
switch(op)
{
case "*":
result = result * partialResult;
break;
case "/":
if(partialResult==0.0)
SyntaxErr(Errors.DIVBYZERO);
result = result / partialResult;
break;
case "%":
if(partialResult==0.0)
SyntaxErr(Errors.DIVBYZERO);
result = (int)result % (int) partialResult;
break;
}
}
}

//Выполняем возведение в степень
void EvalExp4(out double result)
{
double partialResult, ex;
int t;

EvalExp5(out result);
if(token=="^")
{
GetToken();
EvalExp4(out partialResult);
ex=result;
if(partialResult==0.0)
{
result=1.0;
return;
}
for(t=(int)partialResult-1;t>0;t--)
result=result*(double)ex;
}
}

//Выполняем операцию унарного + или -
void EvalExp5(out double result)
{
string op;

op="";
if((tokType==Types.DELIMITER) && token == "+" || token == "-")
{
op=token;
GetToken();
}
EvalExp6(out result);
if(op=="-")result = -result;
}

//Обработка выражений в круглых скобках
void EvalExp6(out double result)
{
if((token=="("))
{
GetToken();
EvalExp2(out result);
if(token != ")")
SyntaxErr(Errors.UNBALPARENS);
GetToken();
}
else Atom(out result);
}

//Получаем значение числа или переменной
void Atom(out double result)
{
switch(tokType)
{
case Types.NUMBER:
try
{
result=Double.Parse(token);
}
catch(FormatException)
{
result=0.0;
SyntaxErr(Errors.SYNTAX);
}
GetToken();
return;
case Types.VARIABLE:
result=FindVar(token);
GetToken();
return;
default:
result=0.0;
SyntaxErr(Errors.SYNTAX);
break;
}
}

//Возвращаем значение переменной

double FindVar(string vname)
{
if(!Char.IsLetter(vname[0]))
{
SyntaxErr(Errors.SYNTAX);
return 0.0;
}
return vars[Char.ToUpper(vname[0])-'A'];
}

//Возвращаем лексему во входной поток
void PutBack()
{
for(int i=0;i<token.Length;i++)expIdx--;
}

//Обрабатываем синтаксическую ошибку
void SyntaxErr(Errors error)
{
string[] err={
"Синтаксическая ошибка",
"Дисбаланс скобок",
"Выражение отсутствует",
"Деление на нуль"
};
throw new ParserException(err[(int)error]);
}

//Получаем следующую лексему
void GetToken()
{
tokType = Types.NONE;
token="";
if(expIdx == exp.Length) return;//Конец выражения
//Опускаем пробелы
while(expIdx < exp.Length &&
Char.IsWhiteSpace(exp[expIdx])) ++expIdx;
//Хвостовой пробел завершает выражение
if(expIdx == exp.Length) return;
if(IsDelim(exp[expIdx]))
{
token += exp[expIdx];
expIdx++;
tokType = Types.DELIMITER;
}
else if(Char.IsLetter(exp[expIdx]))
{
while(!IsDelim(exp[expIdx]))
{
token += exp[expIdx];
expIdx++;
if(expIdx >= exp.Length)break;
}
tokType = Types.VARIABLE;
}
else if(Char.IsDigit(exp[expIdx]))
{
while(!IsDelim(exp[expIdx]))
{
token += exp[expIdx];
expIdx++;
if(expIdx >= exp.Length)break;
}
tokType=Types.NUMBER;
}
}

//Метод возвращает значение true,
//если с -- разделитель
bool IsDelim(char c)
{
if((" +-/*%^=()".IndexOf(c) != -1))
return true;
return false;
}
}


ошибок нет, а не компилит.... (((

Ответить

  Ответы Всего ответов: 2  

Номер ответа: 1
Автор ответа:
 Павел



Администратор

ICQ: 326066673 

Вопросов: 368
Ответов: 5968
 Web-сайт: www.vbnet.ru
 Профиль | | #1
Добавлено: 26.07.05 12:22
------ Build started: Project: CSTest, Configuration: Debug .NET ------

Preparing resources...
Updating references...
Performing main compilation...

Build complete -- 0 errors, 0 warnings
Building satellite assemblies...



---------------------- Done ----------------------

    Build: 1 succeeded, 0 failed, 0 skipped

Ответить

Номер ответа: 2
Автор ответа:
 Павел



Администратор

ICQ: 326066673 

Вопросов: 368
Ответов: 5968
 Web-сайт: www.vbnet.ru
 Профиль | | #2
Добавлено: 26.07.05 12:24
Это на Fw 1.1. Вечером, если надо, на 2.0 попробую.

Ответить

Страница: 1 |

Поиск по форуму



© Copyright 2002-2011 VBNet.RU | Пишите нам