Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Общие вопросы по .NET и C# > Лексический анализатор


Автор: Alexandr507 9.3.2010, 15:33
Доброго времени суток.

в университете задали такую задачку написать

Цитата

Требуется написать программу, которая выполняет лексический анализ входного текста в соответствии с заданием и порождает таблицу лексем с указанием их типов и значений. Текст на входном языке задается в виде символьного (текстового) файла. Программа должна выдавать сообщения о наличие во входном тексте ошибок, которые могут быть обнаружены на этапе лексического анализа.
Длину идентификаторов и строковых констант считать ограниченной 32 символами. Программа должна допускать наличие комментариев неограниченной длины во входном файле. Форму организации комментариев предлагается выбрать самостоятельно.

Входной язык содержит логические выражения, разделенные символом ;(точка с запятой). Логические выражения состоят из идентификаторов, констант 0 и 1, знака присваивания (:=), знаков операций or, xor, and, not и круглых скобок.

по поводу   присвоения := не ругайтесь раньше времени задание по умолчанию ориентированно на паскаль, но делать можно на любом языке.

вообщем я начал разбираться.. как я понял суть такая. непосредственно в самой программе я  ввожу например :

Цитата

bool y = true || false;
bool z = true ^ false ^ true;

int x = false; 



нажимаю enter  и запускается код который обрабатывает  введенное выражение и если есть то находит ошибки указывая их тип. например   тут будет ошибка

Цитата

int x = false;  нельзя присвоить логическое значение к типу int

 Нужно описать все эти правила в коде?  чтобы программа находила ошибки типа и т п

Цитата

 x === y;
x = y'

собственно то чем занимается компилятор когда подчеркивыает значение и высвечивает тип ошибки..Что то типа Сканера

Вообщем надеюсь я правильно представляю программу..если правильно..то подскажите..куда копать собственно..
Пока единственное что разумное приходит в голову это с помощью оператора split  разделять строку     используя в качестве разделителя  символ точки с запятой ;
и то есть потом с каждым элемента полученного массива работать отдельно

ps - я вижу эту программу довольно длинной с тщательным описанием возможных ситуаций..просто может быть существует какой то иной прием

Автор: Dims 10.3.2010, 10:47
Если я правильно помню, что такое "лексический анализ" smile

Нужно читать текст посимвольно, и написать "распознаватель" для каждой лексемы. "Распознаватель" может быть в виде отдельной функции или блока в одной, большой, функции. Задача распознавателя -- сдвинуть текущую позицию чтения на длину найденной лексемы. Если распознаватель не сдвинул позицию, значит, он не опознал лексему. Внешний блок или отдельная функция должны просто по очереди пробовать каждый распознаватель и если не подошёл ни один, то выдавать ошибку. 

Пример ошибки, который ты привёл (int x = false), это не лексическая ошибка, а синтаксическая. Твоя программа не должна находить такие ошибки, так как лексически тут всё правильно. Точно так же, твоя программа не должна проверять парность скобок и т.п. Она просто должна преобразовать массив типа "char" в массив типа "лексема".

А вот здесь (x === y;) есть и лексическая ошибка, так как лексемы === не существует.

Автор: Sveta12 15.1.2013, 21:12
Цитата(Alexandr507 @ 9.3.2010,  15:33)
Доброго времени суток.

в университете задали такую задачку написать

Цитата

Требуется написать программу, которая выполняет лексический анализ входного текста в соответствии с заданием и порождает таблицу лексем с указанием их типов и значений. Текст на входном языке задается в виде символьного (текстового) файла. Программа должна выдавать сообщения о наличие во входном тексте ошибок, которые могут быть обнаружены на этапе лексического анализа.
Длину идентификаторов и строковых констант считать ограниченной 32 символами. Программа должна допускать наличие комментариев неограниченной длины во входном файле. Форму организации комментариев предлагается выбрать самостоятельно.

Входной язык содержит логические выражения, разделенные символом ;(точка с запятой). Логические выражения состоят из идентификаторов, констант 0 и 1, знака присваивания (:=), знаков операций or, xor, and, not и круглых скобок.

по поводу   присвоения := не ругайтесь раньше времени задание по умолчанию ориентированно на паскаль, но делать можно на любом языке.

вообщем я начал разбираться.. как я понял суть такая. непосредственно в самой программе я  ввожу например :

Цитата

bool y = true || false;
bool z = true ^ false ^ true;

int x = false; 



нажимаю enter  и запускается код который обрабатывает  введенное выражение и если есть то находит ошибки указывая их тип. например   тут будет ошибка

Цитата

int x = false;  нельзя присвоить логическое значение к типу int

 Нужно описать все эти правила в коде?  чтобы программа находила ошибки типа и т п

Цитата

 x === y;
x = y'

собственно то чем занимается компилятор когда подчеркивыает значение и высвечивает тип ошибки..Что то типа Сканера

Вообщем надеюсь я правильно представляю программу..если правильно..то подскажите..куда копать собственно..
Пока единственное что разумное приходит в голову это с помощью оператора split  разделять строку     используя в качестве разделителя  символ точки с запятой ;
и то есть потом с каждым элемента полученного массива работать отдельно

ps - я вижу эту программу довольно длинной с тщательным описанием возможных ситуаций..просто может быть существует какой то иной прием

Подскажите пожалуйста, вот тоже необходимо написать лексический анализатор на C#, для языка VB. описала все кроме комментарий, в VB только однострочные и начитаютмя либо с ' либо со слова REM. вот именно ошибка как задать, что комментарий...вот код:

  pattern = "['|REM][\"[^]\"[с]]/[.]*";
            foreach (Match match in Regex.Matches(input, pattern, RegexOptions.IgnoreCase))
            {
                tmp = new MToken();
                tmp.text = match.Value; tmp.LexClass = "Com"; tmp.pos = match.Index; tmp.Spec = "Comment"; tmp.len = match.Length;
                list.Add(tmp);
                input = input.Remove(tmp.pos, tmp.len);
                string str = new String(' ', tmp.len);
                input = input.Insert(tmp.pos, str);
            }

т.е первая строчка, надо правильно описать, что идет ' или REM, далее все что угодно до конца строки.


Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)