diff --git a/src/index.html b/src/index.html
index 8513cf7..b89817c 100644
--- a/src/index.html
+++ b/src/index.html
@@ -40,14 +40,26 @@
stroke: #000;
}
- .anchor text {
+ .anchor text, .any-character text {
fill: #fff;
}
- .anchor rect {
+ .anchor rect, .any-character rect {
fill: #6b6659;
}
+ .escape text, .literal text {
+ fill: #000;
+ }
+
+ .escape rect {
+ fill: #bada55;
+ }
+
+ .literal rect {
+ fill: #dae9e5;
+ }
+
.placeholder text {
fill: #fff;
font-weight: bold;
diff --git a/src/js/parser/javascript/any_character.js b/src/js/parser/javascript/any_character.js
index bf8df15..b0751d1 100644
--- a/src/js/parser/javascript/any_character.js
+++ b/src/js/parser/javascript/any_character.js
@@ -2,5 +2,11 @@ import _ from 'lodash';
import Base from './base.js';
export default _.extend({}, Base, {
- type: 'any_character'
+ type: 'any_character',
+
+ render() {
+ this.container.addClass('any-character');
+
+ this.label = this.render_label(this.container, 'any character');
+ }
});
diff --git a/src/js/parser/javascript/escape.js b/src/js/parser/javascript/escape.js
index d4e0980..97e2314 100644
--- a/src/js/parser/javascript/escape.js
+++ b/src/js/parser/javascript/escape.js
@@ -2,5 +2,63 @@ import _ from 'lodash';
import Base from './base.js';
export default _.extend({}, Base, {
- type: 'escape'
+ type: 'escape',
+
+ codeMap: {
+ b: 'word boundary',
+ B: 'non-word boundary',
+ d: 'digit',
+ D: 'non-digit',
+ f: 'form feed',
+ n: 'line feed',
+ r: 'carriage return',
+ s: 'white space',
+ S: 'non-white space',
+ t: 'tab',
+ v: 'vertical tab',
+ w: 'word',
+ W: 'non-word',
+ 1: 'Back reference (group = 1)',
+ 2: 'Back reference (group = 2)',
+ 3: 'Back reference (group = 3)',
+ 4: 'Back reference (group = 4)',
+ 5: 'Back reference (group = 5)',
+ 6: 'Back reference (group = 6)',
+ 7: 'Back reference (group = 7)',
+ 8: 'Back reference (group = 8)',
+ 9: 'Back reference (group = 9)',
+ 0: (arg) => {
+ if (arg) {
+ return 'octal: ' + arg;
+ } else {
+ return 'null';
+ }
+ },
+ c: (arg) => {
+ return 'ctrl-' + arg;
+ },
+ x: (arg) => {
+ return '0x' + arg.toUpperCase();
+ },
+ u: (arg) => {
+ return 'U+' + arg.toUpperCase();
+ }
+ },
+
+ render() {
+ var code = this.codeMap[this.esc.code.textValue];
+
+ if (_.isFunction(code)) {
+ code = code(this.esc.arg.textValue);
+ }
+
+ this.container.addClass('escape');
+
+ this.label = this.render_label(this.container, code);
+
+ this.label.select('rect').attr({
+ rx: 3,
+ ry: 3
+ });
+ }
});
diff --git a/src/js/parser/javascript/grammar.peg b/src/js/parser/javascript/grammar.peg
index eabde42..1646db6 100644
--- a/src/js/parser/javascript/grammar.peg
+++ b/src/js/parser/javascript/grammar.peg
@@ -23,65 +23,21 @@ grammar JavascriptRegexp
charset <- "[" "^"? ( charset_range / charset_terminal )* "]"
charset_range <- charset_terminal "-" charset_terminal
charset_terminal <- charset_escape / charset_literal
- charset_escape <- ( backspace_esc
- / control_esc
- / digit_esc
- / non_digit_esc
- / form_feed_esc
- / line_feed_esc
- / carriage_return_esc
- / white_space_esc
- / non_white_space_esc
- / tab_esc
- / vertical_tab_esc
- / word_esc
- / non_word_esc
- / octal_esc
- / hex_esc
- / unicode_esc
- / null_esc )
+ 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 <- [^\\\]] / ( "\\" . )
terminal <- any_character
/ escape
/ literal
any_character <- "."
- escape <- ( word_boundary_esc
- / non_word_boundary_esc
- / control_esc
- / digit_esc
- / non_digit_esc
- / form_feed_esc
- / line_feed_esc
- / carriage_return_esc
- / white_space_esc
- / non_white_space_esc
- / tab_esc
- / vertical_tab_esc
- / word_esc
- / non_word_esc
- / back_reference
- / octal_esc
- / hex_esc
- / unicode_esc
- / null_esc )
+ 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:. )
- back_reference <- "\\" [1-9]
- word_boundary_esc <- "\\b"
- non_word_boundary_esc <- "\\B"
- backspace_esc <- "\\b"
- control_esc <- "\\b" .
- digit_esc <- "\\d"
- non_digit_esc <- "\\D"
- form_feed_esc <- "\\f"
- line_feed_esc <- "\\n"
- carriage_return_esc <- "\\r"
- white_space_esc <- "\\s"
- non_white_space_esc <- "\\S"
- tab_esc <- "\\t"
- vertical_tab_esc <- "\\v"
- word_esc <- "\\w"
- non_word_esc <- "\\W"
- octal_esc <- "\\0" [0-7]+
- hex_esc <- "\\x" [0-9a-fA-F] [0-9a-fA-F]
- unicode_esc <- "\\u" [0-9a-fA-F] [0-9a-fA-F] [0-9a-fA-F] [0-9a-fA-F]
- null_esc <- "\\0"
diff --git a/src/js/parser/javascript/literal.js b/src/js/parser/javascript/literal.js
index f4540aa..798cd7c 100644
--- a/src/js/parser/javascript/literal.js
+++ b/src/js/parser/javascript/literal.js
@@ -2,5 +2,16 @@ import _ from 'lodash';
import Base from './base.js';
export default _.extend({}, Base, {
- type: 'literal'
+ type: 'literal',
+
+ render() {
+ this.container.addClass('literal');
+
+ this.label = this.render_label(this.container, '"' + this.literal.textValue + '"');
+
+ this.label.select('rect').attr({
+ rx: 3,
+ ry: 3
+ });
+ }
});