@@ -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,73 @@ 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 == ' &' ||
253+ c == ' <' || 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_at = false ;
268+ bool has_colon= false ;
269+ for (int i= 0 ; i < N (token); i++) {
270+ char c= token[i];
271+ if (c == ' /' || c == ' \\ ' ) return true ;
272+ if (c == ' .' ) has_dot= true ;
273+ if (is_alpha (c)) has_alpha= true ;
274+ if (c == ' @' ) has_at= true ;
275+ if (c == ' :' ) has_colon= true ;
276+ if (c == ' :' && i + 2 < N (token) && token[i + 1 ] == ' /' &&
277+ token[i + 2 ] == ' /' )
278+ return true ;
279+ }
280+
281+ if (N (token) >= 2 && token[0 ] == ' .' && token[1 ] == ' /' ) return true ;
282+ if (N (token) >= 3 && token[0 ] == ' .' && token[1 ] == ' .' &&
283+ token[2 ] == ' /' )
284+ return true ;
285+ if (N (token) >= 2 && token[0 ] == ' ~' && token[1 ] == ' /' ) return true ;
286+ if (has_at && has_colon) return true ;
287+ if (has_dot && has_alpha) return true ;
288+ return false ;
289+ }
290+
291+ static bool
292+ parse_path_token (string s, int & pos) {
293+ if (pos >= N (s)) return false ;
294+ if (is_path_token_delim (s[pos])) return false ;
295+
296+ int start= pos;
297+ int end = pos;
298+ while (end < N (s) && !is_path_token_delim (s[end])) end++;
299+ string token= s (start, end);
300+ if (!looks_like_path_token (token)) return false ;
301+ pos= end;
302+ return true ;
303+ }
304+
230305text_property
231306prog_language_rep::advance (tree t, int & pos) {
232307 string s= t->label ;
@@ -255,6 +330,10 @@ prog_language_rep::advance (tree t, int& pos) {
255330 current_parser= string_parser.get_parser_name ();
256331 return &tp_normal_rep;
257332 }
333+ if (path_parser_enabled && parse_path_token (s, pos)) {
334+ current_parser= " path_parser" ;
335+ return &tp_normal_rep;
336+ }
258337 if (keyword_parser.parse (s, pos)) {
259338 current_parser= keyword_parser.get_parser_name ();
260339 return &tp_normal_rep;
@@ -313,7 +392,9 @@ prog_language_rep::get_color (tree t, int start, int end) {
313392 int pos= 0 ;
314393 while (pos <= start) {
315394 if (inline_comment_parser.can_parse (s, pos)) {
316- return decode_color (lan_name, encode_color (" comment" ));
395+ if (!inline_comment_requires_space ||
396+ (pos == 0 || is_space (s[pos - 1 ])))
397+ return decode_color (lan_name, encode_color (" comment" ));
317398 }
318399 pos++;
319400 }
0 commit comments