/* * "syntax hilighting" * * well, not really, but it does colorize keywords and stuff. * * Just a quick hack to show a way of doing this with parse_string * * Bugs: it doesn't handle quoted strings * it doesn't handle comments * and probably some others */ string grammar; /* * build a grammar * * Call this after changing the data mapping or other parts of the grammar * (and recompiling if appropriate) * */ void build_grammar() { mapping data; string *keys; int x, y, num_keys, sz; /* * in a mapping, so we could later add/remove things to color 'classes' without * having to recompile */ data = ([ "statements" : ({ "break", "case", "continue", "default", "do", "else", "for", "foreach", "goto", "if", "in", "inherit", "return", "sizeof", "switch", "while" }), "pre_comp" : ({ "#define", "#else", "#endif", "#if", "#ifdef", "#include" }), "types" : ({ "char", "enum", "float", "int", "array", "private", "mapping", "mixed", "object", "static", "string", "typedef", "union", "varargs", "void" }), "kfuns" : ({ "acos", "act_mxp", "add_action", "all_inventory", "allocate", "allocate_buffer", "allocate_mapping", "asin", "assemble_class", "atan", "author_stats", "bind", "bufferp", "cache_stats", "call_other", "call_out_info", "call_stack", "ceil", "children", "classp", "clear_bit", "this_object", "this_player", "throw", "time", "to_float", "to_int", "typeof", "undefinedp", "unique_array", "unique_mapping", "upper_case", "uptime", "userp", "values", "variables", "virtualp", "write_buffer", "write_bytes", "write_file", "zonetime" }), "safuns" : ({ "abs", "absolute_path", "absolute_value", "add", "add_article", "add_event", "add_maps", "add_sky_event", "admin_email", "adminp", "append_line", "architecture", "archp", "arrange_string", "arrcmp", "assistp", "valid_timezone", "version", "visibility", "visible", "web_translate", "wild_card", "wipe_inv", "wizardp", "wrap", "write", "year" }), "lfuns" : ({ "eventTellHist","CanRemoveItem","GetDummyItems","direct_annihilate_liv", "direct_listen_to_str_word_obj","direct_missile_liv","GetVoteStatus", "GetRiders","GetLivingMaxCarry","CanManipulate","SaveObject","GetCreatorBirth", "GetRandomLimb","direct_createfix","RestoreLimb","eventSteal","direct_remedy_liv", "eventQueueCommand" }) ]); /* * the different kinds of keywords/statements */ keys = map_indices( data ); /* * Handling of quoted strings could be added here */ grammar = ""; /* * Loop through all keys of the data mapping */ for( x = 0, num_keys = sizeof( keys ); x < num_keys; x++ ) { /* * loop through the list of words for each key */ for( y = 0, sz = sizeof( data[keys[x]] ); y < sz; y++ ) { /* * add key=/word/ to the grammar */ grammar += keys[x] + "=/"+data[keys[x]][y]+"/ "; } } /* * a token that matches everything else, followed by * some stuff to define what a stream of tokens looks like, * followed by production rules to map different classes to * their colors. */ grammar += "unknown = nomatch "+ "line: words " + "words: word " + "words: words word " + "word: green " + "word: blue " + "word: red " + "word: cyan " + "word: magenta " + "word: yellow " + "word: unknown " + "green: statements ? greenme " + "blue: pre_comp ? blueme " + "red: types ? redme " + "cyan: kfuns ? cyanme " + "magenta: safuns ? magentame " + "yellow: lfuns ? yellowme"; } /* * Some functions that handle adding the colors */ mixed * greenme( mixed * arg ) { return ({ "%^GREEN%^" + arg[0] + "%^RESET%^" }); } mixed * blueme( mixed * arg ) { return ({ "%^BLUE%^" + arg[0] + "%^RESET%^" }); } mixed * redme( mixed * arg ) { return ({ "%^RED%^" + arg[0] + "%^RESET%^" }); } mixed * cyanme( mixed * arg ) { return ({ "%^CYAN%^" + arg[0] + "%^RESET%^" }); } mixed * magentame( mixed * arg ) { return ({ "%^MAGENTA%^" + arg[0] + "%^RESET%^" }); } mixed * yellowme( mixed * arg ) { return ({ "%^YELLOW%^" + arg[0] + "%^RESET%^" }); } /* * call this with a filename */ void testme( string file ) { string stuff; if(!grammar) { build_grammar(); write("built grammar: "+grammar); } stuff = read_file( file ); write( implode( parse_string( grammar, stuff ), "" ) ); }