1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132
|
//Syntax highlighting, part two.
#include "fsm.h"
using namespace cppfsm;
#include <iostream>
using std::cin;
using std::cout;
using std::endl;
#include <string>
using std::string;
#include <set>
using std::set;
#include <map>
using std::map;
#include <initializer_list> // for setting up maps without constructors.
// enumeration for our highlighting tags:
enum {
hlstatement, // used for "if,else,for,while" etc...
hlcomment, // for comments
hlstrlit, // for string literals
hlpreproc, // for preprocessor directives (e.g., #include)
hltype, // for datatypes and similar (e.g. int, char, double)
hlnumeric, // for numeric literals (e.g. 1234)
hlescseq, // for escape sequences
hlerror, // for parse errors, like a bad numeric or invalid escape
hlident // for other identifiers. Probably won't use this.
};
// usually global variables are a bad thing, but for simplicity,
// we'll make an exception here.
// initialize our map with the keywords from our list:
map<string, short> hlmap = {
#include "keywords.txt"
};
// note: the above is not a very standard use of #include...
// map of highlighting spans:
map<int, string> hlspans = {
{hlstatement, "<span class='statement'>"},
{hlcomment, "<span class='comment'>"},
{hlstrlit, "<span class='strlit'>"},
{hlpreproc, "<span class='preproc'>"},
{hltype, "<span class='type'>"},
{hlnumeric, "<span class='numeric'>"},
{hlescseq, "<span class='escseq'>"},
{hlerror, "<span class='error'>"}
};
// note: initializing maps as above requires the -std=c++0x compiler flag,
// as well as #include<initializer_list>. Very convenient though.
// to save some typing, store a variable for the end of these tags:
string spanend = "</span>";
string translateHTMLReserved(char c) {
switch (c) {
case '"':
return """;
case '\'':
return "'";
case '&':
return "&";
case '<':
return "<";
case '>':
return ">";
case '\t': // make tabs 4 spaces instead.
return " ";
default:
char s[2] = {c,0};
return s;
}
}
int main() {
// TODO: write the main program.
// It may be helpful to break this down and write
// a function that processes a single line, which
// you repeatedly call from main().
string line;
string output = "";
int state = 0;
string tempWor;
while(getline(cin, line)){ //get input
for(unsigned int i=0; line.size() > i; i++){ //start loop to go through ever character
updateState(state, line[i]);
switch(state){
case 0: //if its in normal state then just add it to output
output += translateHTMLReserved(line[i]);
break; //end of state 0
case 1: //if its state is 1 check to see if it matches hlmap
tempWor += line[i];
while(state == 1){ //makes a temp string to match hlmap
i++;
updateState(state,line[i]);
tempWor += line[i];
}
i--;
tempWor = tempWor.substr(0,tempWor.length()-1); //remove the last char of tempWor
switch(hlmap.find(tempWor) -> second){ //start matching...
case hlstatement: //matched hlstatment
output += hlspans[hlstatement] + tempWor + spanend;
break;
case hltype: //matched hltype
output += hlspans[hltype] + tempWor + spanend;
break;
case hlpreproc: //mathced hlpreproc
output += hlspans[hlpreproc] + tempWor + spanend;
break;
default: //if no match then just add the word to the output =/
output += tempWor;
break; //end of matching
}
tempWor.clear(); //reset tempWor for next use
break; //end of state 1
case 3: //if the state is 3 its in string mode
output += hlspans[hlstrlit] + translateHTMLReserved(line[i]);
str:
while(state != 0){ //loop till it leaves the string state which is when its in its normal state
i++;
updateState(state,line[i]);
return 0;
}
|