Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <assert.h>
- #include <stdlib.h>
- #include <stdio.h>
- #include <math.h>
- #include "lexer.h"
- #include "generator.h"
- #define MAX_INPUT_SIZE 160
- /*** Syntakticky analyzator a interpretator ***/
- /* Overenie symbolu na vstupe a precitanie dalsieho.
- * Vracia atribut overeneho symbolu. */
- int match(const Symbol expected)
- {
- if (lex_symbol == expected) {
- int attr = lex_attr;
- next_symbol();
- return attr;
- } else {
- fprintf(stderr,
- "CHYBA: Chyba symbol %s, namiesto toho sa vyskytol %s.\n",
- symbol_name(expected), symbol_name(lex_symbol));
- exit(1);
- }
- }
- /* Tabulka premennych:
- * index -- index identifikatora, hodnota -- hodnota premennej */
- int variables[LEX_IDS_MAX];
- void read_variable(int id_idx)
- {
- int value;
- printf("%s = ", lex_ids[id_idx]);
- scanf("%d", &value);
- variables[id_idx] = value;
- }
- /* Gramatika:
- *
- * Expr -> Term {("+"|"-") Term}
- * Term -> VALUE | "(" Expr ")"
- */
- int expr(), term(), print(), read(), mul(), power(), equal(), let(), assign(), condition(), program();
- int print(){
- if(lex_symbol == PRINT){
- // sicko ok
- } else {
- fprintf(stderr,"Chyba prikaz PRINT ! objavil sa : %s", symbol_name(lex_symbol));
- }
- next_symbol();
- return equal();
- }
- int condition(){
- // let a; let b; if a < b ? print 1 : print 0;
- int res = -1;
- if(lex_symbol == IF){
- next_symbol();
- if(equal()) {
- while( lex_symbol != ELSE ){
- switch (lex_symbol) {
- case PRINT: res = print(); break;
- case ASSIGN: assign(); break;
- }
- if(lex_symbol == ELSE){
- break;
- }
- next_symbol();
- }
- while(lex_symbol != SEMICOLON && lex_symbol != SEOF){
- next_symbol();
- }
- next_symbol();
- } else {
- while (lex_symbol != ELSE){
- next_symbol();
- }
- while( lex_symbol != SEMICOLON ){
- switch (lex_symbol) {
- case PRINT: res = print(); break;
- case ASSIGN: assign(); break;
- }
- if(lex_symbol == ELSE){
- break;
- }
- next_symbol();
- }
- next_symbol();
- }
- }
- return res;
- }
- int let(){
- int pocet_premennych = 0;
- if( lex_symbol == LET ){
- while( lex_symbol != SEMICOLON) {
- next_symbol();
- if(lex_symbol == SEMICOLON){
- break;
- }
- if(lex_symbol == COMMA){
- next_symbol();
- }
- if(lex_symbol == SEMICOLON){
- break;
- }
- if(lex_symbol == ID){
- read_variable(lex_attr);
- }
- pocet_premennych++;
- next_symbol();
- }
- }
- return pocet_premennych;
- }
- int read(){
- int pocet_premennych = 0;
- if(lex_symbol == READ){
- do {
- next_symbol();
- if(lex_symbol != ID){
- fprintf(stderr,"Chyba ID !");
- } else {
- read_variable(lex_attr);
- }
- next_symbol();
- pocet_premennych++;
- } while (lex_symbol == COMMA);
- } else {
- fprintf(stderr,"Chyba prikaz READ !");
- }
- return pocet_premennych;
- }
- int assign(){
- int variables_count = 0;
- // let a; a:=10; print a; -> 10
- // let a,b; print a*b+5; let a,b; print (a*b)+5;
- // let a,b; a:=b*b; print a;
- // let a,b; print a*b;
- do {
- if(lex_symbol == COMMA){
- next_symbol();
- }
- int position = lex_attr;
- next_symbol();
- if(lex_symbol == SEMICOLON || lex_symbol == SEOF || lex_symbol != ASSIGN){
- next_symbol();
- break;
- }
- next_symbol();
- // if assign
- variables[position] = equal();
- variables_count++;
- } while(lex_symbol != SEOF && lex_symbol != SEMICOLON);
- next_symbol();
- return variables_count;
- }
- int program (){
- int j = 0;
- int k;
- int res = 0;
- while(lex_symbol != SEOF){
- switch (lex_symbol) {
- case LET:
- k = j;
- j += let();
- for (; k < j; k++) {
- write_ask_var(k, lex_ids[k]);
- }
- break;
- case READ:
- k = j;
- j += read();
- for (; k < j; k++) {
- write_ask_var(k, lex_ids[k]);
- }
- break;
- case ID: assign(); break;
- case PRINT: res = print(); break;
- case SEMICOLON: next_symbol(); break;
- case IF: condition(); break;
- case SEOF: break;
- }
- }
- return res;
- }
- /* Term -> VALUE | "(" Expr ")" */
- int term()
- {
- int value;
- switch (lex_symbol) {
- case VALUE:
- value = lex_attr;
- write_number(value);
- next_symbol();
- break;
- case LPAR:
- next_symbol();
- value = expr();
- match(RPAR);
- break;
- case ID:
- write_var(lex_attr);
- value = variables[lex_attr];
- next_symbol();
- break;
- case SEOF: break;
- // default:
- // default:
- //fprintf(stderr, "CHYBA: Chyba operand, namiesto toho sa vyskytol %s\n.",
- // symbol_name(lex_symbol));
- // exit(1);
- }
- return value;
- }
- /* Expr -> Term {("+"|"-") Term} */
- int expr()
- {
- int leftOp, rightOp;
- Symbol operator;
- leftOp = mul();
- while (lex_symbol == PLUS || lex_symbol == MINUS) {
- operator = lex_symbol;
- next_symbol();
- rightOp = mul();
- switch (operator) {
- case PLUS:
- write_add();
- leftOp = leftOp + rightOp;
- break;
- case MINUS:
- write_sub();
- leftOp = leftOp - rightOp;
- break;
- case SEOF:
- break;
- default:
- assert("Neocakavany operator v expr()");
- }
- }
- return leftOp;
- }
- int power(){
- int leftOp, rightOp;
- leftOp = term();
- Symbol operator = lex_symbol;
- while(operator == POWER){
- operator = lex_symbol;
- next_symbol();
- rightOp = power();
- if(operator == POWER){
- write_power(leftOp, rightOp);
- leftOp = (int)pow(leftOp, rightOp);
- }
- }
- return leftOp;
- }
- // let a; let b; if a < b ? print 1 : print 0;
- //
- // var a,b; read a,b; if (a>b) then a:=9; else a:=0; print a;
- // let a,b; if a>b ? print 9 : print 0;
- //
- int mul(){
- int leftOp, rightOp;
- Symbol operator;
- leftOp = power();
- operator = lex_symbol;
- while( operator == MUL || operator == DIV ) {
- operator = lex_symbol;
- if( operator == SEOF || operator == SEMICOLON ){
- break;
- }
- next_symbol();
- rightOp = power();
- switch ( operator ) {
- case MUL:
- write_mul();
- leftOp = leftOp * rightOp;
- break;
- case DIV:
- write_div();
- leftOp = leftOp / rightOp;
- break;
- default:
- break;
- //fprintf(stderr, "CHYBA: Neocakavany ('%s') operator pri deleni a nasobeni", symbol_name(operator));
- }
- }
- return leftOp;
- }
- int equal(){
- int leftOp = expr(), rightOp;
- Symbol operator = lex_symbol;
- while(
- operator == EQUAL ||
- operator == GREATER_THAN ||
- operator == GREATER_THAN_EQUAL ||
- operator == LESS_THAN_EQUAL ||
- operator == LESS_THAN
- ){
- operator = lex_symbol;
- next_symbol();
- rightOp = expr();
- switch ( operator ) {
- case EQUAL: leftOp = leftOp == rightOp; break;
- case GREATER_THAN_EQUAL: leftOp = leftOp >= rightOp; break;
- case GREATER_THAN: leftOp = leftOp > rightOp; break;
- case LESS_THAN_EQUAL: leftOp = leftOp <= rightOp; break;
- case LESS_THAN: leftOp = leftOp < rightOp; break;
- case SEOF: break;
- //default: fprintf(stderr ,"CHYBA: ockava sa operator porovnania nie : ('%s') ", symbol_name(lex_symbol)); break;
- }
- }
- return leftOp;
- }
- int main(int argc, char** argv)
- {
- // otvorenie suboru pre Computron VM
- FILE *output_file = fopen("program.bin", "wb");
- init_generator(output_file);
- printf("Vstupny retazec: ");
- // Citanie vstupneho retazca
- char source[MAX_INPUT_SIZE];
- fgets(source, MAX_INPUT_SIZE, stdin);
- init_lexer(source);
- print_tokens();
- printf("\nZaciatok syntaxou riadenej interpretacie\n\n");
- init_lexer(source);
- next_symbol();
- // volanie programu
- int result = program();
- printf("Vysledok: %d\n", result);
- write_result();
- write_end();
- // ukoncenie prace s binarnym suborom pre Computron VM
- generate_output();
- fclose(output_file);
- printf("Program vygenerovany v program.bin\n");
- getchar();
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement