Мне нужно спроектировать оригинальный язык программирования и предоставить для него анализатор 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);
}
Это работает для объявлений любого типа. Я надеюсь, что вы можете помочь мне с моей проблемой. Спасибо !!