grammar JavascriptRegexp root <- ( ( "/" regexp "/" flags:[igm]* ) / regexp ""? ) regexp <- match:match alternates:( "|" match )* match <- anchor_start:anchor_start? (!repeat) parts:match_fragment* anchor_end:anchor_end? match_fragment <- content:( subexp / charset / terminal ) repeat:repeat? anchor_start <- "^" anchor_end <- "$" repeat <- spec:( repeat_any / repeat_required / repeat_optional / repeat_spec ) greedy:repeat_greedy? repeat_any <- "*" repeat_required <- "+" repeat_optional <- "?" repeat_spec <- ( "{" min:[0-9]+ "," max:[0-9]+ "}" / "{" min:[0-9]+ ",}" / "{" exact:[0-9]+ "}" ) repeat_greedy <- "?" subexp <- "(" capture:( subexp_no_capture / subexp_positive_lookahead / subexp_negative_lookahead )? regexp ")" subexp_no_capture <- "?:" subexp_positive_lookahead <- "?=" subexp_negative_lookahead <- "?!" charset <- "[" invert:"^"? parts:( charset_range / charset_terminal )* "]" charset_range <- first:charset_terminal "-" last:charset_terminal charset_terminal <- charset_escape / charset_literal charset_escape <- "\\" esc:( code:[bdDfnrsStvwW] arg:""? / code:"0" arg:[0-7]+ / code:"x" arg:( [0-9a-fA-F] [0-9a-fA-F] ) / code:"u" arg:( [0-9a-fA-F] [0-9a-fA-F] [0-9a-fA-F] [0-9a-fA-F] ) ) charset_literal <- ( ""? literal:[^\\\]] ) / ( "\\" literal:. ) terminal <- any_character / escape / literal any_character <- "." escape <- "\\" esc:( code:[bBdDfnrsStvwW1-9] arg:""? / code:"c" arg:. / code:"0" arg:[0-7]+ / code:"x" arg:( [0-9a-fA-F] [0-9a-fA-F] ) / code:"u" arg:( [0-9a-fA-F] [0-9a-fA-F] [0-9a-fA-F] [0-9a-fA-F] ) / code:"0" arg:""? ) literal <- ( ""? literal:[^|\\/.\[\(\)?+*$^] ) / ( "\\" literal:. )