Разбор простого выражения - PullRequest
1 голос
/ 19 апреля 2020

Я пытаюсь создать синтаксический анализатор для арифметического c выражения, используя ya cc. Я также включил в него некоторые действия semanti c. Но всякий раз, когда я запускаю код, он показывает ошибку сегментации (дамп памяти). Пожалуйста помоги. Это мой файл cc.

%{
#include <stdio.h>
#include <stdlib.h>
#include<string.h>

int yylex();
void yyerror(const char *s);
int temp[100];
char var[2]="t0";
char label[2]="L1";


%}

%union 
{
    struct attributes
    {
        char code[100];
        char addr[100];
        char op[2];

    }type_id;
        char ch;
}
%start L
%token ID NUM WHILE OR AND NOT True False Do end GE LE EE NE UMINUS
%right '='
%left AND OR
%left '<' '>' LE GE NE
%left '+''-'
%left '*''/'
%right UMINUS
%left '!' 
%type<type_id>L
%type<type_id>E 
%type<ch>ID 
%type<ch>NUM 




%%



%%

#include "lex.yy.c"

int main()
{
   printf("Enter the exp: ");
   yyparse();
}

Это мой файл Lex.

alpha [A-Za-z]
digit [0-9]
%%
[ \t\n]  
{digit}+    return NUM;
{alpha}({alpha}|{digit})*    return ID;
.    return yytext[0];
%%

Когда я компилирую свой файл, я получаю следующее:

rome@rome-VirtualBox:~/Desktop/CompDesin$ gcc y.tab.c -ll -ly
test.y: In function ‘yyparse’:
test.y:48:31: warning: passing argument 1 of ‘strcat’ from incompatible pointer type [-Wincompatible-pointer-types]
                        strcat(temp,$3.code);
                               ^~~~
In file included from test.y:4:0:
/usr/include/string.h:129:14: note: expected ‘char * restrict’ but argument is of type ‘int *’
 extern char *strcat (char *__restrict __dest, const char *__restrict __src)
              ^~~~~~
test.y:49:31: warning: passing argument 1 of ‘strcat’ from incompatible pointer type [-Wincompatible-pointer-types]
                        strcat(temp,"\n");
                               ^~~~
In file included from test.y:4:0:
/usr/include/string.h:129:14: note: expected ‘char * restrict’ but argument is of type ‘int *’
 extern char *strcat (char *__restrict __dest, const char *__restrict __src)
              ^~~~~~
test.y:50:31: warning: passing argument 1 of ‘strcat’ from incompatible pointer type [-Wincompatible-pointer-types]
                        strcat(temp,$1);
                               ^~~~
In file included from test.y:4:0:
/usr/include/string.h:129:14: note: expected ‘char * restrict’ but argument is of type ‘int *’
 extern char *strcat (char *__restrict __dest, const char *__restrict __src)
              ^~~~~~
test.y:50:36: warning: passing argument 2 of ‘strcat’ makes pointer from integer without a cast [-Wint-conversion]
                        strcat(temp,$1);
                                    ^
In file included from test.y:4:0:
/usr/include/string.h:129:14: note: expected ‘const char * restrict’ but argument is of type ‘char’
 extern char *strcat (char *__restrict __dest, const char *__restrict __src)
              ^~~~~~
test.y:51:31: warning: passing argument 1 of ‘strcat’ from incompatible pointer type [-Wincompatible-pointer-types]
                        strcat(temp,"=");
                               ^~~~
In file included from test.y:4:0:
/usr/include/string.h:129:14: note: expected ‘char * restrict’ but argument is of type ‘int *’
 extern char *strcat (char *__restrict __dest, const char *__restrict __src)
              ^~~~~~
test.y:52:31: warning: passing argument 1 of ‘strcat’ from incompatible pointer type [-Wincompatible-pointer-types]
                        strcat(temp,$3.addr);
                               ^~~~
In file included from test.y:4:0:
/usr/include/string.h:129:14: note: expected ‘char * restrict’ but argument is of type ‘int *’
 extern char *strcat (char *__restrict __dest, const char *__restrict __src)
              ^~~~~~
