Не понимаю формулировку задачи - C#

Формулировка задачи:

Задание.
Написать программу, которая по заданной сумме (определение понятия содержится в формулировке предыдущей задачи) вычисляет и печатает либо значение этой суммы, либо сообщение «при вычислении суммы получен промежуточный результат, превосходящий по модулю миллион».
Предыдущее задание с формулировкой суммы.
Кликните здесь для просмотра всего текста
Построить синтаксический анализатор для понятия сумма: сумма ::= целое{знак-операции целое}* целое ::= цифра{цифра}* знак-операции ::= Например, 021 + 16 и 22- суммы, а +1 –не сумма.
Что от меня хотят и как мне начать это реализовывать? Добавлено через 17 минут по сути,в предыдущем задании нужно построить синтаксический анализатор для понятия сумма. Но все равно не понимаю,как мое сделать

Код к задаче: «Не понимаю формулировку задачи - C#»

textual
using System;
using System.IO;
 
namespace Algorithms
{
    internal class Program
    {
 
        static void Main()
        {
            try
            {
                //выводим сумму, если она корректна
                Console.WriteLine(ComputeExpr(Console.In));
            }
            catch (Exception ex)
            {
                //Тут выводим либо, Incorrect expression!, если накосячил с вводом
                //или вот ту длинную хрень по заданию, если промежуточная сумма ...бла-бла-бла
                Console.WriteLine(ex.Message);
            }
            Console.ReadKey(true);
        }
 
        //доступные лексемы(состояния)
        private enum TokenValue
        {
            Plus = '+', Minus = '-', Number = 0, END = 1
        }
        //текущее значение
        private static int _currNum;
        //текущая лексема или состояние - это как захочется назвать
        private static TokenValue _currToken;
        //это наше ограничение на промежуточное значение суммы
        private const int UPPER_BOUND = 1000000;
 
        //вбросит исключение, если переполнилась текущая сумма 
        //по абсолютному значению, тем самым вычисление будет остановлено
        private static void CheckValue(int num)
        {
            if (Math.Abs(num) > UPPER_BOUND)
                throw new Exception("при вычислении суммы получен промежуточный результат, превосходящий по модулю миллион");
        }
 
        //само решение
        private static int ComputeExpr(TextReader expr)
        {
            //получаем, первое число
            
            int left = GetPrimary(expr);
            //текущее состояние должно быть либо Plus, либо Minus, либо END
            //т.к. мы уже распарсили число.
            //погнали считать пока не упремся в конец выражения
            while (true)
                switch (_currToken)
                {
                    //если +, то пытаемся получить следующее число
                    //и прибавить результат.
                    case TokenValue.Plus:
                        left += GetPrimary(expr);
                        CheckValue(left);
                        break;
                    //аналогично, только с '-'
                    case TokenValue.Minus:
                        left -= GetPrimary(expr);
                        CheckValue(left);
                        break;
                    default:
                        //достигли конца, возвращаем результат
                        return left; 
                }
        }
 
        //возвращает следующее число
        static int GetPrimary(TextReader expr)
        {
            //читаем и устанавливаем состояние
            //устанавливаются поля _currNum и _currToken
            ReadToken(expr);
 
            switch(_currToken)
            {
                case TokenValue.Number:
                    int d = _currNum; 
                    //вновь читаем следующую лексему
                    //она обязана быть уже не числом
                    ReadToken(expr);
                    return d;
                default:
                    //если текущее состояние не число, то косяк, т.е. неверное выражение
                    //швыряем исключение
                    throw new Exception("Incorrect expression!");
            }
        }
 
        //читалка лексем
        static void ReadToken(TextReader expr)
        {
            int c;
            //скипаем пробелы
            while ((c = expr.Peek()) != -1 && c == ' ') 
                expr.Read();
            //ну тут код сам за себя говорит, что он делает
            switch (c)
            {
                case '+':
                case '-':
                    _currToken = (TokenValue)expr.Read();
                    break;
                case -1: case '\n': case '\r':
                    _currToken = TokenValue.END;
                    return;
                default:
                    //все что не конец потока и не операция считаем числом
                    //и пытаемся его распарсить
                    _currNum = GetNum(expr);
                    _currToken = TokenValue.Number;
                    break;
            }
        }
 
        //парсинг числа
        private static int GetNum(TextReader exp)
        {
            int c, num = 0;
            //скипаем ведущие пробелы
            while ((c = exp.Peek()) != -1 &&  c == ' ') 
                exp.Read() ;
            //если уперлись в конец потока или не в цифру, то опять же это косяк 
            //в введенном выражении
            if(c == -1 || !char.IsDigit((char)c)) 
                throw new Exception("Incorrect expression!");
            //какая-то кривожопая проверка на конец числа, ну что есть то есть:)
            while ((c = exp.Peek()) != -1 && c != '+' && c != '-' && c != ' ' && c != '\n' && c != '\r')
            {
                //если не цифра, то кривые руки у пользователя
                if(!char.IsDigit((char)c))
                    throw new Exception("Incorrect expression!");
                num *= 10; //сдвигаем на разряд влево
                num += (c - '0'); //если непонятно, то смотрим в таблицу ASCII и еще раз пытаемся понять
                exp.Read();
            }
            return num;
        }
    }
 
}

8   голосов, оценка 4.250 из 5


СОХРАНИТЬ ССЫЛКУ