syntaxdef cpp {

# whitespace
/\s+/m : ;

# keywords
/auto|b(ool|reak)|c(a(se|tch)|har|lass|on(st|tinue))|\
d(e(fault|lete)|o(|uble))|e(lse|num|xtern)|\
f(loat|or|riend)|goto|i(f|n(line|t))|long|\
n(amespace|ew)|operator|p(r(ivate|otected)|ublic)|\
re(gister|turn)|s(hort|i(gned|zeof)|t(atic|ruct)|witch)|\
t(emp(ate|late)|h(is|row)|ry|ypedef)|un(ion|signed)|\
vo(id|latile)|while\b/ : {
       region {
         type=keyword;
         index=word;
       }
    }

# preprocessor line
/^#.*$/m : {
       region {
         type=keyword; # obviously not a keyword. this will change when we shake out a cannonical list of types 
       }
    }

# char literal
/L?'(\\.|\\[0-7]{3}|\\x[0-9a-fA-F]{2}|.)'/ : {
       region {
          type=char_literal;
       }  

    }

# string literal
/L?"/ : {
    context {
        /\\./: ;
        /$/m : exit;
        "\"" : exit;
    }
    region ${ALL} {
           type=string;
    }
}

#numeric literal
/(0x[0-9a-f]+(lu|ul|[ul])?)|((([0-9]+\.?)|([0-9]*\.[0-9]+))(e(\+|-)?[0-9]+)?(fl|lf|[lf])?)/i : {
       region {
          type=numeric;
       }
   } 

# identifier
/[a-zA-Z_][a-zA-Z_0-9]*/ : {
      region {
         type=identifier;
         index=word;
      }
   }


# comment
/\/\*.*?\*\//s : {
      region {
         type=comment;
         index=prose;
         findlinks=true;
      }
    }

# inline comment
/\/\/.*$/m : {
      region {
         type=comment;
         index=prose;
         findlinks=true;
      }
   }
}