test.y:53:52: warning: passing argument 2 of ‘strcpy’ from incompatible pointer type [-Wincompatible-pointer-types]
                        strcpy($$.code,temp);
                                                    ^   
In file included from test.y:4:0:
/usr/include/string.h:121:14: note: expected ‘const char * restrict’ but argument is of type ‘int *’
 extern char *strcpy (char *__restrict __dest, const char *__restrict __src)
              ^~~~~~
test.y:60:32: warning: passing argument 1 of ‘strcat’ from incompatible pointer type [-Wincompatible-pointer-types]
                         strcat(temp,$1.code);
                                ^~~~
In file included from test.y:4:0:
/usr/include/string.h:129:14: note: expected ‘char * restrict’ but argument is of type ‘int *’
 extern char *strcat (char *__restrict __dest, const char *__restrict __src)
              ^~~~~~
test.y:61:32: warning: passing argument 1 of ‘strcat’ from incompatible pointer type [-Wincompatible-pointer-types]
                         strcat(temp,"\n");
                                ^~~~
In file included from test.y:4:0:
/usr/include/string.h:129:14: note: expected ‘char * restrict’ but argument is of type ‘int *’
 extern char *strcat (char *__restrict __dest, const char *__restrict __src)
              ^~~~~~
test.y:62:32: warning: passing argument 1 of ‘strcat’ from incompatible pointer type [-Wincompatible-pointer-types]
                         strcat(temp,$3.code);
                                ^~~~
In file included from test.y:4:0:
/usr/include/string.h:129:14: note: expected ‘char * restrict’ but argument is of type ‘int *’
 extern char *strcat (char *__restrict __dest, const char *__restrict __src)
              ^~~~~~
test.y:63:32: warning: passing argument 1 of ‘strcat’ from incompatible pointer type [-Wincompatible-pointer-types]
                         strcat(temp,"\n");
                                ^~~~
In file included from test.y:4:0:
/usr/include/string.h:129:14: note: expected ‘char * restrict’ but argument is of type ‘int *’
 extern char *strcat (char *__restrict __dest, const char *__restrict __src)
              ^~~~~~
test.y:64:32: warning: passing argument 1 of ‘strcat’ from incompatible pointer type [-Wincompatible-pointer-types]
                         strcat(temp,$$.addr);
                                ^~~~
In file included from test.y:4:0:
/usr/include/string.h:129:14: note: expected ‘char * restrict’ but argument is of type ‘int *’
 extern char *strcat (char *__restrict __dest, const char *__restrict __src)
              ^~~~~~
test.y:65:32: warning: passing argument 1 of ‘strcat’ from incompatible pointer type [-Wincompatible-pointer-types]
                         strcat(temp,"=");
                                ^~~~
In file included from test.y:4:0:
/usr/include/string.h:129:14: note: expected ‘char * restrict’ but argument is of type ‘int *’
 extern char *strcat (char *__restrict __dest, const char *__restrict __src)
              ^~~~~~
test.y:66:32: warning: passing argument 1 of ‘strcat’ from incompatible pointer type [-Wincompatible-pointer-types]
                         strcat(temp,$1.addr);
                                ^~~~
In file included from test.y:4:0:
/usr/include/string.h:129:14: note: expected ‘char * restrict’ but argument is of type ‘int *’
 extern char *strcat (char *__restrict __dest, const char *__restrict __src)
              ^~~~~~
test.y:67:32: warning: passing argument 1 of ‘strcat’ from incompatible pointer type [-Wincompatible-pointer-types]
                         strcat(temp,"+");
                                ^~~~
In file included from test.y:4:0:
/usr/include/string.h:129:14: note: expected ‘char * restrict’ but argument is of type ‘int *’
 extern char *strcat (char *__restrict __dest, const char *__restrict __src)
              ^~~~~~
test.y:68:32: warning: passing argument 1 of ‘strcat’ from incompatible pointer type [-Wincompatible-pointer-types]
                         strcat(temp,$3.addr);
                                ^~~~
In file included from test.y:4:0:
/usr/include/string.h:129:14: note: expected ‘char * restrict’ but argument is of type ‘int *’
 extern char *strcat (char *__restrict __dest, const char *__restrict __src)
              ^~~~~~
test.y:69:53: warning: passing argument 2 of ‘strcpy’ from incompatible pointer type [-Wincompatible-pointer-types]
                         strcpy($$.code,temp);
                                                     ^   
In file included from test.y:4:0:
/usr/include/string.h:121:14: note: expected ‘const char * restrict’ but argument is of type ‘int *’
 extern char *strcpy (char *__restrict __dest, const char *__restrict __src)
              ^~~~~~
test.y:74:53: warning: passing argument 2 of ‘strcpy’ makes pointer from integer without a cast [-Wint-conversion]
                         strcpy($$.addr,$1);
                                                     ^
In file included from test.y:4:0:
/usr/include/string.h:121:14: note: expected ‘const char * restrict’ but argument is of type ‘char’
 extern char *strcpy (char *__restrict __dest, const char *__restrict __src)
              ^~~~~~
test.y:78:53: warning: passing argument 2 of ‘strcpy’ makes pointer from integer without a cast [-Wint-conversion]
                         strcpy($$.addr,$1);
                                                     ^
In file included from test.y:4:0:
/usr/include/string.h:121:14: note: expected ‘const char * restrict’ but argument is of type ‘char’
 extern char *strcpy (char *__restrict __dest, const char *__restrict __src)
              ^~~~~~
rome@rome-VirtualBox:~/Desktop/CompDesin$ gcc y.tab.c -ll -ly
test.y: In function ‘yyparse’:
test.y:48:31: warning: passing argument 1 of ‘strcat’ from incompatible pointer type [-Wincompatible-pointer-types]
                        strcat(temp,$3.code);
                               ^~~~
In file included from test.y:4:0:
/usr/include/string.h:129:14: note: expected ‘char * restrict’ but argument is of type ‘int *’
 extern char *strcat (char *__restrict __dest, const char *__restrict __src)
              ^~~~~~
test.y:49:31: warning: passing argument 1 of ‘strcat’ from incompatible pointer type [-Wincompatible-pointer-types]
                        strcat(temp,"\n");
                               ^~~~
In file included from test.y:4:0:
/usr/include/string.h:129:14: note: expected ‘char * restrict’ but argument is of type ‘int *’
 extern char *strcat (char *__restrict __dest, const char *__restrict __src)
              ^~~~~~
test.y:50:31: warning: passing argument 1 of ‘strcat’ from incompatible pointer type [-Wincompatible-pointer-types]
                        strcat(temp,$1);
                               ^~~~
In file included from test.y:4:0:
/usr/include/string.h:129:14: note: expected ‘char * restrict’ but argument is of type ‘int *’
 extern char *strcat (char *__restrict __dest, const char *__restrict __src)
              ^~~~~~
test.y:50:36: warning: passing argument 2 of ‘strcat’ makes pointer from integer without a cast [-Wint-conversion]
                        strcat(temp,$1);
                                    ^
In file included from test.y:4:0:
/usr/include/string.h:129:14: note: expected ‘const char * restrict’ but argument is of type ‘char’
 extern char *strcat (char *__restrict __dest, const char *__restrict __src)
              ^~~~~~
test.y:51:31: warning: passing argument 1 of ‘strcat’ from incompatible pointer type [-Wincompatible-pointer-types]
                        strcat(temp,"=");
                               ^~~~
In file included from test.y:4:0:
/usr/include/string.h:129:14: note: expected ‘char * restrict’ but argument is of type ‘int *’
 extern char *strcat (char *__restrict __dest, const char *__restrict __src)
              ^~~~~~
test.y:52:31: warning: passing argument 1 of ‘strcat’ from incompatible pointer type [-Wincompatible-pointer-types]
                        strcat(temp,$3.addr);
                               ^~~~
In file included from test.y:4:0:
/usr/include/string.h:129:14: note: expected ‘char * restrict’ but argument is of type ‘int *’
 extern char *strcat (char *__restrict __dest, const char *__restrict __src)
              ^~~~~~
test.y:53:52: warning: passing argument 2 of ‘strcpy’ from incompatible pointer type [-Wincompatible-pointer-types]
                        strcpy($$.code,temp);
                                                    ^   
