Синтаксическая проверка программ на C, таких как непарные круглые, квадратные и фигурные скобки - C (СИ)

Узнай цену своей работы

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

Задание:

Упражнение 1.24.

Напишите программу для выполнения примитивной синтаксической проверки программ на C, таких как непарные круглые, квадратные и фигурные скобки. Не забудьте об одинарных и двойных кавычках, управляющих символах и комментариях. (Это сложная программа, если пытаться реализовать самый общий случай.) Нужно ли реализовывать проверку для

#define

и если да, то насколько это будет сложно? Пример:
#include <stdio.h>
#define M (
#define N )
int main M void N
{
    printf("Test\n" N;
}

Решение задачи: «Синтаксическая проверка программ на C, таких как непарные круглые, квадратные и фигурные скобки»

textual
Листинг программы
#include <stdio.h>
#include <string.h>
#define MAXSTACK 1000
 
char pop(char stack[], int size);
char push(char stack[], char elem, int size);
char peek(char stack[], int size);
int is_com(char s);
int is_proc(char s);
 
int main(void)
{
    char stack[MAXSTACK] = {0};
 
    int c, last=0;
    int ec, com, error, tri;
    com = ec = error = tri = 0;
    while(!error && (c = getchar()) != EOF)
    {
 
        // trigraphs
        if(c == '?' && tri < 2) ++tri;
        else if(tri == 2)
        {
            switch(c)
            {
                case '?': break;
                case '<': c = '{'; break;
                case '>': c = '}'; break;
                case '(': c = '['; break;
                case ')': c = ']'; break;
                case '/': c = '\\'; break;
                default: tri = 0; break;
            }
        }
        else
            tri = 0;
 
        if(c == '\\')
        {
            if(ec)
                ec = 0;
            else
                ec = 2;
        }
 
        // check brackets
        if(is_proc(last))
        {
 
            // ( [ {  } ] )
            switch(c)
            {
                case '(': push(stack, '(', MAXSTACK); break;
                case '[': push(stack, '[', MAXSTACK); break;
                case '{': push(stack, '{', MAXSTACK); break;
 
                case ')':
                    if(pop(stack, MAXSTACK) != '(')
                        error = 1;
                    break;
                case ']':
                    if(pop(stack, MAXSTACK) != '[')
                        error = 1;
                    break;
                case '}':
                    if(pop(stack, MAXSTACK) != '{')
                        error = 1;
                    break;
            }
        }
 
        // check quotes
        if(!is_com(last))
        {
            switch(c)
            {
                case '\'':
                    if(is_proc(last))
                        push(stack, '\'', MAXSTACK);
                    else if(!ec && last == '\'')
                        pop(stack, MAXSTACK);
                    break;
                case '"':
                    if(is_proc(last))
                        push(stack, '"', MAXSTACK);
                    else  if(!ec && last == '"')
                        pop(stack, MAXSTACK);
            }
        }
 
        // Comment open
        if(!is_com(last))
            switch(c)
            {
                case '/':
                    if(com > 0 && !ec)
                    {
                        push(stack, 'l', MAXSTACK);
                        com = 0;
                    }
                    else
                        com = 2;
                    break;
                case '*':
                    if(com > 0 && !ec)
                        push(stack, 'c', MAXSTACK);
                    com = ec = 0;
                    break;
            }
 
        // Comment close
        if(is_com(last))
            switch(c)
            {
                case '*':
                    if(last == 'c')
                        com = -2;
                    break;
                case '/':
                    if(com < 0 && !ec)
                    {
                        pop(stack, MAXSTACK);
                        com = 0;
                    }
                    break;
                case '\n':
                    if(last == 'l' && !ec)
                    {
                        pop(stack, MAXSTACK);
                        com = 0;
                    }
                    break;
            }
 
        if(com && !ec && c!='\n'  && !tri)
            com += com<0? 1: -1;
 
        if(ec==1 && c != '\n')
            com = ec = 0;
 
        else if(ec)
            --ec;
 
        last=peek(stack, MAXSTACK);
    }
 
    if(error || peek(stack, MAXSTACK) != -1)
        printf("Error\n");
    else
        printf("Valid\n");
 
    return 0;
}
 
char pop(char stack[], int size)
{
    int i, c;
    for(i = 0; i < size && stack[i]; ++i);
    if(i > 0)
    {
        c = stack[--i];
        stack[i] = '\0';
        return c;
    }
    return -1;
}
 
char push(char stack[], char elem, int size)
{
    int i, c;
    for(i = 0; i < size && stack[i]; ++i);
    if(i < size)
        return c = stack[i] = elem;
    return -1;
}
 
char peek(char stack[], int size)
{
    int i;
    for(i = 0; i < size && stack[i]; ++i);
    if(i > 0)
        return stack[--i];
    return -1;
}
 
 
int is_proc(char s)
{
    if(s == '\'' || s == '"' || is_com(s))
        return 0;
    return 1;
}
 
int is_com(char s)
{
    if(s == 'c' || s == 'l' || s == '\\')
        return 1;
    return 0;
}

Объяснение кода листинга программы

Код проверяет синтаксис программ на C, в частности, парность скобок (круглых, квадратных и фигурных), кавычек (одиночных и двойных) и обратных слешей. Он также обрабатывает триплеры и комментарии. Вот список функций и их описания:

  1. pop(char stack[], int size) - эта функция удаляет и возвращает последний элемент из стека. Если стек пуст, она возвращает -1.
  2. push(char stack[], char elem, int size) - эта функция добавляет элемент в стек. Если стек полон (т.е. достиг максимума размера), она возвращает -1. В противном случае она возвращает 0, что означает успешное добавление элемента.
  3. peek(char stack[], int size) - эта функция возвращает последний элемент в стеке, не удаляя его. Если стек пуст, она возвращает -1.
  4. is_proc(char s) - эта функция возвращает 0, если символ s является открывающей фигурной скобкой, открывающей квадратной скобкой или апострофом. В противном случае она возвращает 1.
  5. is_com(char s) - эта функция возвращает 0, если символ s является закрывающей фигурной скобкой, закрывающей квадратной скобкой или обратным слешем. В противном случае она возвращает 1. Список символов и их значений:
  6. `> - означает, что символ является закрывающей квадратной скобкой.
  7. `> - означает, что символ является закрывающей фигурной скобкой.
  8. `> - означает, что символ является обратным слешем.
  9. `> - означает, что символ является апострофом.
  10. `> - означает, что символ является открывающей квадратной скобкой.
  11. `> - означает, что символ является открывающей фигурной скобкой. Вот список переменных и их описания:
  12. c - текущий символ ввода.
  13. last - последний символ в стеке.
  14. com - счетчик комментариев.
  15. ec - счетчик прямых слешей.
  16. tri - счетчик тройплеров.
  17. stack - стек, используемый для отслеживания синтаксиса.
  18. error - флаг, устанавливаемый в 1, если обнаружена синтаксическая ошибка. Вот список номеров строк и соответствующих действий:
  19. 3 - начало обработки комментариев.
  20. 5 - начало обработки скобок.
  21. 7 - начало обработки кавычек.
  22. 12 - начало обработки обратных слешей.
  23. 16 - начало обработки триплеров.
  24. 18 - начало обработки парных скобок.
  25. 20 - конец обработки парных скобок. Обратите внимание, что некоторые строки могут иметь несколько действий, разделенных запятыми. Каждое действие обрабатывается последовательно.

ИИ поможет Вам:


  • решить любую задачу по программированию
  • объяснить код
  • расставить комментарии в коде
  • и т.д
Попробуйте бесплатно

Оцени полезность:

8   голосов , оценка 4.125 из 5
Похожие ответы