Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include<stdio.h>
- #include<stdarg.h>
- #include<conio.h>
- #include<stdlib.h>
- #include<string.h>
- #include<ctype.h>
- typedef struct
- {
- int cod;
- int linie;
- union
- {
- char text[50];
- int vi;
- double vr;
- };
- } Atom;
- Atom atomi[1000];
- int idxAtomi = 0;
- int nAtomi = 0;
- int linie = 1;
- char inbuf[10000];
- char *pch = inbuf;
- FILE *fisier = NULL;
- enum {
- ID, VAL_INT, VAL_REAL, VAL_STR, VAR, FUNCTION, IF, ELSE, WHILE, END, RETURN, INT, REAL, STR,
- COLON, SEMICOLON, LPAR, RPAR, COMMA, OR, AND, NOT, EQUAL, NOTEQUAL, LESS, ASSIGN, ADD, SUB, MUL, DIV, FINISH
- };
- void err(const char *fmt, ...){
- va_list va;
- va_start(va, fmt);
- fprintf(stderr, "error: ");
- vfprintf(stderr, fmt, va);
- fputc('\n', stderr);
- va_end(va);
- exit(-1);
- }
- void tkerr(char* m) {
- printf("Eroare in linia %d, %s ",atomi[idxAtomi].linie, m);
- _getch();
- return(1);
- }
- void addAtom(int codul)
- {
- atomi[nAtomi].cod = codul;
- atomi[nAtomi].linie = linie;
- nAtomi++;
- }
- int getNextTK()
- {
- int s = 0;
- char ch;
- char buf[50];
- int n = 0;
- for (;;)
- {
- ch = *pch;
- //printf("#%d %c (%d)\n",s,ch,ch);
- switch (s)
- {
- case 0:
- if (ch == ' ' || ch == '\n' || ch == '\r' || ch == '\t')
- {
- if (ch == '\n')
- ++linie;
- ++pch;
- }
- else if (ch == ':')
- {
- ++pch;
- s = 1;
- }
- else if (ch == ';')
- {
- ++pch;
- s = 2;
- }
- else if (ch == '(')
- {
- ++pch;
- s = 3;
- }
- else if (ch == ')')
- {
- ++pch;
- s = 4;
- }
- else if (ch == ',')
- {
- ++pch;
- s = 5;
- }
- else if (ch == '-')
- {
- ++pch;
- s = 6;
- }
- else if (ch == '&')
- {
- ++pch;
- s = 7;
- }
- else if (ch == '!')
- {
- ++pch;
- s = 9;
- }
- else if (ch == '=')
- {
- ++pch;
- s = 12;
- }
- else if (ch == '<')
- {
- ++pch;
- s = 15;
- }
- else if (ch == '+')
- {
- ++pch;
- s = 16;
- }
- else if (ch == '*')
- {
- ++pch;
- s = 17;
- }
- else if (ch == '/')
- {
- ++pch;
- s = 18;
- }
- else if (isalpha(ch) || ch == '_')
- {
- buf[n++] = ch;
- ++pch;
- s = 19;
- }
- else if (isdigit(ch))
- {
- buf[n++] = ch;
- ++pch;
- s = 21;
- }
- else if (ch == '\"')
- {
- ++pch;
- s = 26;
- }
- else if (ch == '\0')
- {
- ++pch;
- s = 28;
- }
- else if (ch == '#')
- {
- ++pch;
- s = 29;
- }
- else if (ch == '|')
- {
- ++pch;
- s = 30;
- }
- else
- err("Caracter necunoscut %s \n", ch);
- break;
- case 1:
- addAtom(COLON);
- return COLON;
- case 2:
- addAtom(SEMICOLON);
- return SEMICOLON;
- case 3:
- addAtom(LPAR);
- return LPAR;
- case 4:
- addAtom(RPAR);
- return RPAR;
- case 5:
- addAtom(COMMA);
- return COMMA;
- case 6:
- addAtom(SUB);
- return SUB;
- case 7:
- if (ch == '&')
- s = 8;
- case 8:
- addAtom(AND);
- return AND;
- case 9:
- if (ch == '!')
- {
- ++pch;
- s = 10;
- }
- else
- s = 11;
- break;
- case 10:
- addAtom(NOTEQUAL);
- return NOTEQUAL;
- case 11:
- addAtom(NOT);
- return NOT;
- case 12:
- if (ch == '=')
- {
- ++pch;
- s = 13;
- }
- else
- s = 14;
- break;
- case 13:
- addAtom(EQUAL);
- return EQUAL;
- case 14:
- addAtom(ASSIGN);
- return ASSIGN;
- case 15:
- addAtom(LESS);
- return LESS;
- case 16:
- addAtom(ADD);
- return ADD;
- case 17:
- addAtom(MUL);
- return MUL;
- case 18:
- addAtom(DIV);
- return DIV;
- case 19:
- if (isalnum(ch) || ch == '_')
- {
- buf[n++] = ch;
- ++pch;
- }
- else
- s = 20;
- break;
- case 20:
- buf[n] = '\0';
- if (!strcmp(buf, "var"))
- {
- addAtom(VAR);
- return VAR;
- }
- else if (!strcmp(buf, "function"))
- {
- addAtom(FUNCTION);
- return FUNCTION;
- }
- else if (!strcmp(buf, "if"))
- {
- addAtom(IF);
- return IF;
- }
- else if (!strcmp(buf, "else"))
- {
- addAtom(ELSE);
- return ELSE;
- }
- else if (!strcmp(buf, "while"))
- {
- addAtom(WHILE);
- return WHILE;
- }
- else if (!strcmp(buf, "end"))
- {
- addAtom(END);
- return END;
- }
- else if (!strcmp(buf, "return"))
- {
- addAtom(RETURN);
- return RETURN;
- }
- else if (!strcmp(buf, "int"))
- {
- addAtom(INT);
- return INT;
- }
- else if (!strcmp(buf, "real"))
- {
- addAtom(REAL);
- return REAL;
- }
- else if (!strcmp(buf, "str"))
- {
- addAtom(STR);
- return STR;
- }
- else
- {
- addAtom(ID);
- strcpy(atomi[nAtomi - 1].text, buf);
- return ID;
- }
- break;
- case 21:
- if (isdigit(ch))
- {
- buf[n++] = ch;
- ++pch;
- }
- else if (ch == '.')
- {
- buf[n++] = ch;
- ++pch;
- s = 23;
- }
- else
- s = 22;
- break;
- case 22:
- addAtom(VAL_INT);
- strcpy(atomi[nAtomi - 1].text, buf);
- atomi[nAtomi - 1].vi = atoi(buf);
- return VAL_INT;
- case 23:
- if (isdigit(ch))
- {
- buf[n++] = ch;
- ++pch;
- s = 24;
- }
- break;
- case 24:
- if (isdigit(ch))
- {
- ++pch;
- buf[n++] = ch;
- }
- else
- s = 25;
- break;
- case 25:
- addAtom(VAL_REAL);
- strcpy(atomi[nAtomi - 1].text, buf);
- atomi[nAtomi - 1].vr = atof(buf);
- return VAL_REAL;
- case 26:
- if (ch != '\"')
- {
- ++pch;
- buf[n++] = ch;
- }
- else if (ch == '\"') {
- ++pch;
- s = 27;
- }
- break;
- case 27:
- buf[n] = 0;
- addAtom(VAL_STR);
- strcpy(atomi[nAtomi - 1].text, buf);
- return VAL_STR;
- case 28:
- addAtom(FINISH);
- return FINISH;
- case 29:
- if (ch != '\r'&&ch != '\n'&&ch != '\0')
- {
- ++pch;
- }
- else
- s = 0;
- break;
- case 30:
- if (ch == '|')
- s = 31;
- break;
- case 31:
- addAtom(OR);
- return OR;
- default:
- err("Stare necunoscuta %d \n", s);
- break;
- }
- }
- }
- char *Afisare(int c)
- {
- if (c == 0)
- return("ID");
- else if (c == 1)
- return("VAL_INT");
- else if (c == 2)
- return("VAL_REAL");
- else if (c == 3)
- return("VAL_STR");
- else if (c == 4)
- return("VAR");
- else if (c == 5)
- return("FUNCTION");
- else if (c == 6)
- return("IF");
- else if (c == 7)
- return("ELSE");
- else if (c == 8)
- return("WHILE");
- else if (c == 9)
- return("END");
- else if (c == 10)
- return("RETURN");
- else if (c == 11)
- return("INT");
- else if (c == 12)
- return("REAL");
- else if (c == 13)
- return("STR");
- else if (c == 14)
- return("COLON");
- else if (c == 15)
- return("SEMICOLON");
- else if (c == 16)
- return("LPAR");
- else if (c == 17)
- return("RPAR");
- else if (c == 18)
- return("COMMA");
- else if (c == 19)
- return("OR");
- else if (c == 20)
- return("AND");
- else if (c == 21)
- return("NOT");
- else if (c == 22)
- return("EQUAL");
- else if (c == 23)
- return("NOTEQUAL");
- else if (c == 24)
- return("LESS");
- else if (c == 25)
- return("ASSIGN");
- else if (c == 26)
- return("ADD");
- else if (c == 27)
- return("SUB");
- else if (c == 28)
- return("MUL");
- else if (c == 29)
- return("DIV");
- else if (c == 30)
- return("FINISH");
- }
- int consume(int cod)
- {
- printf("%d: se consuma %s", atomi[idxAtomi].linie ,Afisare(cod));
- if (atomi[idxAtomi].cod == cod) {
- ++idxAtomi;
- printf("=>> consumat\n");
- return 1;
- }
- else {
- printf("=>>altceva (%s)\n", Afisare(atomi[idxAtomi].cod));
- return 0;
- }
- }
- int instr()
- {
- if (expr()) {
- if (consume(SEMICOLON)) {
- return 1;
- }
- else tkerr("expresie neterminata de ;");
- }
- else if (consume(SEMICOLON)) {
- return 1;
- }
- else if (consume(IF)) {
- if (consume(LPAR)) {
- if (expr()) {
- if (consume(RPAR)) {
- if (block()) {
- if (consume(ELSE)) {
- if (block()) {
- if (consume(END)) {
- return 1;
- }
- else tkerr("lipseste END dupa ramura ELSE");
- }
- else tkerr("lipseste blocul de instructiuni de pe ramura ELSE");
- }
- else if (consume(END)) {
- return 1;
- }
- else tkerr("lipseste END la finalul if");
- }
- else tkerr("lipseste blocul de instructiuni din if");
- }
- else tkerr("lipsa paranteza dreapta");
- }
- else tkerr("lipsa expresie in if");
- }
- else tkerr("lipsa paranteza stanga");
- }
- else if (consume(RETURN)) {
- if (expr()) {
- if (consume(SEMICOLON)) {
- return 1;
- }
- else tkerr("lipsa ;");
- }
- else tkerr("lipsa expresie");
- }
- else if (consume(WHILE)) {
- if (consume(LPAR)) {
- if (expr()) {
- if (consume(RPAR)) {
- if (block()) {
- if (consume(END)) {
- return 1;
- }
- else tkerr("lipsa END la finalul WHILE");
- }
- else tkerr("lipsa bloc din interiorul while");
- }
- else tkerr("lipsa paranteza dreapta la while");
- }
- else tkerr("lipsa expresie in while");
- }
- else tkerr("lipsa paranteza stanga la while");
- }
- else return 0;
- }
- int block()
- {
- if (instr()) {
- while (1) {
- if (!instr()) {
- break;
- }
- }
- return 1;
- }
- else return 0;
- }
- int factor()
- {
- if (consume(VAL_INT)) {
- return 1;
- }
- else if (consume(VAL_REAL)) {
- return 1;
- }
- else if (consume(VAL_STR)) {
- return 1;
- }
- else if (consume(LPAR)) {
- if (expr()) {
- if (consume(RPAR)) {
- return 1;
- }
- else tkerr("lipsa paranteza dreapta");
- }
- else tkerr("expresie gresita intre paranteze");
- }
- else {
- if (consume(ID)) {
- if (consume(LPAR)) {
- if (expr()) {
- while (1) {
- if (consume(COMMA)) {
- if (!expr())
- tkerr("lipsa expresie dupa virgula");
- }
- else break;
- }
- if (consume(RPAR)) {
- return 1;
- }
- else tkerr("lipsa paranteza dreapta");
- }
- else if (consume(RPAR)) {
- return 1;
- }
- else tkerr("lipsa paranteza dreapta");
- }
- return 1;
- }
- return 0;
- }
- }
- int exprPrefix()
- {
- if (consume(SUB)) {
- if (factor()) {
- return 1;
- }
- else tkerr("lipsa factor dupa SUB");
- }
- else if (consume(NOT)) {
- if (factor()) {
- return 1;
- }
- else tkerr("lipsa factor dupa NOT");
- }
- else if (factor()) {
- return 1;
- }
- return 0;
- }
- int exprMul()
- {
- if (exprPrefix()) {
- while (1) {
- if (consume(MUL)) {
- if (exprPrefix()) {
- return 1;
- }
- else tkerr("lipsa exprPrefix dupa MUL");
- }
- else if (consume(DIV)) {
- if (exprPrefix()) {
- return 1;
- }
- else tkerr("lipsa exprPrefix dupa DIV");
- }
- else break;
- }
- return 1;
- }
- else return 0;
- }
- int exprAdd()
- {
- if (exprMul()) {
- while (1) {
- if (consume(ADD)) {
- if (exprMul()) {
- return 1;
- }
- else tkerr("lipsa exprInmultire dupa ADD");
- }
- else if (consume(SUB)) {
- if (exprMul()) {
- return 1;
- }
- else tkerr("lipsa exprInmultire dupa SUB");
- }
- else break;
- }
- return 1;
- }
- else return 0;
- }
- int exprComp()
- {
- if (exprAdd()) {
- if (consume(LESS)) {
- if (exprAdd()) {
- return 1;
- }
- else tkerr("lipsa exprAdunare dupa LESS");
- }
- else if (consume(EQUAL)) {
- if (exprAdd()) {
- return 1;
- }
- else tkerr("lipsa exprAdunare dupa EQUAL");
- }
- return 1;
- }
- else return 0;
- }
- int exprAssing()
- {
- if (consume(ID)) {
- if (consume(ASSIGN)) {
- if (exprComp()) {
- return 1;
- }
- else tkerr("lipsa exprComp dupa ASSIGN");
- }
- else {
- idxAtomi--;
- if (exprComp()) {
- return 1;
- }
- else return 0;
- }
- }
- else {
- if (exprComp()) {
- return 1;
- }
- else return 0;
- }
- }
- int exprLogic()
- {
- if (exprAssing()) {
- while (1) {
- if (consume(AND)) {
- if (exprAssing()) {
- return 1;
- }
- else tkerr("lipseste exprAtribuire dupa AND");
- }
- else if (consume(OR)) {
- if (exprAssing()) {
- return 1;
- }
- else tkerr("lipseste exprAtribuire dupa OR");
- }
- else break;
- }
- return 1;
- }
- else return 0;
- }
- int expr()
- {
- if (exprLogic()) {
- return 1;
- }
- return 0;
- }
- int funcParam()
- {
- if (consume(ID)) {
- if (consume(COLON)) {
- if (baseType())
- return 1;
- else tkerr("lipseste tipul de baza");
- }
- else tkerr("lipseste :");
- }
- return 0;
- }
- int funcParams()
- {
- if (funcParam()) {
- while (1) {
- if (consume(COMMA))
- {
- if (funcParam())
- return 1;
- else tkerr("lipseste parametrul de dupa virgula");
- }
- }
- return 1;
- }
- else return 1;
- }
- int baseType()
- {
- if (consume(INT)) {
- return 1;
- }
- else if (consume(REAL)) {
- return 1;
- }
- else if (consume(STR)) {
- return 1;
- }
- else return 0;
- }
- int defVar()
- {
- if (consume(VAR)) {
- if (consume(ID)) {
- if (consume(COLON)) {
- if (baseType()) {
- if (consume(SEMICOLON)) {
- return 1;
- }
- else tkerr("lipseste ; dupa definitia variabile");
- }
- else tkerr("lipseste tipul variabile");
- }
- else tkerr("lipseste : dupa numele variabilei");
- }
- else tkerr("lipseste numele varaibilei");
- }
- return 0;
- }
- int defFunc()
- {
- if (consume(FUNCTION)) {
- if (consume(ID)) {
- if (consume(LPAR)) {
- if (funcParams()) {
- if (consume(RPAR)) {
- if (consume(COLON)) {
- if (baseType()){
- while (1) {
- if (!defVar())
- break;
- }
- if (block()) {
- if (consume(END))
- return 1;
- else tkerr("lipseste END");
- }
- else tkerr("lipseste blocul cu instructiuni");
- }
- else tkerr("lipseste tipul de baza");
- }
- else tkerr("lipseste :");
- }
- else tkerr("lipseste )");
- }
- else tkerr("lipsesc parametrii functiei");
- }
- else tkerr("lipseste (");
- }
- else tkerr("lipseste numele functiei");
- }
- return 0;
- }
- int program()
- {
- for (;;) {
- if (defVar()) {
- }
- else if (defFunc()) {
- }
- else if (block()) {
- }
- else break;
- }
- if (consume(FINISH))
- return 1;
- else {
- tkerr("lipseste FINISH");
- return 0;
- }
- }
- int main()
- {
- fisier = fopen("prog.q", "r");
- if (fisier == NULL)
- printf("eroare");
- int m = fread(inbuf, 1, 20000, fisier);
- inbuf[m] = '\0';
- while (getNextTK() != FINISH)
- {
- printf("%d ", atomi[nAtomi - 1].linie);
- if (atomi[nAtomi - 1].cod == 1)
- {
- printf("%s %d \n", Afisare(atomi[nAtomi - 1].cod), atomi[nAtomi - 1].vi);
- }
- else if (atomi[nAtomi - 1].cod == 2)
- {
- printf("%s %f \n", Afisare(atomi[nAtomi - 1].cod), atomi[nAtomi - 1].vr);
- }
- else
- {
- printf("%s %s \n", Afisare(atomi[nAtomi - 1].cod), atomi[nAtomi - 1].text);
- }
- }
- if (program())
- printf("Sintaxa OK\n");
- else
- err("Eroare\n");
- fclose(fisier);
- _getch();
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement