Pojęcia

Przykład kompilatora

Następujący program implementuje bardzo prosty jednoprzebiegowy kompilator napisany w języku C. Ten kompilator kompiluje wyrażenia zdefiniowane w notacji infiksowej do ONP, a także do asemblera. Kompilator realizuje strategię rekurencyjnego zagłębiania się w wyrażenie. Każde wywołanie funkcji odpowiada napotkaniu symbolu nieterminalnegonależącego do gramatyki języka.

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
 
#define MODE_POSTFIX 	0
#define MODE_ASSEMBLY 	1
 
char lookahead;
int pos;
int	compile_mode;
char expression[20+1];
 
void error()
{
        printf("Syntax error!\n");
}
 
void match( char t )
{
        if( lookahead == t )
        {
                pos++;
                lookahead = expression[pos];
        }
        else
                error();
}
 
void digit()
{
        switch( lookahead )
        {
                case '0':
                case '1':
                case '2':
                case '3':
                case '4':
                case '5':
                case '6':
                case '7':
                case '8':
                case '9':
			if( compile_mode == MODE_POSTFIX )
				printf("%c", lookahead);
			else
				printf("\tPUSH %c\n", lookahead);
 
                        match( lookahead );
                        break;
                default:
                        error();
                        break;
        }
}
 
void term()
{
        digit();
        while(1)
        {
                switch( lookahead )
                {
                        case '*':
                                match('*');
                                digit();
 
                                printf( "%s", compile_mode == MODE_POSTFIX ? "*"
					: "\tPOP B\n\tPOP A\n\tMUL A, B\n\tPUSH A\n");
 
                                break;
                        case '/':
                                match('/');
                                digit();
 
                                printf( "%s", compile_mode == MODE_POSTFIX ? "/"
					: "\tPOP B\n\tPOP A\n\tDIV A, B\n\tPUSH A\n");
                                break;
                        default:
                                return;
                }
        }
}
 
void expr()
{
        term();
        while(1)
        {
                switch( lookahead )
                {
                        case '+':
                                match('+');
                                term();
 
                                printf( "%s", compile_mode == MODE_POSTFIX ? "+"
					: "\tPOP B\n\tPOP A\n\tADD A, B\n\tPUSH A\n");
                                break;
                        case '-':
                                match('-');
                                term();
 
                                printf( "%s", compile_mode == MODE_POSTFIX ? "-"
					: "\tPOP B\n\tPOP A\n\tSUB A, B\n\tPUSH A\n");
                                break;
                        default:
                                return;
                }
        }
}
 
int main ( int argc, char** argv )
{
        printf("Please enter an infix-notated expression with single digits:\n\n\t");
        scanf("%20s", expression);
 
        printf("\nCompiling to postfix-notated expression:\n\n\t");
	compile_mode = MODE_POSTFIX;
        pos = 0;
        lookahead = *expression;
        expr();
 
        printf("\n\nCompiling to assembly-notated machine code:\n\n");
        compile_mode = MODE_ASSEMBLY;
        pos = 0;
        lookahead = *expression;
        expr();
 
        return 0;
}

Przykład możliwego wyjścia, wygenerowanego podczas wykonania powyższego programu:

 

Please enter an infix-notated expression with single digits:

        3-4*2+2

Compiling to postfix-notated expression:

        342*-2+

Compiling to assembly-notated machine code:

        PUSH 3
        PUSH 4
        PUSH 2
        POP B
        POP A
        MUL A, B
        PUSH A
        POP B
        POP A
        SUB A, B
        PUSH A
        PUSH 2
        POP B
        POP A
        ADD A, B
        PUSH A


Dodaj komentarz






Dodaj

© 2013-2024 PRV.pl
Strona została stworzona kreatorem stron w serwisie PRV.pl