In file included from test.y:4:0:
/usr/include/string.h:121:14: note: expected ‘const char * restrict’ but argument is of type ‘int *’
 extern char *strcpy (char *__restrict __dest, const char *__restrict __src)
              ^~~~~~
test.y:60:32: warning: passing argument 1 of ‘strcat’ from incompatible pointer type [-Wincompatible-pointer-types]
                         strcat(temp,$1.code);
                                ^~~~
In file included from test.y:4:0:
/usr/include/string.h:129:14: note: expected ‘char * restrict’ but argument is of type ‘int *’
 extern char *strcat (char *__restrict __dest, const char *__restrict __src)
              ^~~~~~
test.y:61:32: warning: passing argument 1 of ‘strcat’ from incompatible pointer type [-Wincompatible-pointer-types]
                         strcat(temp,"\n");
                                ^~~~
In file included from test.y:4:0:
/usr/include/string.h:129:14: note: expected ‘char * restrict’ but argument is of type ‘int *’
 extern char *strcat (char *__restrict __dest, const char *__restrict __src)
              ^~~~~~
test.y:62:32: warning: passing argument 1 of ‘strcat’ from incompatible pointer type [-Wincompatible-pointer-types]
                         strcat(temp,$3.code);
                                ^~~~
In file included from test.y:4:0:
/usr/include/string.h:129:14: note: expected ‘char * restrict’ but argument is of type ‘int *’
 extern char *strcat (char *__restrict __dest, const char *__restrict __src)
              ^~~~~~
test.y:63:32: warning: passing argument 1 of ‘strcat’ from incompatible pointer type [-Wincompatible-pointer-types]
                         strcat(temp,"\n");
                                ^~~~
In file included from test.y:4:0:
/usr/include/string.h:129:14: note: expected ‘char * restrict’ but argument is of type ‘int *’
 extern char *strcat (char *__restrict __dest, const char *__restrict __src)
              ^~~~~~
test.y:64:32: warning: passing argument 1 of ‘strcat’ from incompatible pointer type [-Wincompatible-pointer-types]
                         strcat(temp,$$.addr);
                                ^~~~
In file included from test.y:4:0:
/usr/include/string.h:129:14: note: expected ‘char * restrict’ but argument is of type ‘int *’
 extern char *strcat (char *__restrict __dest, const char *__restrict __src)
              ^~~~~~
test.y:65:32: warning: passing argument 1 of ‘strcat’ from incompatible pointer type [-Wincompatible-pointer-types]
                         strcat(temp,"=");
                                ^~~~
In file included from test.y:4:0:
/usr/include/string.h:129:14: note: expected ‘char * restrict’ but argument is of type ‘int *’
 extern char *strcat (char *__restrict __dest, const char *__restrict __src)
              ^~~~~~
test.y:66:32: warning: passing argument 1 of ‘strcat’ from incompatible pointer type [-Wincompatible-pointer-types]
                         strcat(temp,$1.addr);
                                ^~~~
In file included from test.y:4:0:
/usr/include/string.h:129:14: note: expected ‘char * restrict’ but argument is of type ‘int *’
 extern char *strcat (char *__restrict __dest, const char *__restrict __src)
              ^~~~~~
test.y:67:32: warning: passing argument 1 of ‘strcat’ from incompatible pointer type [-Wincompatible-pointer-types]
                         strcat(temp,"+");
                                ^~~~
In file included from test.y:4:0:
/usr/include/string.h:129:14: note: expected ‘char * restrict’ but argument is of type ‘int *’
 extern char *strcat (char *__restrict __dest, const char *__restrict __src)
              ^~~~~~
test.y:68:32: warning: passing argument 1 of ‘strcat’ from incompatible pointer type [-Wincompatible-pointer-types]
                         strcat(temp,$3.addr);
                                ^~~~
In file included from test.y:4:0:
/usr/include/string.h:129:14: note: expected ‘char * restrict’ but argument is of type ‘int *’
 extern char *strcat (char *__restrict __dest, const char *__restrict __src)
              ^~~~~~
