scanner/scanner.c
scanner/scanner
+#parser
+parser/parser
+parser/parser.c
+parser/parser.h
+parser/scanner.c
+
#weitere eintragen...
--- /dev/null
+NAME := parser
+PARSER := $(NAME)
+SCANNER := scanner
+
+CFLAGS := -pedantic -ansi -g -D_GNU_SOURCE
+
+all: $(NAME)
+
+$(NAME): $(SCANNER).o $(PARSER).o
+ @echo " LINK $<"
+ @gcc $(CFLAGS) -o $@ $? -lfl
+
+$(SCANNER).o: $(SCANNER).c $(PARSER).h
+ @echo " CC $<"
+ @gcc $(CFLAGS) -c $<
+
+$(SCANNER).c: $(SCANNER).lex
+ @echo " FLEX $<"
+ @flex -o$@ $<
+
+$(PARSER).o: $(PARSER).c
+ @echo " CC $<"
+ @gcc $(CFLAGS) -c $<
+
+$(PARSER).c: $(PARSER).y
+ @echo " YACC $<"
+ @yacc -t -v -d $< -o $@
+
+$(PARSER).h: $(PARSER).c
+
+
+.PHONY: clean
+clean:
+ rm -f $(PARSER){,.o,.c,.h,.output} $(SCANNER).{c,o}
+
+2test:
+ /usr/ftp/pub/ublu/test/$(NAME)/test 2>&1
+
--- /dev/null
+%{
+ #include <stdio.h>
+ #include <stdlib.h>
+%}
+
+%start Program
+%token FUNC END STRUCT VAR IF THEN ELSE WHILE DO RETURN OR NOT
+%token ID NUM ASSIGN GREATER
+
+%%
+
+Program: Funcdef ';' Program
+ | Structdef ';' Program
+ |
+ ;
+
+Funcdef: FUNC ID '(' Pars ')' Stats END
+ | FUNC ID '(' ')' Stats END
+ ;
+
+Structdef: STRUCT Ids END
+ ;
+
+Ids: ID Ids
+ |
+ ;
+
+Pars: Pars ',' ID
+ | ID
+ ;
+
+Stats: Stat ';' Stats
+ |
+ ;
+
+Stat: VAR ID ASSIGN Expr
+ | Lexpr ASSIGN Expr
+ | IF Bool THEN Stats END
+ | IF Bool THEN Stats ELSE Stats END
+ | WHILE Bool DO Stats END
+ | Call
+ | RETURN Expr
+ ;
+
+Lexpr: ID
+ | Field
+ ;
+
+Expr: '-' Term
+ | Term
+ | Term Plusterm
+ | Term Malterm
+ ;
+
+Plusterm: '+' Term Plusterm
+ | '+' Term
+ ;
+
+Malterm: '*' Term Malterm
+ | '*' Term
+ ;
+
+Term: '(' Expr ')'
+ | ID
+ | NUM
+ | Call
+ | Field
+ ;
+
+Bool: Bterm
+ | Bterm Orterm
+ | NOT Bterm
+ ;
+
+Orterm: OR Bterm Orterm
+ | OR Bterm
+ ;
+
+Bterm: Term GREATER Term
+ | Term '=' Term
+ | '(' Bool ')'
+ ;
+
+Field: Term '.' ID
+ ;
+
+Call: ID '(' Exprs ')'
+ | ID '(' ')'
+ ;
+
+Exprs: Expr
+ | Exprs ',' Expr
+ ;
+
+%%
+
+extern int yylex();
+extern int yylineno;
+
+int yyerror(char *error_text) {
+ fprintf(stderr,"Line %i: %s\n",yylineno, error_text);
+ exit(2);
+}
+
+int main(int argc, char **argv) {
+/* yydebug=1; */
+ yyparse();
+ return 0;
+}
+
--- /dev/null
+ #include <stdio.h>
+ #include <stdlib.h>
+ #include <string.h>
+ #include "parser.h"
+
+KEYWORD func|end|struct|var|if|then|else|while|do|return|or|not
+SPECIAL_CHAR \;|\.|\(|\)|\,|\:=|\-|\+|\*|>=|=
+IDENTIFIER [[:alpha:]_][[:alnum:]_]*
+NUMBER_HEX [0-9][0-9A-Fa-f]*H
+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>{COMMENT_START} fprintf(stderr, "Possibly nested comment on line %i\n", yylineno);
+
+<COMMENT><<EOF>> { fprintf(stderr, "Unterminated comment.\n"); exit(1); }
+
+<COMMENT>{WHITESPACE} /* ignore */
+
+<COMMENT>. /* ignore everything inside comment */
+
+func return(FUNC);
+end return(END);
+struct return(STRUCT);
+var return(VAR);
+if return(IF);
+then return(THEN);
+else return(ELSE);
+while return(WHILE);
+do return(DO);
+return return(RETURN);
+or return(OR);
+not return(NOT);
+
+{IDENTIFIER} return(ID);
+
+{NUMBER_DEC} return(NUM);
+{NUMBER_HEX} return(NUM);
+
+\:= return(ASSIGN);
+>= return(GREATER);
+{SPECIAL_CHAR} return(yytext[0]);
+
+{WHITESPACE} /* ignore */
+
+. { fprintf(stderr, "Lexical error on line %i\n", yylineno); exit(1); }
+
+%%
+
+