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

  • Цель работы Научиться создавать синтаксические анализаторы.Задачи работы

  • Листинг программы

  • Отчет по лабораторной работе 5 Выполнил студент группы 220272 Хавренко В. С. Проверил доцент, к т. н. Волошко А. Г


    Скачать 71.94 Kb.
    НазваниеОтчет по лабораторной работе 5 Выполнил студент группы 220272 Хавренко В. С. Проверил доцент, к т. н. Волошко А. Г
    Дата07.12.2022
    Размер71.94 Kb.
    Формат файлаdocx
    Имя файла22LR5.docx
    ТипОтчет
    #833447

    МИНОБРНАУКИ РОССИИ

    Федеральное государственное бюджетное образовательное учреждение

    высшего образования

    "Тульский государственный университет"
    Институт прикладной математики и компьютерных наук
    Кафедра вычислительной техники
    Лингвистическое и программное обеспечение автоматизированных
    систем


    ОТЧЕТ ПО ЛАБОРАТОРНОЙ РАБОТЕ № 5

    Выполнил студент группы 220272

    Хавренко В.С.
    Проверил доцент, к.т.н.

    Волошко А.Г.

    Тула 2021

    Цель работы

    Научиться создавать синтаксические анализаторы.

    Задачи работы

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

    Индивидуальное задание: Описать язык арифметических выражений в префиксной форме с операциями сложения, вычитания, умножения, деления без скобок, с операндами в форме идентификаторов.

    Ход работы

    Синтаксический анализатор производит анализ арифметических выражений в префиксной форме с операциями сложения, вычитания, умножения, деления без скобок, с операндами в форме идентификаторов. Анализатор проверяет правильность написания текста в соответствии с правилом грамматики.

    На рисунках 1-5 представлен результат работы программы.



    Рисунок 1 – Правильный ввод



    Рисунок 2 – Отсутствует знак


    Рисунок 3 – Ошибка нехватки идентификаторов



    Рисунок 4 – Ошибка перебора идентификаторов



    Рисунок 5 – Ошибка разделения

    Листинг программы

    Листинг 1 - program.cs

    using System;
    namespace ConsoleApp1

    {

    public struct Result

    {

    public string lexeme;

    public string name;

    public int position;

    }
    public class LexicalAnalyzer

    {

    public static string[] lexemeType = { "ID", "SIGN", "FINISH", "|_|" };

    private string error;

    private Result[] lexemes;

    string s = "";

    int i;
    public LexicalAnalyzer()

    {

    error = "";

    lexemes = new Result[0];

    }
    public String Error { get { return error; } }

    public Result[] Lexemes { get { return lexemes; } }
    public void AddLexeme(byte LexemeType, string name, int position)

    {

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

    lexemes[lexemes.Length - 1].lexeme = lexemeType[LexemeType - 1];

    lexemes[lexemes.Length - 1].name = name;

    lexemes[lexemes.Length - 1].position = position;

    }

    public void ReadNUM(int start_pos)

    {

    string num = "";

    do

    {

    num += s[i];

    i++;

    }

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

    AddLexeme(1, num, start_pos);

    i--;

    }

    public void Run(string Data)

    {

    s = Data;

    Array.Resize(ref lexemes, 0);

    error = "";

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

    {

    if (s[i] == '+') AddLexeme(2, "+", i);

    else if (s[i] == '-') AddLexeme(2, "-", i);

    else if (s[i] == '*') AddLexeme(2, "*", i);

    else if (s[i] == '/') AddLexeme(2, "/", i);

    else if (s[i] == ' ') Console.Write("");

    //else if (char.IsLetterOrDigit(s, i)) AddLexeme(1, Convert.ToString(s[i]), i);

    else if (char.IsLetterOrDigit(s, i)) ReadNUM(i);

    else

    {

    error = "Error at pos " + i + ": symbol '" + s[i] + "' is unacceptable.";

    break;

    }

    }

    AddLexeme(3, "", i);

    }
    }
    class Program

    {

    static void Main(string[] args)

    {

    string input = Console.ReadLine();

    LexicalAnalyzer lexicalAnalyzer = new LexicalAnalyzer();

    lexicalAnalyzer.Run(input);

    Console.WriteLine("Лексический анализ\n");

    Console.WriteLine("Input: {0}\n", input);

    foreach (var lexeme in lexicalAnalyzer.Lexemes)

    {

    Console.WriteLine("{0} at {1}: {2}", lexeme.lexeme, lexeme.position, lexeme.name);

    }

    if (lexicalAnalyzer.Error != "") Console.WriteLine(lexicalAnalyzer.Error);

    Console.WriteLine("\n");

    Console.WriteLine("Синтаксический анализ\n");

    TSyntaxAnalyzer SyntaxAnalyzer3 = new TSyntaxAnalyzer(lexicalAnalyzer.Lexemes);

    SyntaxAnalyzer3.Parse();

    Console.ReadLine();

    }

    }

    }

    Листинг 2 - класса TSyntaxAnalyzer.cs

    using System;

    namespace ConsoleApp1

    {

    partial class TSyntaxAnalyzer

    {

    public string Ferr; //Сообщение об ошибке

    public string Ferr1; //Сообщение об ошибке

    public string Ferr2; //Сообщение об ошибке

    public ushort FerrPos; //Позиция ошибки во входной строке

    private Result[] Flex; //Входной массив лексем после лексического разбора

    private Int32 Count; //Номер текущей лексемы

    public ushort ErrorPos { get { return FerrPos; } }

    public String Error { get { return Ferr; } }

    public TSyntaxAnalyzer(Result[] Lexems) //Конструктор

    {

    Ferr = "";

    Ferr1 = "";

    Ferr2 = "";

    FerrPos = 0;

    Flex = Lexems;

    Count = 0;

    }

    public int sign = 0;

    public int id = 0;

    public Result GetLex()

    {

    if (Count <= Flex.Length - 1)

    {

    Count++;

    return Flex[Count - 1];

    }

    else

    {

    Result FinishRes;

    FinishRes.lexeme = "FINISH";

    FinishRes.name = "";

    FinishRes.position = 0;

    return FinishRes;

    }

    }
    public virtual void Parse()

    {

    string[] Operation = { "SIGN" }, item = { "ID" }, item2 = { "|_|" };

    Result Curlex = GetLex();

    do

    {

    link1:

    if (Array.IndexOf(Operation, Curlex.lexeme) != -1)

    {

    Curlex = GetLex();

    sign = sign + 1;

    goto link1;

    }

    else

    {

    if (Array.IndexOf(item, Curlex.lexeme) != -1 || Array.IndexOf(item2, Curlex.lexeme) !=- 1)

    {

    if (sign != 0)

    {

    goto link2;

    }

    }

    Ferr = "Синтаксическая ошибка. Знаки спереди!";

    FerrPos = (ushort)Curlex.position;

    Console.WriteLine("{0}, {1}", FerrPos, Ferr);

    Console.ReadLine();

    goto link2;

    }

    link2:

    do

    {

    if (Array.IndexOf(item2, Curlex.lexeme) != -1)

    {

    Curlex = GetLex();

    }

    else

    if (Array.IndexOf(item, Curlex.lexeme) != -1)

    {

    if (sign >= id+1)

    {

    Curlex = GetLex();

    id = id + 1;

    }

    else

    {

    Ferr = "Синтаксическая ошибка. Слишком много идентификаторов!";

    FerrPos = (ushort)Curlex.position;

    Console.WriteLine("{0}, {1}", FerrPos, Ferr);

    Console.ReadLine();

    break;

    }

    }

    else

    if (Array.IndexOf(Operation, Curlex.lexeme) != -1)

    {

    Ferr = "Синтаксическая ошибка. Ожидалось разделение";

    FerrPos = (ushort)Curlex.position;

    Console.WriteLine("{0}, {1}", FerrPos, Ferr);

    Console.ReadLine();

    break;

    }


    }

    while (Curlex.lexeme != "FINISH");

    }

    while (Curlex.lexeme != "FINISH");

    if (sign > id)

    {

    Ferr = "Синтаксическая ошибка. Слишком мало идентификаторов!";

    FerrPos = (ushort)Curlex.position;

    Console.WriteLine("{0}, {1}", FerrPos, Ferr);

    }

    if (sign == id)

    {

    Console.WriteLine("Ошибки не обнаружены");

    }

    Console.ReadLine();

    //Console.WriteLine("OK");

    }
    }

    }


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