140 likes | 289 Views
Leksikalsk- analyse. Syntax- analyse. Semantik- analyse. Mellemk.- optimering. Kode- generering. Kode- optimering. Buttom-up parsning: Hvor er vi. If-token Ident-token. IdentX(type=Int). if viggo == 3 then. Gen(Comp, *Viggo,3) Gen(jump if not, adress).
E N D
Leksikalsk- analyse Syntax- analyse Semantik- analyse Mellemk.- optimering Kode- generering Kode- optimering Buttom-up parsning: Hvor er vi If-token Ident-token ...... IdentX(type=Int) if viggo == 3 then .... Gen(Comp, *Viggo,3) Gen(jump if not, adress) - - - - - - - Front end - - - - - - - - - Mellem- kode - - - - - Compiler - - - - - - Kald til Runtimesys. - Fortolker - - - - - - - - Back end - - - - - - - - -
Botton-upparsning A Top-down A B Botton-up x x y LALR(1): Fx. YACC Bottom-up
Struktur Fo.l Fo.y lex yacc yylex() yyparse() Source kode Target kode
Makefile LEX= flex YACC= bison LIBS= -L/Programmer/GnuWin32/lib -ly -lfl -lm CC= gcc PROG= Fo $(PROG): $(PROG).tab.o lex.yy.o $(CC) -o $@ $(PROG).tab.o lex.yy.o $(LIBS) lex.yy.o: $(PROG).tab.h $(PROG).tab.c: $(PROG).y $(YACC) -d -v $(PROG).y lex.yy.c: $(PROG).l $(LEX) $(PROG).l
Struktur af Fo.y Erklæringer %% Grammatiske regler %% C-kode Erklæringer: %{ #include "symtab.h" #include <stdio.h> . . . %} %token name1 name2 . . .
Grammatiske regler. BNF formalisme. Både Højre og venstre rekursioner er tilladt. Ikke EBNF. Dvs ikke (..)*, (..)+ osv. Mulighed for at at styre precedence. Dvs: exp-> exp + exp | exp * exp | ..... Er OK.
Regler Type 2 produktion {C kode der udføres når hele højresiden er fundet.}; Ifst: IFT ’(’ logikvalue ’)’ statementlist {CodeGen(Ifst,$3,$5);} $$: Attributten til venstre siden af produktionen $n: Attributten til de n’te symbol på højre siden. Typen af attributten angives i definitionen af tokens. Default er typen integer.
Simpel heltalsregner regn.y %token TAL %% regner: exp {printf("= %d\n",$1);}; exp: exp '+' TAL {$$ = $1 + $3;} | TAL {$$ = $1;} |error ’+’ {printf("bad syntaks ppm");}; %% main() { yyparse(); }
Simpel heltals regner regn.l %{ #include "y.tab.h" extern int yylval; %} %% [0-9]+ {yylval = atoi(yytext); return TAL;} [ \t] ; \n return 0; . return yytext[0]; %%
%% statement_list:statement '\n' | statement_list statement '\n' ; statement: VARIABEL '=' expression {$1->value = $3;} | expression {printf("= %e\n",$1);}; expression: expression '+' expression {$$ = $1 + $3;} | expression '-' expression {$$ = $1 - $3;} | expression '*' expression {$$ = $1 * $3;} | expression '/' expression {if ($3 == 0.0) yyerror("divide dy zero"); else $$ = $1 / $3;} | '-' expression %prec UMINUS {$$ = - $2;} | '(' expression ')' {$$= $2;} | TAL {$$ = $1;} | VARIABEL {$$ = $1->value;}; %%
%{ #include <math.h> #include "symtab.h" #include <string.h> %} %union { char *string; double dval; struct symnote *symptr; } %token <symptr> VARIABEL %token <dval> TAL %token LOG EXP SQRT %left '-' '+' %left '*' '/' %right UMINUS %type<dval> expression
regn.tab.h typedef union { char *string; double dval; struct symnote *symptr; } YYSTYPE; #define VARIABEL 257 #define TAL 258 #define LOG 259 #define EXP 260 #define SQRT 261 #define UMINUS 262 extern YYSTYPE yylval;
%{ #include <string.h> #include "symtab.h" #include "regn.tab.h" %} realtal ([0-9]+|([0-9]*\.[0-9]+))([eE][-+]?[0-9]+)? variabelnavn [a-zA-Z][a-zA-Z0-9]* %% {realtal} {yylval.dval = atof(yytext); return TAL;} {variabelnavn} {if ((yylval.symptr= lookup_sym(yytext)) == NULL) yylval.symptr= insert_sym(yytext); return VARIABEL;} [ \t] ; '$' {return 0;} \n|. {return yytext[0];} %%
main() { init_sym(); yyparse(); }