test.y:69:53: warning: passing argument 2 of ‘strcpy’ from incompatible pointer type [-Wincompatible-pointer-types]
                         strcpy($$.code,temp);
                                                     ^   
In file included from test.y:4:0:
/usr/include/string.h:121:14: note: expected ‘const char * restrict’ but argument is of type ‘int *’
 extern char *strcpy (char *__restrict __dest, const char *__restrict __src)
              ^~~~~~
test.y:74:53: warning: passing argument 2 of ‘strcpy’ makes pointer from integer without a cast [-Wint-conversion]
                         strcpy($$.addr,$1);
                                                     ^
In file included from test.y:4:0:
/usr/include/string.h:121:14: note: expected ‘const char * restrict’ but argument is of type ‘char’
 extern char *strcpy (char *__restrict __dest, const char *__restrict __src)
              ^~~~~~
test.y:78:53: warning: passing argument 2 of ‘strcpy’ makes pointer from integer without a cast [-Wint-conversion]
                         strcpy($$.addr,$1);
                                                     ^
In file included from test.y:4:0:
/usr/include/string.h:121:14: note: expected ‘const char * restrict’ but argument is of type ‘char’
 extern char *strcpy (char *__restrict __dest, const char *__restrict __src)
              ^~~~~~

И когда я запускаю свой файл, я получаю эту ошибку:

rome@rome-VirtualBox:~/Desktop/CompDesin$ ./a.out
Enter the exp: a=b+c
Segmentation fault (core dumped)

1 Ответ

2 голосов
/ 19 апреля 2020

Есть несколько проблем:

Два примечания:

  • имейте в виду, что строки в C заканчиваются на Байт NUL и, следовательно, массивы символов должны иметь соответствующие размеры

  • , для некоторых из них компилятор предупреждает вас, рекомендуется обратить внимание на предупреждения компилятора

Давайте go быстро преодолеем различные проблемы:

  • Как правильно заметили Пол R и Бруно, temp должен быть массивом char, а размеры массивов var и label слишком малый

  • , затем он все еще падает, потому что ID и NUM

определены как

%type<ch>ID 
%type<ch>NUM 

и ch :

char ch;

в операторе% union.

Сбои происходят, потому что вы определяете strcat(temp,$1); в строке 50. $ 1 представляет один символ, но ваш код пытается интерпретировать это как NUL-оканчивающаяся строка (указатель на char *). У вас есть похожие случаи в строках 74 и 78 с strcpy($$.addr,$1);. Как упоминалось ранее, компилятор предупреждает вас об этом. Это вызывает неопределенное поведение, которое в вашем случае проявляется в ошибке сегментации.

Вы можете исправить это, например, на strncat(temp,&$1,1);, чтобы использовать только один символ, но в комментариях вы пишете, что количество копируемых символов будет отличаться и будет зависеть от ввода.

Поэтому измените определение, возможно, в% union, на что-то вроде:

char strval[100];

Затем адаптируйте:

%type<strval>ID
%type<strval>NUM

Установите значения в сканере

Теперь он больше не будет обрабатывать sh, но он не будет работать должным образом, так как значения не установлены в сканере. Там определяется только тип (ID или NUM), но соответствующее значение не задано.

Там оно должно выглядеть следующим образом:

{digit}+                     {
                                strcpy(yylval.strval, yytext);
                                return NUM;
                             }
{alpha}({alpha}|{digit})*    {
                                strcpy(yylval.strval, yytext);
                                return ID;
                             }

Сканер

В настоящее время вы включаете файл "lex.yy. c" в файл .y, например, так:

#include "lex.yy.c"

Я бы предпочел сделать это наоборот. Удалите его оттуда и вместо этого включите сгенерированный ya cc "y.tab.h" в файл .l. Таким образом, начало файла .l может выглядеть так:

%{
    #include "y.tab.h"
%}
alpha [A-Za-z]
...

Команды для сборки будут (могут немного отличаться на вашей платформе):

flex scanner.l
yacc -d grammar.y
cc -Wall -Wextra y.tab.c lex.yy.c -ll

Наконец, ввод, например

a=bb+c+4711

, будет производить вывод, например:

t0=bb+c
t1=t0+4711

Дальнейшие возможные улучшения

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

...