Главная страница
Навигация по странице:

  • Лабораторная работа № 2

  • МУ_ЛР_ЛиПОАС. Методические указания по выполнению лабораторных работ по дисциплине (модулю) Лингвистическое и программное обеспечение автоматизированных систем


    Скачать 2.76 Mb.
    НазваниеМетодические указания по выполнению лабораторных работ по дисциплине (модулю) Лингвистическое и программное обеспечение автоматизированных систем
    Дата12.04.2023
    Размер2.76 Mb.
    Формат файлаdoc
    Имя файлаМУ_ЛР_ЛиПОАС.doc
    ТипМетодические указания
    #1057976
    страница5 из 32
    1   2   3   4   5   6   7   8   9   ...   32

    4. Ход работы (порядок выполнения работы)



    1) Ознакомится теоретической справкой.

    2) Описать грамматики тремя различными способами.

    3) Оформить отчет.

    4) Защитить работу преподавателю.

    5. Содержание отчета



    1) Титульный лист

    2) Задание

    3) Примеры допустимых и недопустимых выражений в описываемой грамматике.

    4) Описание грамматики в форме Бэкуса-Наура.

    5) Описание грамматики в расширенной форме Бэкуса-Наура.

    6) Описание грамматики в графической форме.

    7) Выводы по работе

    8) Список используемой литературы


    Лабораторная работа № 2

    Разработка лексического и синтаксического анализаторов

    1.Цель и задачи работы


    Целью работы являются выработать у студентов навык построения лексических и синтаксических анализаторов.

    Задачами работы являются

    1. Изучение методов разработки лексических и синтаксических анализаторов.

    2. Разработка лексического анализатора грамматики в соответствии с индивидуальным заданием.

    3. Разработка синтаксического анализатора грамматики в соответствии с индивидуальным заданием.

    2.Общие положения (теоретические сведения)




    2.1. Разработка лексического анализатора



    При лексическом анализе текст выражения на языке L разделяется на отдельные лексемы. Лексема – это один терминальный или нетерминальный символ. В рассматриваемой грамматике лексический анализатор (ЛА) должен выделять лексемы следующих типов: идентификатор; число; "+"; "-", т.е. лексемы, непосредственно входящие в описание грамматики языка L. Результатом работы является динамический массив лексем.

    Константа FINISH соответствует концу анализируемого выражения и указывает на то, что за ней других лексем нет.

    Такая грамматика имеет вид:

    <цифра> ( 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 )

    <число>  <цифра>{<цифра>}

     ( A | B | C | D … Z | _ )

     ( A | B | C | D … Z | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | _ )

    <идентификатор>  {}

    <слагаемое>  (<идентификатор>|<число>)

    <операция>  ( + | - )

     < слагаемое>[{<операция><слагаемое>}]
    Опишем тип Tresult элемента выходного динамического массива:

    public struct Tresult

    {

    public string lexeme;

    public long value;

    public string name;

    public ushort position; // целое число от 0 до 65535

    }

    Здесь в поле value хранится численное значение лексемы типа NUMBER, в поле name – имя лексемы-идентификатора типа ID, в поле position – позиция лексемы во входной строке (для индикации).

    Создадим теперь класс "Лексический анализатор":

    public partial class TLexicalAnalyzer

    {

    public static string[] TLexemeType = { "NUMBER", "ID", "PLUS", "MINUS", "FINISH" };

    private string Ferr;

    private Tresult[] Flex;

    public TLexicalAnalyzer() //Конструктор

    { Ferr = ""; Flex = new Tresult[0]; }

    public String Error { get { return Ferr; } }

    public Tresult[] Lexem { get { return Flex; } }

    string s = "";

    ushort i;

    Здесь введено свойство Error (только для чтения) для хранения в нём сообщений об ошибках, которые могут быть обнаружены в процессе анализа. В свойстве Lexem хранится собственно формируемый список лексем. Основным методом данного класса является функция Run, которая получает на вход выражение на языке L, а возвращает массив лексем.

    А теперь самое интересное.… Для упрощения кода основная процедура Run разбита на несколько отдельных процедур - AddLex, добавляющая лексему в результирующий массив. Процедуры ReadID и ReadNumber считывают идентификаторы и числа соответственно. Для преобразования текса в число в процедуре ReadNumber применена стандартная функция Convert.ToString().

    public void AddLex(byte LexemeType, long v, string n)

    {

    Array.Resize(ref Flex, Flex.Length + 1);

    Flex[Flex.Length - 1].lexeme = TLexemeType[LexemeType - 1];

    Flex[Flex.Length - 1].value = v;

    Flex[Flex.Length - 1].name = n;

    Flex[Flex.Length - 1].position = i;

    }

    public void ReadID()

    {

    string N = "";

    do

    {

    N += s[i];

    i++;

    }

    while ((i < s.Length) && (char.IsLetterOrDigit(s, i) || (s[i] == '_')));

    AddLex(2, 0, N);

    i--;

    }
    public void ReadNumber()

    {

    string N = "";

    do

    {

    N += s[i];

    i++;

    }

    while ((i < s.Length) && (char.IsDigit(s, i)));

    AddLex(1, Convert.ToInt64(N), N);

    i--;

    }
    public void Run(string Data)

    {

    s = Data;

    Array.Resize(ref Flex, 0);

    Ferr = "";

    for (i = 0; i <= s.Length – 1; i++)

    {

    if (s[i] == '+') AddLex(3, 0, "+");

    else

    if (s[i] == '-') AddLex(4, 0, "-");

    else

    if ((char.IsLetter(s, i)) || (s[i] == '_')) ReadID();

    else

    if (char.IsDigit(s, i)) ReadNumber();

    else

    {

    Ferr = "Недопустимый символ в коде!";

    break;

    }

    }

    AddLex(5, 0, "");

    }

    1   2   3   4   5   6   7   8   9   ...   32


    написать администратору сайта