diff --git a/homework/0MI0800028/Homework 02/Makefile b/homework/0MI0800028/Homework 02/Makefile new file mode 100644 index 00000000..91f0182c --- /dev/null +++ b/homework/0MI0800028/Homework 02/Makefile @@ -0,0 +1,31 @@ +in="example.lisp" +out="highlighted.html" + +CC=gcc +CFLAGS=-lfl -g +LEX=flex +YACC=bison -t -d + +.PHONY: all +all: build-all webpage + +.PHONY: webpage +webpage: + cat ./page_top.html > $(out) + ./a.out < $(in) >> $(out) + cat ./page_bottom.html >> $(out) + +build-all: build-bison build-flex + $(CC) lex.yy.c commonlisp2html.tab.c $(CFLAGS) + +.PHONY: build-flex +build-flex: commonlisp2html.l + $(LEX) commonlisp2html.l + +.PHONY: build-bison +build-bison: commonlisp2html.y + $(YACC) commonlisp2html.y + +.PHONY: clean +clean: + rm -f a.out *.tab.* lex.yy.c diff --git a/homework/0MI0800028/Homework 02/commonlisp2html.l b/homework/0MI0800028/Homework 02/commonlisp2html.l new file mode 100644 index 00000000..0ae4e549 --- /dev/null +++ b/homework/0MI0800028/Homework 02/commonlisp2html.l @@ -0,0 +1,61 @@ +%{ +#include "commonlisp2html.tab.h" +%} + +DIGIT [0-9] +LEFTBRACKET \( +RIGHTBRACKET \) + +STR \"([^\"]|\\\")*([^\\]|\\\\)\" +NUMBERS [^A-z](\+|-)?{DIGIT}+(\.{DIGIT}+(e{DIGIT}+|d{DIGIT}+|e-{DIGIT}+)?|\/{DIGIT}+)? + +COMMENT ;.*$ +PARAMETER_TYPE &[0-9A-z]+ +KEYWORD :[0-9A-z]+ +CONSTANTS T|NIL|pi|t + +SPECIAL_FORM block|function|if|let|quote|return-from|defun|demacro + +/* Functions */ +F_ARITHMETIC "+ "|"- "|"* "|\/|1\+|1-|conjugate|gcd|lcm +F_NUM_COMPARISON =|\/=|<|>|<=|>=|max|min +F_TRIGONOMETRIC sin|cos|tan|cis|asin|acos|atan|sinh|cosh|tanh|asinh|acosh|atanh +F_OTHER_MATH abs|sqrt|phase|signum +F_LOGICAL not +F_LISTS list +F_OTHER format + +/* Macros */ +M_ARITHMETIC incf|decf +M_LOGICAL and|or +M_CONDITIONAL when|unless|cond|case|typecase +M_DECLARE defvar|defparameter|defconstant|defun + +/* Not in spec, but commonly followed */ +GLOBAL_VAR \*([0-9A-z.?-_])+\* +CONST_VAR \+([0-9A-z.?-_])+\+ + +%% + +{LEFTBRACKET} { return LBRACKET; } +{RIGHTBRACKET} { return RBRACKET; } +{STR} { yylval = strdup(yytext); return STR; } +{NUMBERS} { yylval = strdup(yytext); return NUM; } +{COMMENT} { yylval = strdup(yytext); return COMMENT;} +{PARAMETER_TYPE} { yylval = strdup(yytext); return PARAMETER_TYPE; } +{KEYWORD} { yylval = strdup(yytext); return KEYWORD; } +{CONSTANTS} { yylval = strdup(yytext); return CONSTANT; } + +{SPECIAL_FORM} { yylval = strdup(yytext); return SPECIAL_FORM; } +{F_ARITHMETIC}|{F_NUM_COMPARISON}|{F_TRIGONOMETRIC}|{F_TRIGONOMETRIC}|{F_OTHER_MATH}|{F_LOGICAL}|{F_LISTS}|{F_OTHER} { yylval = strdup(yytext); return FUNCTION; } +{M_ARITHMETIC}|{M_LOGICAL}|{M_CONDITIONAL}|{M_DECLARE} { yylval = strdup(yytext); return MACRO; } + +{GLOBAL_VAR}|{CONST_VAR} { yylval = strdup(yytext); return VARIABLE; } + +\n { return NEWLINE; } + + /* flex catches the longest possibility, so if some variable name contains a known word (function, macro, etc.), this will prevent it from highlighting */ +[A-z!-'*-@]+|" "|\t { yylval = strdup(yytext); return OTHER; } + + +%% diff --git a/homework/0MI0800028/Homework 02/commonlisp2html.y b/homework/0MI0800028/Homework 02/commonlisp2html.y new file mode 100644 index 00000000..008bedbc --- /dev/null +++ b/homework/0MI0800028/Homework 02/commonlisp2html.y @@ -0,0 +1,108 @@ +%{ +#include +#include + +int yylex(); +int yyerror(char *s); + +#define LBRACKET_SPAN "(" +#define RBRACKET_SPAN ")" + +char* span(char *c, char *s); +char* details(char *summary, char *rest); +char* concat2(char *first, char *second); +char* concatperm2(char *first, char *second); +char* concatperm3(char *first, char *second, char *third); +%} + +%token LBRACKET RBRACKET OTHER +%token NEWLINE SPACE TAB +%token STR NUM COMMENT PARAMETER_TYPE KEYWORD CONSTANT +%token SPECIAL_FORM FUNCTION MACRO VARIABLE + +%define api.value.type {char*} + +%% + +start: + | start stlist { printf("%s", $2); free($2); } + | start terminal { printf("%s", $2); free($2); } + | start NEWLINE { printf("\n"); } + +stlist: LBRACKET RBRACKET { $$ = concat2(LBRACKET_SPAN, RBRACKET_SPAN); } + | LBRACKET list RBRACKET { $$ = concatperm3(LBRACKET_SPAN, $2, RBRACKET_SPAN); } + | LBRACKET NEWLINE list RBRACKET { $$ = details(concat2(LBRACKET_SPAN, ""), $3); } + | LBRACKET list NEWLINE postlist RBRACKET { $$ = details($2, $4); } + ; + +postlist: { $$ = ""; } + | postlist stlist { $$ = concat2($1, $2); free($2); } + | postlist terminal { $$ = concat2($1, $2); free($2); } + | postlist NEWLINE { $$ = concat2($1, "\n"); } + ; + +list: terminal + | list terminal { $$ = concatperm2($1, $2); } + | stlist + | list stlist { $$ = concatperm2($1, $2); } + ; + +terminal: STR { $$ = span("string", $1); } + | NUM { $$ = span("number", $1); } + | COMMENT { $$ = span("comment", $1); } + | PARAMETER_TYPE { $$ = span("parameter-type", $1); } + | KEYWORD { $$ = span("keyword", $1); } + | CONSTANT { $$ = span("constant", $1); } + | SPECIAL_FORM { $$ = span("special-operator", $1); } + | FUNCTION { $$ = span("function", $1); } + | MACRO { $$ = span("macro", $1); } + | VARIABLE { $$ = span("variable", $1); } + | OTHER { $$ = span("", $1); } + ; + +%% + + +char* span(char *c, char *s) { + char* str = (char*)malloc(strlen(c) + strlen(s) + 1 + 22); + sprintf(str, "%s", c, s); + free(s); + return str; +} +char* details(char *summary, char *rest) { + if (*rest == '\0') rest = concat2("", ""); // Зверски грозен фикс, но не е толкова голям проблем + + char* str = (char*)malloc(strlen(LBRACKET_SPAN) + strlen(summary) + strlen(rest) + strlen(RBRACKET_SPAN) + 1 + 39); + sprintf(str, "
%s%s\n%s%s
", LBRACKET_SPAN, summary, rest, RBRACKET_SPAN); + + free(summary); free(rest); + return str; +} + +char* concat2(char* first, char* second) { + char* concat = (char*)malloc(strlen(first) + strlen(second) + 1); + sprintf(concat, "%s%s", first, second); + return concat; +} +char* concatperm2(char *first, char *second) { + char* concat = concat2(first, second); + free(first); free(second); + return concat; +} + +char* concatperm3(char *first, char *second, char *third) { + char* concat = (char*)malloc(strlen(first) + strlen(second) + strlen(third) + 1); + sprintf(concat, "%s%s%s", first, second, third); + free(second); + return concat; +} + + +int yyerror(char *s) { + printf("Error: %s\n", s); + return 0; +} + +int main(int argc, char **argv) { + yyparse(); +} diff --git a/homework/0MI0800028/Homework 02/example.lisp b/homework/0MI0800028/Homework 02/example.lisp new file mode 100644 index 00000000..cd7a5773 --- /dev/null +++ b/homework/0MI0800028/Homework 02/example.lisp @@ -0,0 +1,21 @@ +(defvar *NAME* "John") +(defvar *AGE* 23) +(defvar *ABOUT* " T NIL cond decf block") + +;;; This is a stupid funciton +(defun adult? () + (>= *AGE* 18)) + +(defun will-I-graduate? () + NIL) + +(defun distance (p1 p2) + (sqrt (* p1 p1) (* p2 p2))) + +(defun bar (a b) + (if (and (> b a) (<= 10 b)) + (format t "Valid") + (format t "Invalid"))) + +(defun foo (&key ((:apple a)) ((:box b) 0) ((:charlie c) 0 c-supplied-p)) + (list a b c c-supplied-p)) diff --git a/homework/0MI0800028/Homework 02/page_bottom.html b/homework/0MI0800028/Homework 02/page_bottom.html new file mode 100644 index 00000000..073ae297 --- /dev/null +++ b/homework/0MI0800028/Homework 02/page_bottom.html @@ -0,0 +1,3 @@ + + + diff --git a/homework/0MI0800028/Homework 02/page_top.html b/homework/0MI0800028/Homework 02/page_top.html new file mode 100644 index 00000000..fce4d888 --- /dev/null +++ b/homework/0MI0800028/Homework 02/page_top.html @@ -0,0 +1,59 @@ + + + + Highlighted code + + + +