diff --git a/homework/4MI3400199/C2HTML/README.md b/homework/4MI3400199/C2HTML/README.md new file mode 100644 index 00000000..c2149c83 --- /dev/null +++ b/homework/4MI3400199/C2HTML/README.md @@ -0,0 +1,5 @@ +# Homework 1 - C to HTML lexer +### Use flex to colorize C tokens + +### Usage +#### Prints .html to STDOUT. Pipe or write output to file, then open with browser. \ No newline at end of file diff --git a/homework/4MI3400199/C2HTML/ansi.lex b/homework/4MI3400199/C2HTML/ansi.lex new file mode 100644 index 00000000..b4beeda1 --- /dev/null +++ b/homework/4MI3400199/C2HTML/ansi.lex @@ -0,0 +1,209 @@ +%e 1019 +%p 2807 +%n 371 +%k 284 +%a 1213 +%o 1117 + +O [0-7] +D [0-9] +NZ [1-9] +L [a-zA-Z_] +A [a-zA-Z_0-9] +H [a-fA-F0-9] +HP (0[xX]) +E ([Ee][+-]?{D}+) +P ([Pp][+-]?{D}+) +FS (f|F|l|L) +IS (((u|U)(l|L|ll|LL)?)|((l|L|ll|LL)(u|U)?)) +CP (u|U|L) +SP (u8|u|U|L) +ES (\\(['"\?\\abfnrtv]|[0-7]{1,3}|x[a-fA-F0-9]+)) +WS [ \t\v\f] +NL [\n] + +%{ +#include +#include + +#include "y.tab.h" + +int comment_flag = 0; +#define PRINT_DIV(color, text) do{ printf("%s", (comment_flag?"green":(color)), (text)); }while(0); + +extern void yyerror(const char *); /* prints grammar violation message */ + +extern int sym_type(const char *); /* returns type from symbol table */ + +#define sym_type(identifier) IDENTIFIER /* with no symbol table, fake it */ + +static void comment(void); +static int check_type(void); +%} + +%% +"/*" { comment_flag = 1; PRINT_DIV("green", yytext); } +"//".* { comment_flag = 1; PRINT_DIV("green", yytext); } +"*/" { PRINT_DIV("green", yytext); comment_flag = 0; } + +"#"{L}* { PRINT_DIV("pink", yytext); } + +"auto" { PRINT_DIV("blue", yytext); } +"break" { PRINT_DIV("blue", yytext); } +"case" { PRINT_DIV("blue", yytext); } +"char" { PRINT_DIV("blue", yytext); } +"const" { PRINT_DIV("blue", yytext); } +"continue" { PRINT_DIV("blue", yytext); } +"default" { PRINT_DIV("blue", yytext); } +"do" { PRINT_DIV("blue", yytext); } +"double" { PRINT_DIV("blue", yytext); } +"else" { PRINT_DIV("blue", yytext); } +"enum" { PRINT_DIV("blue", yytext); } +"extern" { PRINT_DIV("blue", yytext); } +"float" { PRINT_DIV("blue", yytext); } +"for" { PRINT_DIV("blue", yytext); } +"goto" { PRINT_DIV("blue", yytext); } +"if" { PRINT_DIV("blue", yytext); } +"inline" { PRINT_DIV("blue", yytext); } +"int" { PRINT_DIV("blue", yytext); } +"long" { PRINT_DIV("blue", yytext); } +"register" { PRINT_DIV("blue", yytext); } +"restrict" { PRINT_DIV("blue", yytext); } +"return" { PRINT_DIV("blue", yytext); } +"short" { PRINT_DIV("blue", yytext); } +"signed" { PRINT_DIV("blue", yytext); } +"sizeof" { PRINT_DIV("blue", yytext); } +"static" { PRINT_DIV("blue", yytext); } +"struct" { PRINT_DIV("blue", yytext); } +"switch" { PRINT_DIV("blue", yytext); } +"typedef" { PRINT_DIV("blue", yytext); } +"union" { PRINT_DIV("blue", yytext); } +"unsigned" { PRINT_DIV("blue", yytext); } +"void" { PRINT_DIV("blue", yytext); } +"volatile" { PRINT_DIV("blue", yytext); } +"while" { PRINT_DIV("blue", yytext); } +"_Alignas" { PRINT_DIV("steelblue", yytext); } +"_Alignof" { PRINT_DIV("steelblue", yytext); } +"_Atomic" { PRINT_DIV("steelblue", yytext); } +"_Bool" { PRINT_DIV("steelblue", yytext); } +"_Complex" { PRINT_DIV("steelblue", yytext); } +"_Generic" { PRINT_DIV("steelblue", yytext); } +"_Imaginary" { PRINT_DIV("steelblue", yytext); } +"_Noreturn" { PRINT_DIV("steelblue", yytext); } +"_Static_assert" { PRINT_DIV("steelblue", yytext); } +"_Thread_local" { PRINT_DIV("steelblue", yytext); } +"__func__" { PRINT_DIV("steelblue", yytext); } + +{L}{A}* { PRINT_DIV("black", yytext); } + +{HP}{H}+{IS}? { PRINT_DIV("gold", yytext); } +{NZ}{D}*{IS}? { PRINT_DIV("gold", yytext); } +"0"{O}*{IS}? { PRINT_DIV("gold", yytext); } +{CP}?"'"([^'\\\n]|{ES})+"'" { PRINT_DIV("gold", yytext); } + +{D}+{E}{FS}? { PRINT_DIV("gold", yytext); } +{D}*"."{D}+{E}?{FS}? { PRINT_DIV("gold", yytext); } +{D}+"."{E}?{FS}? { PRINT_DIV("gold", yytext); } +{HP}{H}+{P}{FS}? { PRINT_DIV("gold", yytext); } +{HP}{H}*"."{H}+{P}{FS}? { PRINT_DIV("gold", yytext); } +{HP}{H}+"."{P}{FS}? { PRINT_DIV("gold", yytext); } + +({SP}?\"([^"\\\n]|{ES})*\"{WS}*)+ { PRINT_DIV("pink", yytext); } + +"..." { PRINT_DIV("black", yytext); } +">>=" { PRINT_DIV("black", yytext); } +"<<=" { PRINT_DIV("black", yytext); } +"+=" { PRINT_DIV("black", yytext); } +"-=" { PRINT_DIV("black", yytext); } +"*=" { PRINT_DIV("black", yytext); } +"/=" { PRINT_DIV("black", yytext); } +"%=" { PRINT_DIV("black", yytext); } +"&=" { PRINT_DIV("black", yytext); } +"^=" { PRINT_DIV("black", yytext); } +"|=" { PRINT_DIV("black", yytext); } +">>" { PRINT_DIV("black", yytext); } +"<<" { PRINT_DIV("black", yytext); } +"++" { PRINT_DIV("black", yytext); } +"--" { PRINT_DIV("black", yytext); } +"->" { PRINT_DIV("black", yytext); } +"&&" { PRINT_DIV("black", yytext); } +"||" { PRINT_DIV("black", yytext); } +"<=" { PRINT_DIV("black", yytext); } +">=" { PRINT_DIV("black", yytext); } +"==" { PRINT_DIV("black", yytext); } +"!=" { PRINT_DIV("black", yytext); } +";" { PRINT_DIV("black", yytext); } +("{"|"<%") { PRINT_DIV("brown", yytext); } +("}"|"%>") { PRINT_DIV("brown", yytext); } +"," { PRINT_DIV("black", yytext); } +":" { PRINT_DIV("black", yytext); } +"=" { PRINT_DIV("black", yytext); } +"(" { PRINT_DIV("brown", yytext); } +")" { PRINT_DIV("brown", yytext); } +("["|"<:") { PRINT_DIV("brown", yytext); } +("]"|":>") { PRINT_DIV("brown", yytext); } +"." { PRINT_DIV("black", yytext); } +"&" { PRINT_DIV("grey", yytext); } +"!" { PRINT_DIV("black", yytext); } +"~" { PRINT_DIV("grey", yytext); } +"-" { PRINT_DIV("black", yytext); } +"+" { PRINT_DIV("black", yytext); } +"*" { PRINT_DIV("black", yytext); } +"/" { PRINT_DIV("black", yytext); } +"%" { PRINT_DIV("black", yytext); } +"<" { PRINT_DIV("black", yytext); } +">" { PRINT_DIV("black", yytext); } +"^" { PRINT_DIV("grey", yytext); } +"|" { PRINT_DIV("grey", yytext); } +"?" { PRINT_DIV("black", yytext); } + +{WS}+ { PRINT_DIV("white", yytext); } +{NL}+ { printf("
%s
", yytext); } + +. { /* discard bad characters */ } + +%% + +int yywrap(void) /* called at end of input */ +{ + return 1; /* terminate now */ +} + +static void comment(void) +{ + int c; + + while ((c = input()) != 0) + if (c == '*') + { + while ((c = input()) == '*') + ; + + if (c == '/') + return; + + if (c == 0) + break; + } + yyerror("unterminated comment"); +} + +static int check_type(void) +{ + switch (sym_type(yytext)) + { + case TYPEDEF_NAME: /* previously defined */ + return TYPEDEF_NAME; + case ENUMERATION_CONSTANT: /* previously defined */ + return ENUMERATION_CONSTANT; + default: /* includes undefined */ + return IDENTIFIER; + } +} + +int main() +{ + yylex(); + + return 0; +} diff --git a/homework/4MI3400199/C2HTML/ansi.yacc b/homework/4MI3400199/C2HTML/ansi.yacc new file mode 100644 index 00000000..d0b0356c --- /dev/null +++ b/homework/4MI3400199/C2HTML/ansi.yacc @@ -0,0 +1,534 @@ +%token IDENTIFIER I_CONSTANT F_CONSTANT STRING_LITERAL FUNC_NAME SIZEOF +%token PTR_OP INC_OP DEC_OP LEFT_OP RIGHT_OP LE_OP GE_OP EQ_OP NE_OP +%token AND_OP OR_OP MUL_ASSIGN DIV_ASSIGN MOD_ASSIGN ADD_ASSIGN +%token SUB_ASSIGN LEFT_ASSIGN RIGHT_ASSIGN AND_ASSIGN +%token XOR_ASSIGN OR_ASSIGN +%token TYPEDEF_NAME ENUMERATION_CONSTANT + +%token TYPEDEF EXTERN STATIC AUTO REGISTER INLINE +%token CONST RESTRICT VOLATILE +%token BOOL CHAR SHORT INT LONG SIGNED UNSIGNED FLOAT DOUBLE VOID +%token COMPLEX IMAGINARY +%token STRUCT UNION ENUM ELLIPSIS + +%token CASE DEFAULT IF ELSE SWITCH WHILE DO FOR GOTO CONTINUE BREAK RETURN + +%token ALIGNAS ALIGNOF ATOMIC GENERIC NORETURN STATIC_ASSERT THREAD_LOCAL + +%start translation_unit +%% + +primary_expression + : IDENTIFIER + | constant + | string + | '(' expression ')' + | generic_selection + ; + +constant + : I_CONSTANT /* includes character_constant */ + | F_CONSTANT + | ENUMERATION_CONSTANT /* after it has been defined as such */ + ; + +enumeration_constant /* before it has been defined as such */ + : IDENTIFIER + ; + +string + : STRING_LITERAL + | FUNC_NAME + ; + +generic_selection + : GENERIC '(' assignment_expression ',' generic_assoc_list ')' + ; + +generic_assoc_list + : generic_association + | generic_assoc_list ',' generic_association + ; + +generic_association + : type_name ':' assignment_expression + | DEFAULT ':' assignment_expression + ; + +postfix_expression + : primary_expression + | postfix_expression '[' expression ']' + | postfix_expression '(' ')' + | postfix_expression '(' argument_expression_list ')' + | postfix_expression '.' IDENTIFIER + | postfix_expression PTR_OP IDENTIFIER + | postfix_expression INC_OP + | postfix_expression DEC_OP + | '(' type_name ')' '{' initializer_list '}' + | '(' type_name ')' '{' initializer_list ',' '}' + ; + +argument_expression_list + : assignment_expression + | argument_expression_list ',' assignment_expression + ; + +unary_expression + : postfix_expression + | INC_OP unary_expression + | DEC_OP unary_expression + | unary_operator cast_expression + | SIZEOF unary_expression + | SIZEOF '(' type_name ')' + | ALIGNOF '(' type_name ')' + ; + +unary_operator + : '&' + | '*' + | '+' + | '-' + | '~' + | '!' + ; + +cast_expression + : unary_expression + | '(' type_name ')' cast_expression + ; + +multiplicative_expression + : cast_expression + | multiplicative_expression '*' cast_expression + | multiplicative_expression '/' cast_expression + | multiplicative_expression '%' cast_expression + ; + +additive_expression + : multiplicative_expression + | additive_expression '+' multiplicative_expression + | additive_expression '-' multiplicative_expression + ; + +shift_expression + : additive_expression + | shift_expression LEFT_OP additive_expression + | shift_expression RIGHT_OP additive_expression + ; + +relational_expression + : shift_expression + | relational_expression '<' shift_expression + | relational_expression '>' shift_expression + | relational_expression LE_OP shift_expression + | relational_expression GE_OP shift_expression + ; + +equality_expression + : relational_expression + | equality_expression EQ_OP relational_expression + | equality_expression NE_OP relational_expression + ; + +and_expression + : equality_expression + | and_expression '&' equality_expression + ; + +exclusive_or_expression + : and_expression + | exclusive_or_expression '^' and_expression + ; + +inclusive_or_expression + : exclusive_or_expression + | inclusive_or_expression '|' exclusive_or_expression + ; + +logical_and_expression + : inclusive_or_expression + | logical_and_expression AND_OP inclusive_or_expression + ; + +logical_or_expression + : logical_and_expression + | logical_or_expression OR_OP logical_and_expression + ; + +conditional_expression + : logical_or_expression + | logical_or_expression '?' expression ':' conditional_expression + ; + +assignment_expression + : conditional_expression + | unary_expression assignment_operator assignment_expression + ; + +assignment_operator + : '=' + | MUL_ASSIGN + | DIV_ASSIGN + | MOD_ASSIGN + | ADD_ASSIGN + | SUB_ASSIGN + | LEFT_ASSIGN + | RIGHT_ASSIGN + | AND_ASSIGN + | XOR_ASSIGN + | OR_ASSIGN + ; + +expression + : assignment_expression + | expression ',' assignment_expression + ; + +constant_expression + : conditional_expression /* with constraints */ + ; + +declaration + : declaration_specifiers ';' + | declaration_specifiers init_declarator_list ';' + | static_assert_declaration + ; + +declaration_specifiers + : storage_class_specifier declaration_specifiers + | storage_class_specifier + | type_specifier declaration_specifiers + | type_specifier + | type_qualifier declaration_specifiers + | type_qualifier + | function_specifier declaration_specifiers + | function_specifier + | alignment_specifier declaration_specifiers + | alignment_specifier + ; + +init_declarator_list + : init_declarator + | init_declarator_list ',' init_declarator + ; + +init_declarator + : declarator '=' initializer + | declarator + ; + +storage_class_specifier + : TYPEDEF /* identifiers must be flagged as TYPEDEF_NAME */ + | EXTERN + | STATIC + | THREAD_LOCAL + | AUTO + | REGISTER + ; + +type_specifier + : VOID + | CHAR + | SHORT + | INT + | LONG + | FLOAT + | DOUBLE + | SIGNED + | UNSIGNED + | BOOL + | COMPLEX + | IMAGINARY /* non-mandated extension */ + | atomic_type_specifier + | struct_or_union_specifier + | enum_specifier + | TYPEDEF_NAME /* after it has been defined as such */ + ; + +struct_or_union_specifier + : struct_or_union '{' struct_declaration_list '}' + | struct_or_union IDENTIFIER '{' struct_declaration_list '}' + | struct_or_union IDENTIFIER + ; + +struct_or_union + : STRUCT + | UNION + ; + +struct_declaration_list + : struct_declaration + | struct_declaration_list struct_declaration + ; + +struct_declaration + : specifier_qualifier_list ';' /* for anonymous struct/union */ + | specifier_qualifier_list struct_declarator_list ';' + | static_assert_declaration + ; + +specifier_qualifier_list + : type_specifier specifier_qualifier_list + | type_specifier + | type_qualifier specifier_qualifier_list + | type_qualifier + ; + +struct_declarator_list + : struct_declarator + | struct_declarator_list ',' struct_declarator + ; + +struct_declarator + : ':' constant_expression + | declarator ':' constant_expression + | declarator + ; + +enum_specifier + : ENUM '{' enumerator_list '}' + | ENUM '{' enumerator_list ',' '}' + | ENUM IDENTIFIER '{' enumerator_list '}' + | ENUM IDENTIFIER '{' enumerator_list ',' '}' + | ENUM IDENTIFIER + ; + +enumerator_list + : enumerator + | enumerator_list ',' enumerator + ; + +enumerator /* identifiers must be flagged as ENUMERATION_CONSTANT */ + : enumeration_constant '=' constant_expression + | enumeration_constant + ; + +atomic_type_specifier + : ATOMIC '(' type_name ')' + ; + +type_qualifier + : CONST + | RESTRICT + | VOLATILE + | ATOMIC + ; + +function_specifier + : INLINE + | NORETURN + ; + +alignment_specifier + : ALIGNAS '(' type_name ')' + | ALIGNAS '(' constant_expression ')' + ; + +declarator + : pointer direct_declarator + | direct_declarator + ; + +direct_declarator + : IDENTIFIER + | '(' declarator ')' + | direct_declarator '[' ']' + | direct_declarator '[' '*' ']' + | direct_declarator '[' STATIC type_qualifier_list assignment_expression ']' + | direct_declarator '[' STATIC assignment_expression ']' + | direct_declarator '[' type_qualifier_list '*' ']' + | direct_declarator '[' type_qualifier_list STATIC assignment_expression ']' + | direct_declarator '[' type_qualifier_list assignment_expression ']' + | direct_declarator '[' type_qualifier_list ']' + | direct_declarator '[' assignment_expression ']' + | direct_declarator '(' parameter_type_list ')' + | direct_declarator '(' ')' + | direct_declarator '(' identifier_list ')' + ; + +pointer + : '*' type_qualifier_list pointer + | '*' type_qualifier_list + | '*' pointer + | '*' + ; + +type_qualifier_list + : type_qualifier + | type_qualifier_list type_qualifier + ; + + +parameter_type_list + : parameter_list ',' ELLIPSIS + | parameter_list + ; + +parameter_list + : parameter_declaration + | parameter_list ',' parameter_declaration + ; + +parameter_declaration + : declaration_specifiers declarator + | declaration_specifiers abstract_declarator + | declaration_specifiers + ; + +identifier_list + : IDENTIFIER + | identifier_list ',' IDENTIFIER + ; + +type_name + : specifier_qualifier_list abstract_declarator + | specifier_qualifier_list + ; + +abstract_declarator + : pointer direct_abstract_declarator + | pointer + | direct_abstract_declarator + ; + +direct_abstract_declarator + : '(' abstract_declarator ')' + | '[' ']' + | '[' '*' ']' + | '[' STATIC type_qualifier_list assignment_expression ']' + | '[' STATIC assignment_expression ']' + | '[' type_qualifier_list STATIC assignment_expression ']' + | '[' type_qualifier_list assignment_expression ']' + | '[' type_qualifier_list ']' + | '[' assignment_expression ']' + | direct_abstract_declarator '[' ']' + | direct_abstract_declarator '[' '*' ']' + | direct_abstract_declarator '[' STATIC type_qualifier_list assignment_expression ']' + | direct_abstract_declarator '[' STATIC assignment_expression ']' + | direct_abstract_declarator '[' type_qualifier_list assignment_expression ']' + | direct_abstract_declarator '[' type_qualifier_list STATIC assignment_expression ']' + | direct_abstract_declarator '[' type_qualifier_list ']' + | direct_abstract_declarator '[' assignment_expression ']' + | '(' ')' + | '(' parameter_type_list ')' + | direct_abstract_declarator '(' ')' + | direct_abstract_declarator '(' parameter_type_list ')' + ; + +initializer + : '{' initializer_list '}' + | '{' initializer_list ',' '}' + | assignment_expression + ; + +initializer_list + : designation initializer + | initializer + | initializer_list ',' designation initializer + | initializer_list ',' initializer + ; + +designation + : designator_list '=' + ; + +designator_list + : designator + | designator_list designator + ; + +designator + : '[' constant_expression ']' + | '.' IDENTIFIER + ; + +static_assert_declaration + : STATIC_ASSERT '(' constant_expression ',' STRING_LITERAL ')' ';' + ; + +statement + : labeled_statement + | compound_statement + | expression_statement + | selection_statement + | iteration_statement + | jump_statement + ; + +labeled_statement + : IDENTIFIER ':' statement + | CASE constant_expression ':' statement + | DEFAULT ':' statement + ; + +compound_statement + : '{' '}' + | '{' block_item_list '}' + ; + +block_item_list + : block_item + | block_item_list block_item + ; + +block_item + : declaration + | statement + ; + +expression_statement + : ';' + | expression ';' + ; + +selection_statement + : IF '(' expression ')' statement ELSE statement + | IF '(' expression ')' statement + | SWITCH '(' expression ')' statement + ; + +iteration_statement + : WHILE '(' expression ')' statement + | DO statement WHILE '(' expression ')' ';' + | FOR '(' expression_statement expression_statement ')' statement + | FOR '(' expression_statement expression_statement expression ')' statement + | FOR '(' declaration expression_statement ')' statement + | FOR '(' declaration expression_statement expression ')' statement + ; + +jump_statement + : GOTO IDENTIFIER ';' + | CONTINUE ';' + | BREAK ';' + | RETURN ';' + | RETURN expression ';' + ; + +translation_unit + : external_declaration + | translation_unit external_declaration + ; + +external_declaration + : function_definition + | declaration + ; + +function_definition + : declaration_specifiers declarator declaration_list compound_statement + | declaration_specifiers declarator compound_statement + ; + +declaration_list + : declaration + | declaration_list declaration + ; + +%% +#include + +void yyerror(const char *s) +{ + fflush(stdout); + fprintf(stderr, "*** %s\n", s); +}