Бизон семантическое значение строки, принимает все, что рядом со строкой, также в нем - PullRequest
0 голосов
/ 02 декабря 2018

Чтобы объявить переменную из нескольких символов, я решил использовать структуру, где будет поле указателя символов и поле целочисленного значения.Мой файл "testy.l" содержит регулярное выражение для переменных как [ab] *.Мой файл "testy.y" правильно принимает значения переменных из идентификатора грамматики (который используется для объявления переменных).Но когда в части оператора - я пытаюсь присвоить значение моей переменной, $ 1 берет весь оператор как строку и сохраняет его как переменную.Я не понимаю, почему и как мне это решить.

Мои файлы здесь:

testy.l

%{
    #include <stdio.h>
    #include <string.h>
    #include "test.tab.h"
%}

%%

"int"   { return INT;   }
"float" { return FLOAT; }
"char"  { return CHAR;  }

";"     { return EOS; }
","     { return CM;  }
"="     { return EQ;  }

"("     { return LP; }
")"     { return RP; }
"{"     { return LB; }
"}"     { return RB; }
"+"     { return ADD; }
"-"     { return SUB; }
"*"     { return MUL; }
"/"     { return DIV; }
">"     { return GT; }
"<"     { return LT; }

"void mainf"    { return MAIN; }
"out->"         { return PRINT; }

[0-9]+  {
            yylval.IN = atoi(yytext);
            return NUM;
        }

[a-z]+  {
            yylval.ch = yytext;
            return  VAR;
        }

[a-zA-Z0-9_!&,.]+    { yylval.ch = yytext; return LINE; }

[\t\n]* ;

%%

int main()
{
    yyin = freopen("a.txt","r",stdin);
    yyout = freopen("out.txt","w",stdout);
    yyparse();
}

testy.y

%{
    #include<stdio.h>
    #include<string.h>
    int sym[26],store[26];
    int cnt=0;
    int yylex (void);
    struct node {
        char *name;
        int val;
    } var[100];

    int setval(int val, char *varname, int n) {
        int i=0;
        for(i=0; i<n; i++){
            if(strcmp(varname, var[i].name)==0){
                printf("\nsetval loop: strcmp= %d, val= %d", strcmp(varname, var[i].name), val);
                var[i].val = val;
                return;
            }
        }
        printf("\nVariable %s not declared!", varname);
    }

    int declare(int i, char *varname) {
        if(checkRedeclaratn(i, varname)) {
            printf("\nVariable %s re-declared!", varname);
        }
        var[i].name = varname;
        printf("\n%s declared at index %d", var[i].name, i);
    }

    int checkRedeclaratn(int n, char *varname) {
        int i=0;
        for(i=0; i<n; i++){
            if(strcmp(varname, var[i].name)==0)
                return 1;
        }
        return 0;
    }

    int getval(int n, char *varname) {
        int i=0;
        for(i=0; i<n; i++){
            if(strcmp(varname, var[i].name)==0)
                return var[i].val;
        }printf("\nVariable %s not declared in getval!", varname);
    }

%}

%union {
    char *ch;
    int IN;  
}

%token<ch>LINE
%token<ch>VAR
%token<IN>NUM

%token INT FLOAT CHAR EOS CM EQ LP RP LB RB ADD SUB MUL DIV GT LT MAIN PRINT 

%%
/*need changes here*/
program: MAIN LP RP LB cstatement RB { printf("\nsuccessful compilation\n"); }
     ;

cstatement: /* empty */
    | statement cstatement
    | cdeclaration cstatement
    | iostmt cstatement
    ;

cdeclaration: TYPE ID EOS { printf("\nvalid declaration\n"); }
            ;

statement: EOS
    | VAR EQ NUM EOS { printf("\nstatement VAR %s",$1); setval($3, $1, cnt); }
    ;

TYPE : INT
     | FLOAT
     | CHAR
     ;

ID  : ID CM VAR { declare(cnt,$3);cnt++; }
    | VAR   { declare(cnt,$1);cnt++; }
     ;

iostmt: PRINT VAR EOS { printf("\n%s = %d", $2, getval(cnt,$2)); }
    | PRINT LINE EOS { printf("\n%s\n", $2); }
    ;

%%

int yywrap()
{
    return 1;
}

yyerror(char *s){
    printf( "%s\n", s);
}
/*if(store[$3] == 1) printf("\nvariable %c Redeclared\n",$3+'a');
                                        else store[$3]=1; /*if(store[$1] == 1) printf("\nvariable %c Redeclared\n",$1+'a');
                                        else store[$1]=1;*/ 
//if(store[$1] != 1) printf("\nvariable %c not declared\n",$1+'a'); 
//var.name = $1; var.val= $3; printf("\nValue of variable %s: %d",var.name, $3);

a.txt

void mainf() {
    int aaa , bbb , ccc ;
    aaa = 10;
    bbb = 20;
    out-> argvWaa ;
}

1 Ответ

0 голосов
/ 02 декабря 2018

yytext всегда указывает на один и тот же буфер, который будет изменен Flex после запроса следующего токена.Если вам нужно использовать значение yytext в семантическом значении токена, вам необходимо скопировать его.

Вы можете использовать strdup:

yylval.ch = strdup(yytext);

Обратите внимание, что strdup выделяет память, используя malloc, поэтому вам нужно будет free, как только вы закончите, используя ее.

...