Как я могу узнать, была ли переменная уже объявлена ​​с использованием lex / ya cc? - PullRequest
1 голос
/ 06 января 2020

Мне нужно спроектировать оригинальный язык программирования и предоставить для него анализатор syntacti c. Теперь я нахожусь в точке, где я должен проверить, была ли переменная уже объявлена, и если это так, я не смогу объявить ее снова. Как я могу сделать это? С массивом? (Как)

Это то, что я сделал до сих пор.

lex:


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

%}
%option noyywrap
%%

"/*"(.|\n)+"*/" ;
"float"|"char"|"string" {return TYPE;}
"int" {return INTTYPE;}
"for" {return FOR;}
"while" {return WHILE;}
"if" {return IF;}
"else" {return ELSE;}
"bool" {return BOOLTYPE;}
"true"|"false" {return BOOLVALUE;}
"++"|"--" {return INCRDECR;}
"/[^\"]+/" {return STRINGVALUE;}
"scat"|"scmp"|"scpy"|"slen" {return STRINGFUNCTION;}
"protected"|"private"|"public" { return CLASSTYPE;}
"class" {return CLASS;}
"eval" {return EVAL;}
[1-9][0-9]*|0 {yylval = atoi(yytext); return INTVALUE;}
[A-Za-z][A-Za-z0-9]* {yylval = strdup(yytext); return ID;}
"=" {return ASSIGN;}
"<="|"<"|">="|">"|"=="|"!=" {return COMP;}
"begin_prog" {return BGIN;}
"end_prog" {return END;}
[ \t] ;
\n {yylineno++;}
. {return yytext[0];}

я cc :

%{
#include <stdio.h>
extern FILE* yyin;
extern char* yytext;
extern int yylineno;
%}
%token TYPE INTTYPE FOR WHILE IF ELSE BOOLTYPE BOOLVALUE INCRDECR STRINGVALUE STRINGFUNCTION CLASSTYPE CLASS EVAL INTVALUE ID ASSIGN COMP BGIN END 

%start s
%left '.'
%left ','
%left ';'
%left '+' '-'
%left '*' '/' '%'

%%



s: declarations block {printf ("correct input \n ");}
;
declarations : declaration ';'
| declarations declaration ';'
;


declaration : TYPE ID 
|BOOLTYPE ID ASSIGN BOOLVALUE
|INTTYPE ID ASSIGN INTVALUE
|INTTYPE ID
|TYPE ID '(' list_param ')'
|TYPE ID '[' INTVALUE ']'
|INTTYPE ID '(' list_param ')'
|INTTYPE ID '[' INTVALUE ']'
|BOOLTYPE ID 
;


block: BGIN blockinstr END
;

blockinstr: blockinstr listfiw 
| blockinstr classs 
| blockinstr fdeclaration
| listfiw 
| listinstr 
| stringg 
| classs 
| fdeclaration

;

fdeclaration : TYPE EVAL '(' list_paramf ')' '{' listinstr '}' 
| INTTYPE EVAL '(' list_paramf ')' '{' listinstr '}'
| TYPE ID '(' list_param ')' '{' listinstr '}'
| INTTYPE ID '(' list_param ')' '{' listinstr '}'
;

list_param : parameter
| list_param ',' parameter
;

parameter : TYPE ID
| parameterf
;

list_paramf : parameterf
| list_paramf ',' parameterf
; 

parameterf : INTTYPE ID
;

listfiw : iff
|forr
|whilee
;

iff: IF '('  ID COMP INTVALUE ')' '{' listinstr '}'
| IF '(' ID COMP ID ')' '{' listinstr '}'
| IF '(' ID ')' '{' listinstr '}'
| IF '(' ID COMP INTVALUE ')' '{' listinstr '}' ELSE '{' listinstr '}'
| IF '(' ID COMP ID ')' '{' listinstr '}' ELSE '{' listinstr '}'
| IF '(' ID ')' '{' listinstr '}' ELSE '{' listinstr '}'
| IF '(' ID COMP BOOLVALUE ')' '{' listinstr '}'
| IF '(' ID COMP BOOLVALUE ')' '{' listinstr '}' ELSE '{' listinstr '}'
;

forr: FOR '(' ID ASSIGN INTVALUE ';' ID COMP INTVALUE ';' ID INCRDECR ')' '{' listinstr '}' 
| FOR '(' ID ASSIGN INTVALUE ';' ID COMP INTVALUE ';' ID INCRDECR ')' '{' FOR '(' ID ASSIGN INTVALUE ';' ID COMP INTVALUE ';' ID INCRDECR ')' '{' listinstr '}'  '}' 
    ;

whilee: WHILE '(' ID COMP INTVALUE ')' '{' listinstr '}'
| WHILE '(' INTVALUE ')' '{' listinstr '}'
 ;


listinstr : instruction ';'
| listinstr instruction ';'
;

instruction: ID ASSIGN BOOLVALUE
| ID ASSIGN operations
| ID '(' operations ')' 
;

operations: operations '+' operations
| operations '*' operations
|operations '-' operations
|operations '/' operations 
|operations '%' operations
|'(' operations ')'
|ID '[' INTVALUE ']'
|ID '(' operations ')'
|INTVALUE
|ID
;

stringg : stringg STRINGFUNCTION '(' ID ')' ';' 
        | stringg STRINGFUNCTION '(' ID ',' ID ')' ';'
    | STRINGFUNCTION '(' ID ')' ';'
        | STRINGFUNCTION '(' ID ',' ID ')' ';'
        ;

classs: CLASS ID '{' classlists '}'
      ;
classlists: classlist 
| classlists classlist
;
classlist: CLASSTYPE ':' declarations 
;


%%
int yyerror(char * s){
 printf("err: %s line:%d\n",s,yylineno);
}

int main(int argc, char** argv[]){
 yyin=fopen(argv[1],"r");
 yyparse();
 fclose(f);
 fclose(yyin);


} 

Это работает для объявлений любого типа. Я надеюсь, что вы можете помочь мне с моей проблемой. Спасибо !!

...