Я пытаюсь создать простой C компилятор, используя lex для фазы лексического анализа и ya cc для синтаксического анализа. Я строю таблицу символов в lex и заполняю ее всеми идентификаторами (только имя, номер строки и область действия идентификатора на данный момент), с которыми я столкнулся в лексическом анализе. Сама таблица символов находится в форме связанного списка, а указатель указывает на заголовок связанного списка. Теперь я хочу получить доступ к этой таблице символов в ya cc, чтобы обновить значение и тип данных для каждого идентификатора. Как мне получить доступ к таблице символов в ya cc?
Я определил указатель головы в lex как extern, но это не помогает. Вот полный код для справки -
Lex (ngrammar.l) -
%{
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#define MAX 1000
extern int yylval;
int scope = 0;
int lineno = 1;
int paran = 0;
typedef struct node{
int index;
int scope;
char symbol[MAX];
char lineno[MAX];
char type[MAX];
char value[MAX];
struct node* next;
}node;
extern node* head;
head = NULL;
node* InsertSymbol(node*,int,char*,int,int);
void display(node* head);
node* InsertSymbol(node* head, int scope, char* symbol, int lineno, int paran){
if(paran>0){
scope++;
}
else{;
}
if(head == NULL){
node* temp = (node*)malloc(sizeof(node));
temp->index = 1;
temp->scope = scope;
strcpy(temp->symbol,symbol);
char str[4];
sprintf(str, "%d", lineno);
strcpy(temp->lineno,str);
temp->next = NULL;
head = temp;
}
else{
node* cur= head;
node* prev = NULL;
int present = 0;
while(cur != NULL){
if((cur->scope == scope) && (strcmp(cur->symbol,symbol)==0)){
char str[4];
sprintf(str, ", %d", lineno);
strcat(cur->lineno,str);
present = 1;
}
prev = cur;
cur = cur->next;
}
if(present == 0){
node* temp = (node*)malloc(sizeof(node));
temp->index = (prev->index)+1;
temp->scope = scope;
strcpy(temp->symbol,symbol);
char str[4];
sprintf(str, "%d", lineno);
strcpy(temp->lineno,str);
temp->next = NULL;
prev->next = temp;
}
}
return head;
}
void display(node* head){
node* p = head;
printf("\t\t\t SYMBOL TABLE \t\t\t\n\n");
printf("\t Index \t\t Symbol \t Scope \t\t Line Number \n");
if(p == NULL){
printf("nothing");
return;
}
else{
while(p != NULL){
//printf("enter");
printf("\t %d \t\t %s \t\t %d \t\t %s \n",p->index,p->symbol,p->scope,p->lineno);
p = p->next;
}
}
}
%}
alpha [A-Za-z]
digit [0-9]
und [_]
space [ ]
tab [ ]
line [\n]
acc [^"*/"]
str [^\"]
%%
\/\/(.*)[\n]* {;}
\/\*({acc}*\n)*{acc}*\*\/[\n]* {;}
for {return FOR;}
if {return IF;}
char {return CHAR;}
float {return FLOAT;}
int {return INT;}
continue {return CONTINUE;}
return {return RETURN;}
bool {return BOOL;}
main {return MAIN;}
else {return ELSE;}
printf {return PRINT;}
break {return BREAK;}
TRUE {return BOOLTRUE;}
FALSE {return BOOLFALSE;}
\|\| {return OR;}
\%d|\%c|\%f {return FORMATSPEC;}
\( {return OPENBRACES;paran++;}
\) {return CLOSEBRACES;paran--;}
\{ {return OPENCURLYBRACES;scope++;}
\} {return CLOSECURLYBRACES;scope--;}
[.] {return DOT;}
= {return ASSIGNOP;}
\+\+|\-\- {return UNARYOP;}
\+|\-|\*|\/ {return ARITHOP;}
>|<|>=|<=|!=|== {return RELOP;}
&& {return AND;}
[,] {return COMMA;}
[;] {return SEMICOLON;}
['] {return SINGLEQUOTES;}
["] {return DOUBLEQUOTES;}
["]{str}*["] {return STRING;}
{alpha}({alpha}|{digit}|{und})* {return IDENTIFIER;
head = InsertSymbol(head,scope,yytext,lineno,paran);}
{digit}+ {return INTCONST;}
({digit}+)\.({digit}+) {return FLOATCONST;}
[\n] {lineno++;}
[\t] {;}
[ ] {;}
. {return yytext[0];}
%%
int yywrap()
{
return 1;
}
Ya cc (ngrammar.y) -
%{
#include<stdio.h>
#include<string.h>
int valid=1;
%}
%token CHAR INT FLOAT BOOL MAIN FOR IF ELSE PRINT BREAK CONTINUE BOOLTRUE BOOLFALSE FORMATSPEC OPENBRACES CLOSEBRACES OPENCURLYBRACES CLOSECURLYBRACES UNARYOP ARITHOP RELOP ASSIGNOP COMMA SEMICOLON SINGLEQUOTES DOUBLEQUOTES UNDERSCORE RETURN AND OR DOT STRING IDENTIFIER INTCONST FLOATCONST
%%
start: INT MAIN OPENBRACES CLOSEBRACES OPENCURLYBRACES statement return_statement CLOSECURLYBRACES;
statement: compound_statement | expression_statement | jump_statement | print_statement | for_loop | if_else;
for_loop: FOR OPENBRACES declaration condition_statement SEMICOLON for_expression_statement CLOSEBRACES statement;
if_else: IF OPENBRACES condition_statement CLOSEBRACES statement ELSE statement;
return_statement: RETURN identifier SEMICOLON | RETURN intconstant SEMICOLON;
declaration: declaration_specifiers init_declarator_list SEMICOLON | init_declarator_list SEMICOLON;
declaration_specifiers: CHAR | INT | FLOAT | BOOL;
init_declarator_list: init_declarator | init_declarator COMMA init_declarator_list;
init_declarator: identifier | identifier ASSIGNOP initializer;
initializer: numconstant | identifier;
compound_statement: OPENCURLYBRACES CLOSECURLYBRACES | OPENCURLYBRACES block_item_list CLOSECURLYBRACES | block_item_list;
block_item_list: block_item block_item | block_item;
block_item: declaration | statement |;
expression_statement: identifier ASSIGNOP expression SEMICOLON | identifier UNARYOP SEMICOLON | UNARYOP identifier SEMICOLON;
expression: identifier ARITHOP identifier | identifier ARITHOP numconstant | numconstant ARITHOP numconstant;
for_expression_statement: identifier ASSIGNOP expression | identifier UNARYOP | UNARYOP identifier;
condition_statement: identifier RELOP identifier | identifier RELOP numconstant | numconstant RELOP identifier | condition_statement AND condition_statement | condition_statement OR condition_statement | BOOLTRUE | BOOLFALSE;
jump_statement: BREAK SEMICOLON | CONTINUE SEMICOLON;
print_statement: PRINT OPENBRACES stringconstant CLOSEBRACES SEMICOLON | PRINT OPENBRACES DOUBLEQUOTES FORMATSPEC DOUBLEQUOTES COMMA identifier CLOSEBRACES SEMICOLON;
identifier: IDENTIFIER;
intconstant: INTCONST;
numconstant: INTCONST | FLOATCONST;
stringconstant: STRING;
%%
#include "lex.yy.c"
int yyerror()
{
printf("\nDoes not satisfy the grammar\n");
valid=0;
return 0;
}
int main()
{
yyin = fopen("in.c","r");
yyparse();
if(valid)
{
printf("\nSatisfies the grammar \n");
}
display(head);
}
Скриншоты ниже показаны предупреждения и вывод на выполнение -
(Я пока не написал код для обновления значения и типа данных. Это просто для отображения таблицы символов в ya cc.)