Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include<stdio.h>
- #include<stdlib.h>
- #include<ctype.h>
- #include<string.h>
- #define MAX_TEXT_LEN 30
- #define MAX_ATOMS 100
- enum{
- ID,
- VAL_INT, /* INT */
- VAL_REAL, /* FLOAT */
- VAL_STR, /* STRING */
- VAR,FUNCTION,IF,ELSE,WHILE,END,RETURN,INT,REAL,STR, /* Reserved words */
- COLON,
- SEMICOLON,
- LPAR,RPAR,
- COMMA,
- OR,AND,NOT,EQUAL,NOTEQUAL,LESS,ASSIGN,
- ADD,SUB,MUL,DIV,
- FINISH /* EOF */
- };
- typedef struct{
- int tip;
- union{
- char text[MAX_TEXT_LEN];
- int nrInt;
- double nrReal;
- };
- }Atom;
- int crtAtom;
- int nrAtom = 0;
- int states[] = {0, 1, 3, 5, 6, 8, 15, 17, 19, 22};
- FILE *f = NULL;
- Atom atomi[MAX_ATOMS];
- /* Analiza sintactica */
- int consume(int tip)
- {
- if(atomi[crtAtom].tip == tip)
- {
- crtAtom++;
- return 1;
- }
- return 0;
- }
- int tipBaza()
- {
- return (crtAtom == INT || crtAtom == REAL || crtAtom == STR);
- }
- int declVar()
- {
- int initAtom = crtAtom;
- if(consume(VAR)){
- if(consume(ID)){
- if(consume(COLON)){
- if(tipBaza()){
- if(consume(SEMICOLON)){
- return 1;
- }
- }
- }
- }
- }
- crtAtom = initAtom;
- return 0;
- }
- int funcArgs()
- {
- return 1;
- }
- int bloc()
- {
- return 1;
- }
- int declFunc()
- {
- int initAtom = crtAtom;
- if(consume(FUNCTION)){
- if(consume(ID)){
- if(consume(LPAR)){
- if(funcArgs()){
- if(consume(RPAR)){
- if(consume(COLON)){
- if(tipBaza()){
- while(declVar())
- ;
- if(bloc()){
- if(consume(END)){
- return 1;
- }
- }
- }
- }
- }
- }
- }
- }
- }
- crtAtom = initAtom;
- return 0;
- }
- int declBloc()
- {
- return 1;
- }
- int program()
- {
- int initAtom = crtAtom;
- for(;;) {
- if(declVar()) {
- } else if(declFunc()) {
- } else if(bloc()) {
- } else break;
- }
- if(consume(FINISH)) {
- return 1;
- }
- crtAtom = initAtom;
- return 0;
- }
- void error(char* m){
- printf("EROARE: %s ",m);
- exit(0);
- }
- void addAtom(int tipAtom){
- atomi[nrAtom].tip = tipAtom;
- nrAtom++;
- }
- int lexer(){
- int s=0, ch = 0, i;
- char buf[100];
- int buf_len = 0;
- while(1){
- /* Check if state is one from the states array */
- for(i = 0; i < 10 && s != states[i]; i++)
- ;
- if(i != 10) {
- ch = getc(f);
- }
- switch(s){
- case 0:
- if(isalpha(ch)||ch=='_'){
- s=1;
- buf[buf_len]=ch;
- buf_len++;
- }
- else if(isdigit(ch)){
- s=3;
- buf[buf_len]=ch;
- buf_len++;
- }
- else if(ch=='\"')
- s=8;
- else if(ch==':')
- s=10;
- else if(ch==';')
- s=11;
- else if(ch=='(')
- s=12;
- else if(ch==')')
- s=13;
- else if(ch==',')
- s=14;
- else if(ch=='|')
- s=15;
- else if(ch=='&')
- s=17;
- else if(ch=='!')
- s=19;
- else if(ch=='=')
- s=22;
- else if(ch=='<')
- s=25;
- else if(ch=='+')
- s=26;
- else if(ch=='-')
- s=27;
- else if(ch=='*')
- s=28;
- else if(ch=='/')
- s=29;
- else if(ch==EOF)
- s=30;
- else if(ch==' '||ch=='\n'||ch=='\r'||ch=='\t'){}
- else error("caracter necunoscut");
- break;
- case 1:
- if(isalpha(ch)||ch=='_'){
- buf[buf_len]=ch;
- buf_len++;
- }
- else {
- ungetc(ch,f);
- s=2;
- }
- break;
- case 2:
- buf[buf_len]=0;
- if(strcmp(buf,"var")==0){
- addAtom(VAR);
- return VAR;
- }
- else if(strcmp(buf,"function")==0){
- addAtom(FUNCTION);
- return FUNCTION;
- }
- else if(strcmp(buf,"if")==0){
- addAtom(IF);
- return IF;
- }
- else if(strcmp(buf,"else")==0){
- addAtom(ELSE);
- return ELSE;
- }
- else if(strcmp(buf,"while")==0){
- addAtom(WHILE);
- return WHILE;
- }
- else if(strcmp(buf,"end")==0){
- addAtom(END);
- return END;
- }
- else if(strcmp(buf,"return")==0){
- addAtom(RETURN);
- return RETURN;
- }
- else if(strcmp(buf,"int")==0){
- addAtom(INT);
- return INT;
- }
- else if(strcmp(buf,"real")==0){
- addAtom(REAL);
- return REAL;
- }
- else if(strcmp(buf,"str")==0){
- addAtom(STR);
- return STR;
- }
- else {
- addAtom(ID);
- strcpy(atomi[nrAtom-1].text,buf);
- return ID;
- }
- case 3:
- if(isdigit(ch)){
- buf[buf_len]=ch;
- buf_len++;
- }
- else if(ch=='.'){
- s=5;
- buf[buf_len]=ch;
- buf_len++;
- }
- else {
- ungetc(ch,f);
- s=4;
- }
- break;
- case 4:
- buf[buf_len]=0;
- addAtom(VAL_INT);
- atomi[nrAtom-1].nrInt=atoi(buf);
- return VAL_INT;
- case 5:
- if(isdigit(ch)){
- s=6;
- buf[buf_len]=ch;
- buf_len++;
- }
- else error("caracter necunoscut - lipsesc zecimale dintr-un numar real");
- break;
- case 6:
- if(isdigit(ch)){
- buf[buf_len]=ch;
- buf_len++;
- }
- else {
- ungetc(ch,f);
- s=7;
- }
- break;
- case 7:
- buf[buf_len]=0;
- addAtom(VAL_REAL);
- atomi[nrAtom-1].nrReal=atof(buf);
- return VAL_REAL;
- case 8:
- if(ch!='\"'){
- buf[buf_len]=ch;
- buf_len++;
- }
- else if(ch=='\"')
- s=9;
- else error("ati introdus un sir invalid");
- break;
- case 9:
- buf[buf_len]=0;
- addAtom(VAL_STR);
- strcpy(atomi[nrAtom-1].text,buf);
- return VAL_STR;
- case 10:
- addAtom(COLON);
- return COLON;
- case 11:
- addAtom(SEMICOLON);
- return SEMICOLON;
- case 12:
- addAtom(LPAR);
- return LPAR;
- case 13:
- addAtom(RPAR);
- return RPAR;
- case 14:
- addAtom(COMMA);
- return COMMA;
- case 15:
- if(ch=='|')
- s=16;
- else error("caracter necunoscut - un singur |");
- break;
- case 16:
- addAtom(OR);
- return OR;
- case 17:
- if(ch=='&')
- s=18;
- else error("caracter necunoscut - un singur &");
- break;
- case 18:
- addAtom(AND);
- return AND;
- case 19:
- if(ch=='=')
- s=21;
- else {
- ungetc(ch,f);
- s=20;
- }
- break;
- case 20:
- addAtom(NOT);
- return NOT;
- case 21:
- addAtom(NOTEQUAL);
- return NOTEQUAL;
- case 22:
- if(ch=='=')
- s=24;
- else {
- ungetc(ch,f);
- s=23;
- }
- break;
- case 23:
- addAtom(ASSIGN);
- return ASSIGN;
- case 24:
- addAtom(EQUAL);
- return EQUAL;
- case 25:
- addAtom(LESS);
- return LESS;
- case 26:
- addAtom(ADD);
- return ADD;
- case 27:
- addAtom(SUB);
- return SUB;
- case 28:
- addAtom(MUL);
- return MUL;
- case 29:
- addAtom(DIV);
- return DIV;
- case 30:
- addAtom(FINISH);
- return FINISH;
- default:
- error("s-a ajuns intr-o stare neprevazuta");
- break;
- }
- }
- }
- const char* showEnum(int i)
- {
- /* Functie doar pentru afisare nume in loc de cifrele corespunzatoare din enum */
- switch (i)
- {
- case 0: return "ID";
- case 1: return "VAL_INT";
- case 2: return "VAL_REAL";
- case 3: return "VAL_STR";
- case 4: return "VAR";
- case 5: return "FUNCTION";
- case 6: return "IF";
- case 7: return "ELSE";
- case 8: return "WHILE";
- case 9: return "END";
- case 10: return "RETURN";
- case 11: return "INT";
- case 12: return "REAL";
- case 13: return "STR";
- case 14: return "COLON";
- case 15: return "SEMICOLON";
- case 16: return "LPAR";
- case 17: return "RPAR";
- case 18: return "COMMA";
- case 19: return "OR";
- case 20: return "AND";
- case 21: return "NOT";
- case 22: return "EQUAL";
- case 23: return "NOTEQUAL";
- case 24: return "LESS";
- case 25: return "ASSIGN";
- case 26: return "ADD";
- case 27: return "SUB";
- case 28: return "MUL";
- case 29: return "DIV";
- case 30: return "FINISH";
- default: return "!!! EROARE !!!";
- }
- }
- int main(){
- //freopen("rezultat.txt", "w", stdout);
- if ((f = fopen("/Users/adrian.creteanu/Docs/Scoala/An III/Sem I/LFTC/Laborator/Compilator_LFTC/Compilator_LFTC/atomi.txt", "r")) == NULL) {
- printf("Eroare: nu se poate deschide fisierul!\n");
- return -1;
- }
- else {
- while(lexer()!=FINISH){
- if(atomi[nrAtom-1].tip==1){
- printf("%s %d \n",showEnum(atomi[nrAtom-1].tip),atomi[nrAtom-1].nrInt);
- }
- else if(atomi[nrAtom-1].tip==2){
- printf("%s %f \n",showEnum(atomi[nrAtom-1].tip),atomi[nrAtom-1].nrReal);
- }
- else {
- printf("%s %s \n",showEnum(atomi[nrAtom-1].tip),atomi[nrAtom-1].text);
- }
- }
- printf("FINISH");
- fclose(f);
- //printf("\n\n");
- //f=fopen("program.q","r");
- /* Verificare analiza sintactica */
- if(program()) {
- printf("Sintaxa okay!\n");
- } else {
- printf("Eroare de sintaxa!\n");
- }
- fclose(f);
- getc(stdin);
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement