ag/parser.h
ag/scanner.c
+#codea
+codea/codea
+codea/parser.c
+codea/parser.h
+codea/scanner.c
+codea/code.c
+
#weitere eintragen...
torero/torero.log
--- /dev/null
+SHELL := bash
+NAME := codea
+CFLAGS := -ansi -pedantic -D_GNU_SOURCE
+OBJS := scanner.o parser.o symtable.o code.o
+
+all: $(NAME)
+
+$(NAME): $(OBJS)
+ @echo " LINK $@"
+ @gcc -o $@ $(OBJS) -lfl
+
+scanner.c: oxout.l
+ @echo " FLEX $<"
+ @flex -o$@ $<
+
+%.o: %.c parser.h symtable.h
+ @echo " CC $<"
+ @gcc -c $(CFLAGS) $< #-Wall
+
+parser.c: oxout.y
+ @echo " YACC $<"
+ @yacc -t -v -d $< -o $@
+
+parser.h: parser.c
+
+oxout.y oxout.l: parser.y scanner.lex
+ @echo " OX $^"
+ @ox $^
+
+%.c: %.bfe
+ @echo " IBURG $<"
+ @bfe < $< | iburg > $@
+
+.PHONY: clean
+clean:
+ rm -f $(NAME) $(OBJS) scanner.c parser.{h,c,output} oxout.{y,l,h} code.c
+
+1test: 2test
+
+2test:
+ /usr/ftp/pub/ublu/test/$(NAME)/test 2>&1
--- /dev/null
+%{
+ #include <stdio.h>
+ #include <stdlib.h>
+ #include <string.h>
+ #include "symtable.h"
+%}
+
+%start Input
+%token STRUCT END METHOD VAR IF THEN ELSE WHILE DO RETURN NOT OR THIS IDENT NUM ASSIGN
+
+@macro xxputsin(xx,)
+ @i xx = @Statement.sin@;
+@end
+
+@macro statinout()
+ @i @Statement.sout@ = @Statement.sin@;
+ /* das
+ *> xxputsin(@Statement.sout@,)
+ * geht nicht, weil verschachtelte macros deaktiviert sind */
+@end
+
+@autoinh s
+@attributes { char *name; } IDENT
+@attributes { struct symbol *f; } FeldID Parms Structdef Program
+@attributes { struct symbol *s; } Methoddef Statseq Lexpr Expr Minusterm Multerm Orterm Term Exprs Feld
+@attributes { struct symbol *sin; struct symbol *sout; } Statement
+
+@traversal @postorder c
+
+%%
+Input:
+ Program
+ @{
+ @i @Program.f@ = tab_new();
+ @}
+ ;
+
+Program:
+ Methoddef ';' Program
+ @{
+ @i @Methoddef.s@ = @Program.0.f@;
+ @i @Program.1.f@ = @Program.0.f@;
+ @}
+
+ | Structdef ';' Program
+ @{
+ @i @Program.1.f@ = tab_merge(@Program.0.f@, @Structdef.f@, 1);
+ @}
+ |
+ ;
+
+Methoddef:
+ METHOD IDENT '(' Parms ')' Statseq END
+ @{
+ @i @Statseq.s@ = tab_merge(@Methoddef.s@, @Parms.f@, 0);
+ @}
+ ;
+
+Structdef:
+ STRUCT FeldID END
+ @{
+ @i @Structdef.f@ = @FeldID.f@;
+ @}
+ ;
+
+Parms:
+ /* lokale Vars werden in Statement in die tabelle eingefuegt */
+ IDENT Parms
+ @{
+ @i @Parms.0.f@ = tab_add_symbol(@Parms.1.f@, @IDENT.name@, S_VAR, 1);
+ @}
+
+ |
+ @{
+ @i @Parms.f@ = tab_new();
+ @}
+ ;
+
+FeldID:
+ IDENT FeldID
+ @{
+ @i @FeldID.0.f@ = tab_add_symbol(@FeldID.1.f@, @IDENT.name@, S_FIELD, 1);
+ @}
+
+ |
+ @{
+ @i @FeldID.f@ = tab_new();
+ @}
+ ;
+
+Statseq:
+ Statement ';' Statseq
+ @{
+ @i @Statement.sin@ = @Statseq.0.s@;
+ @i @Statseq.1.s@ = @Statement.sout@;
+ @}
+
+ |
+ ;
+
+Statement:
+ Lexpr ASSIGN Expr
+ @{
+ statinout()
+ xxputsin(@Lexpr.s@,)
+ xxputsin(@Expr.s@,)
+ @}
+
+ | VAR IDENT ASSIGN Expr
+ @{
+ /* tab_clone ist hier noetig, vgl. folgendes statement
+ * > var x := x - 1; */
+ @i @Statement.sout@ = tab_add_symbol(tab_clone(@Statement.sin@), @IDENT.name@, S_VAR, 1);
+ xxputsin(@Expr.s@,)
+ @}
+
+ | Expr
+ @{
+ statinout()
+ xxputsin(@Expr.s@,)
+ @}
+
+ | IF Expr THEN Statseq END
+ @{
+ statinout()
+ xxputsin(@Expr.s@,)
+ xxputsin(@Statseq.s@,)
+ @}
+
+ | IF Expr THEN Statseq ELSE Statseq END
+ @{
+ statinout()
+ xxputsin(@Expr.s@,)
+ xxputsin(@Statseq.0.s@,)
+ xxputsin(@Statseq.1.s@,)
+ @}
+
+ | WHILE Expr DO Statseq END
+ @{
+ statinout()
+ xxputsin(@Expr.s@,)
+ xxputsin(@Statseq.s@,)
+ @}
+
+ | RETURN Expr
+ @{
+ statinout()
+ xxputsin(@Expr.s@,)
+ @}
+ ;
+
+Lexpr:
+ IDENT
+ @{
+ @c check(@Lexpr.s@, @IDENT.name@, S_VAR);
+ @}
+
+ | Feld
+ ;
+
+Feld: Term '.' IDENT
+ @{
+ @c check(@Feld.s@, @IDENT.name@, S_FIELD);
+ @}
+ ;
+
+Expr:
+ Term
+ | NOT Term
+ | Term Minusterm
+ | Term Multerm
+ | Term Orterm
+ | Term '<' Term
+ | Term '=' Term
+ ;
+
+Minusterm:
+ '-' Term Minusterm
+ | '-' Term
+ ;
+
+Multerm:
+ '*' Term Multerm
+ | '*' Term
+ ;
+
+Orterm:
+ OR Term Orterm
+ | OR Term
+ ;
+
+Term:
+ '(' Expr ')'
+ | NUM
+ | '-' NUM
+ | THIS
+ | IDENT
+ @{
+ @c check(@Term.s@, @IDENT.name@, S_VAR);
+ @}
+
+ | Feld
+ | IDENT '(' Exprs ')'
+ | Term '.' IDENT '(' Exprs ')'
+ ;
+
+Exprs:
+ Expr ',' Exprs
+ | Expr
+ |
+ ;
+%%
+
+extern int yylex();
+extern int yylineno;
+
+int yyerror(char *error_text)
+{
+ fprintf(stderr,"Zeile %i: %s\n", yylineno, error_text);
+ exit(2);
+}
+
+int main(int argc, char **argv)
+{
+ #if 0
+ yydebug=1;
+ #endif
+ yyparse();
+ return 0;
+}
+
--- /dev/null
+ #include <stdio.h>
+ #include <stdlib.h>
+ #include <string.h>
+ #include "parser.h"
+
+KEYWORD struct|end|method|var|if|then|else|while|do|return|not|or|this
+IDENTIFIER [a-zA-Z_][0-9a-zA-Z_]*
+NUMBER_HEX 0x[0-9A-Fa-f]+
+NUMBER_DEC [0-9]+
+WHITESPACE [\t\n\r ]
+COMMENT_START \/\*
+COMMENT_END \*\/
+
+%x COMMENT
+%option yylineno
+%%
+
+{COMMENT_START} BEGIN(COMMENT);
+
+<COMMENT>{COMMENT_END} BEGIN(INITIAL);
+
+<COMMENT><<EOF>> {
+ fprintf(stderr, "Kommentar nicht geschlossen\n");
+ exit(1);
+}
+
+<COMMENT>(.|\n) /* alles im kommentar wird ignoriert */
+
+struct return(STRUCT);
+end return(END);
+method return(METHOD);
+var return(VAR);
+if return(IF);
+then return(THEN);
+else return(ELSE);
+while return(WHILE);
+do return(DO);
+return return(RETURN);
+not return(NOT);
+or return(OR);
+this return(THIS);
+
+{IDENTIFIER} return(IDENT); @{ @IDENT.name@ = strdup(yytext); @}
+
+{NUMBER_DEC} return(NUM);
+{NUMBER_HEX} return(NUM);
+
+\:= return(ASSIGN);
+\; return(';');
+\( return('(');
+\) return(')');
+\. return('.');
+\- return('-');
+\* return('*');
+\< return('<');
+\= return('=');
+\, return(',');
+
+{WHITESPACE} /* ignore */
+
+. {
+ fprintf(stderr, "Lexical error on line %i\n", yylineno);
+ exit(1);
+}
+
+%%
+
--- /dev/null
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include "symtable.h"
+
+#define DD
+
+struct symbol *tab_new(void)
+{
+ return SYMNULL;
+}
+
+struct symbol *tab_clone(struct symbol *tab)
+{
+ struct symbol *elm = tab;
+ struct symbol *ntab = tab_new();
+#ifdef DD
+ printf("tab_clone: tab(%08X)\n", tab);
+#endif
+
+ while(elm != SYMNULL) {
+ ntab = tab_add_symbol(ntab, elm->ident, elm->type, 0);
+ elm = elm->next;
+ }
+ return ntab;
+}
+
+struct symbol *tab_add_symbol(struct symbol *tab, char *ident, short type, short check)
+{
+ struct symbol *elm = tab;
+ struct symbol *new_elm;
+#ifdef DD
+ printf("tab_add_symbol: tab(%08X), ident(%s), type(%i), check(%i)\n", tab, ident, type, check);
+#endif
+
+ if(tab_lookup(tab, ident, type) != SYMNULL) {
+ if(check) {
+ fprintf(stderr, "Identifier doppelt vorhanden: \"%s\"\n", ident);
+ exit(3);
+ } else {
+ tab = tab_remove_symbol(tab, ident, type);
+ }
+ }
+
+ new_elm = (struct symbol *) malloc(sizeof(struct symbol));
+ new_elm->next = SYMNULL;
+ new_elm->ident = strdup(ident);
+ new_elm->type = type;
+
+ if(tab == SYMNULL) {
+ return new_elm;
+ }
+
+ while(elm->next != SYMNULL) {
+ elm = elm->next;
+ }
+ elm->next = new_elm;
+
+ return tab;
+}
+
+struct symbol *tab_lookup(struct symbol *tab, char *ident, short type)
+{
+ struct symbol *elm = tab;
+
+ if(tab == SYMNULL) {
+ return SYMNULL;
+ }
+
+ do {
+ if((elm->type == type) && (strcmp(elm->ident, ident) == 0)) {
+ return elm;
+ }
+ elm = elm->next;
+ } while(elm != SYMNULL);
+
+ return SYMNULL;
+}
+
+struct symbol *tab_merge(struct symbol *tab, struct symbol *to_add, short check)
+{
+ struct symbol *elm = to_add;
+ struct symbol *ntab = tab_clone(tab);
+#ifdef DD
+ printf("tab_merge: tab(%08X), to_add(%08X), check(%i), ntab(%08X)\n", tab, to_add, check, ntab);
+#endif
+
+ while(elm != SYMNULL) {
+ ntab = tab_add_symbol(ntab, elm->ident, elm->type, check);
+ elm = elm->next;
+ }
+
+ return ntab;
+}
+
+struct symbol *tab_remove_symbol(struct symbol *tab, char *ident, short type)
+{
+ struct symbol *elm = tab;
+ struct symbol *previous_elm = SYMNULL;
+
+ while(elm != SYMNULL) {
+ if((elm->type == type) && (strcmp(elm->ident, ident) == 0)) {
+ if(previous_elm == SYMNULL) {
+ tab = elm->next;
+ } else {
+ previous_elm->next = elm->next;
+ }
+ (void)free(elm->ident);
+ (void)free(elm);
+ break;
+ }
+ previous_elm = elm;
+ elm = elm->next;
+ }
+
+ return tab;
+}
+
+void check(struct symbol *tab, char *ident, short type)
+{
+ struct symbol *elm;
+#ifdef DD
+ printf("check: tab(%08X), ident(%s), type(%i), elm(%08X)\n", tab, ident, type, elm);
+#endif
+
+ if(type == S_VAR) {
+ elm = tab_lookup(tab, ident, type);
+ if(elm != SYMNULL) {
+ return;
+ }
+ }
+
+ /* keine passende variable gefunden?
+ * => vllt gibt es ja ein passenden feldnamen */
+ elm = tab_lookup(tab, ident, S_FIELD);
+ if(elm == SYMNULL) {
+ fprintf(stderr, "Unbekannter Identifier: \"%s\"\n", ident);
+ exit(3);
+ }
+}
+
--- /dev/null
+#ifndef SYMTABLE_H
+#define SYMTABLE_H
+
+#define S_FIELD 0
+#define S_VAR 1
+
+#define SYMNULL (struct symbol *)NULL
+
+struct symbol {
+ char *ident;
+ struct symbol *next;
+ short type;
+};
+
+struct symbol *tab_clone(struct symbol *tab);
+struct symbol *tab_new(void);
+struct symbol *tab_add_symbol(struct symbol *tab, char *ident, short type, short check);
+struct symbol *tab_lookup(struct symbol *tab, char *ident, short type);
+struct symbol *tab_remove_symbol(struct symbol *tab, char *ident, short type);
+struct symbol *tab_merge(struct symbol *tab, struct symbol *to_add, short check);
+void check(struct symbol *tab, char *ident, short type);
+
+#endif