grammar JavascriptRegexp root <- ( ( "/" regexp "/" flags:[igm]* ) / regexp flags:""? ) regexp <- match:match alternates:( "|" match )* match <- (!repeat) parts:match_fragment* anchor <- ( "^" / "$" ) match_fragment <- content:( anchor / subexp / charset / terminal ) repeat:repeat? repeat <- spec:( repeat_any / repeat_required / repeat_optional / repeat_spec ) greedy:"?"? repeat_any <- "*" repeat_required <- "+" repeat_optional <- "?" repeat_spec <- ( "{" min:[0-9]+ "," max:[0-9]+ "}" / "{" min:[0-9]+ ",}" / "{" exact:[0-9]+ "}" ) subexp <- "(" capture:( "?:" / "?=" / "?!" )? regexp ")" charset <- "[" invert:"^"? parts:( charset_range / charset_terminal )* "]" charset_range <- first:charset_range_terminal "-" last:charset_range_terminal charset_terminal <- charset_escape / charset_literal charset_range_terminal <- charset_range_escape / charset_literal charset_escape <- "\\" esc:( code:[bdDfnrsStvwW] arg:""? / control_escape / octal_escape / hex_escape / unicode_escape / null_escape ) charset_range_escape <- "\\" esc:( code:[bfnrtv] arg:""? / control_escape / octal_escape / hex_escape / unicode_escape / null_escape ) charset_literal <- ( ""? literal:[^\\\]] ) / ( literal:"\\" &"c" ) / ( "\\" literal:[^bdDfnrsStvwW] ) terminal <- "." / escape / literal escape <- "\\" esc:( code:[bBdDfnrsStvwW1-9] arg:""? / control_escape / octal_escape / hex_escape / unicode_escape / null_escape ) literal <- ( ""? literal:[^|\\/.\[\(\)?+*$^] ) / ( literal:"\\" &"c" ) / ( "\\" literal:. ) control_escape <- code:"c" arg:[a-zA-Z] octal_escape <- code:"0" arg:[0-7]+ hex_escape <- code:"x" arg:( [0-9a-fA-F] [0-9a-fA-F] ) unicode_escape <- code:"u" arg:( [0-9a-fA-F] [0-9a-fA-F] [0-9a-fA-F] [0-9a-fA-F] ) null_escape <- code:"0" arg:""?