@@ -25,6 +25,8 @@ prog_language_rep::prog_language_rep (string name)
2525 : abstract_language_rep (name) {
2626 if (DEBUG_PARSER)
2727 debug_packrat << " Building the " * name * " language parser" << LF;
28+ inline_comment_requires_space= false ;
29+ path_parser_enabled = false ;
2830
2931 string use_modules= " (use-modules (code " * name * " -lang))" ;
3032 eval (use_modules);
@@ -49,6 +51,9 @@ prog_language_rep::prog_language_rep (string name)
4951
5052 tree preprocessor_config= get_parser_config (name, " preprocessor" );
5153 customize_preprocessor (preprocessor_config);
54+
55+ tree path_config= get_parser_config (name, " path" );
56+ customize_path (path_config);
5257}
5358
5459tree
@@ -207,6 +212,9 @@ prog_language_rep::customize_comment (tree config) {
207212 }
208213 inline_comment_parser.set_starts (inline_comment_starts);
209214 }
215+ else if (label == " inline_require_space" ) {
216+ inline_comment_requires_space= true ;
217+ }
210218 }
211219}
212220
@@ -227,6 +235,78 @@ prog_language_rep::customize_preprocessor (tree config) {
227235 if (DEBUG_PARSER) debug_packrat << preprocessor_parser.to_string ();
228236}
229237
238+ void
239+ prog_language_rep::customize_path (tree config) {
240+ for (int i= 0 ; i < N (config); i++) {
241+ tree feature= config[i];
242+ string label = get_label (feature);
243+ if (label == " enable" ) {
244+ path_parser_enabled= true ;
245+ }
246+ }
247+ }
248+
249+ static bool
250+ is_path_token_delim (char c) {
251+ return is_space (c) || c == ' (' || c == ' )' || c == ' {' || c == ' }' ||
252+ c == ' [' || c == ' ]' || c == ' ;' || c == ' |' || c == ' &' || c == ' <' ||
253+ c == ' >' ;
254+ }
255+
256+ static bool
257+ looks_like_path_token (string token) {
258+ if (is_empty (token)) return false ;
259+ if (token == " ." || token == " .." ) return false ;
260+
261+ url parsed= url_path (token);
262+ if (is_rooted (parsed) || is_rooted_web (parsed) || is_concat (parsed))
263+ return true ;
264+
265+ bool has_dot = false ;
266+ bool has_alpha= false ;
267+ bool has_digit= false ;
268+ bool has_at = false ;
269+ bool has_colon= false ;
270+ bool has_dash = false ;
271+ for (int i= 0 ; i < N (token); i++) {
272+ char c= token[i];
273+ if (c == ' /' || c == ' \\ ' ) return true ;
274+ if (c == ' .' ) has_dot= true ;
275+ if (is_alpha (c)) has_alpha= true ;
276+ if (is_digit (c)) has_digit= true ;
277+ if (c == ' -' ) has_dash= true ;
278+ if (c == ' @' ) has_at= true ;
279+ if (c == ' :' ) has_colon= true ;
280+ if (c == ' :' && i + 2 < N (token) && token[i + 1 ] == ' /' &&
281+ token[i + 2 ] == ' /' )
282+ return true ;
283+ }
284+
285+ if (N (token) >= 2 && token[0 ] == ' .' && token[1 ] == ' /' ) return true ;
286+ if (N (token) >= 3 && token[0 ] == ' .' && token[1 ] == ' .' && token[2 ] == ' /' )
287+ return true ;
288+ if (N (token) >= 2 && token[0 ] == ' ~' && token[1 ] == ' /' ) return true ;
289+ if (has_at && has_colon) return true ;
290+ if (has_dot && has_alpha) return true ;
291+ if (token[0 ] != ' -' && has_dash && has_alpha && has_digit) return true ;
292+ return false ;
293+ }
294+
295+ static bool
296+ parse_path_token (string s, int & pos) {
297+ if (pos >= N (s)) return false ;
298+ if (is_path_token_delim (s[pos])) return false ;
299+
300+ int start= pos;
301+ int end = pos;
302+ while (end < N (s) && !is_path_token_delim (s[end]))
303+ end++;
304+ string token= s (start, end);
305+ if (!looks_like_path_token (token)) return false ;
306+ pos= end;
307+ return true ;
308+ }
309+
230310text_property
231311prog_language_rep::advance (tree t, int & pos) {
232312 string s= t->label ;
@@ -255,6 +335,10 @@ prog_language_rep::advance (tree t, int& pos) {
255335 current_parser= string_parser.get_parser_name ();
256336 return &tp_normal_rep;
257337 }
338+ if (path_parser_enabled && parse_path_token (s, pos)) {
339+ current_parser= " path_parser" ;
340+ return &tp_normal_rep;
341+ }
258342 if (keyword_parser.parse (s, pos)) {
259343 current_parser= keyword_parser.get_parser_name ();
260344 return &tp_normal_rep;
@@ -313,7 +397,8 @@ prog_language_rep::get_color (tree t, int start, int end) {
313397 int pos= 0 ;
314398 while (pos <= start) {
315399 if (inline_comment_parser.can_parse (s, pos)) {
316- return decode_color (lan_name, encode_color (" comment" ));
400+ if (!inline_comment_requires_space || (pos == 0 || is_space (s[pos - 1 ])))
401+ return decode_color (lan_name, encode_color (" comment" ));
317402 }
318403 pos++;
319404 }
0 commit comments