function ReGen(form) { var ul = document.getElementById("ex"); while(ul.lastChild) ul.removeChild(ul.lastChild) var f = example_generator(form.re.value) for(var i=0; i!=10; ++i) { var li = document.createElement("li") var tx = document.createTextNode( f() ) li.appendChild(tx) ul.appendChild(li) } } function example_generator( re_str ) { // データメンバ var src = 0 // 始状態 var dst = undefined // 終状態 var eps = [] // イプシロン遷移 var trn = [] // 普通の遷移 // パーザが使う補助関数とか function epsilon(s1, s2) { (eps[s1] || (eps[s1]=[])).push(s2) // dirty hack :p for making back edges broader if(s1 > s2) for(var i=0;i<5;++i) (eps[s1] || (eps[s1]=[])).push(s2) } function transition(s1, s2, tr) { (trn[s1] || (trn[s1]=[])).push({to:s2,tr:tr}) } // とか var cur = 0 var i = 0 function is(c) { return peek()==c } function eat() { return re_str.charAt(i++) } function end() { return re_str.length<=i } function peek() { return re_str.charAt(i) } function skip() { ++cur; ++i } /////////////////////// 正規表現(のごくごく一部)パーザ ///////////////////////////// // REGEX ::= SEQ ('|' SEQ)* // SEQ ::= (UNIT [*+?]?)* // UNIT ::= '(' REGEX ')' | '.' | '[' letters ']' | letter ////////////////////////////////////////////////////////////////////////////////////// function REGEX() { var s = cur++ var ee = [] epsilon(s,cur) ; SEQ() ; ee.push(cur) ; while(is('|')) { skip() ; epsilon(s,cur) ; SEQ() ; ee.push(cur) } for(var i in ee) epsilon(ee[i], cur) } function SEQ() { while( !end() && !is(')') && !is('|') ) { var s = cur UNIT() if( is('*') || is('+') || is('?') ) { if( !is('+') ) epsilon(s, cur+1) if( !is('?') ) epsilon(cur, s) epsilon(cur, cur+1) skip() } } } function UNIT() { switch( peek() ) { case '(': epsilon(cur, cur+1) ; skip() ; REGEX() ; skip() ; epsilon(cur-1, cur) break case '.': transition(cur, cur+1, " !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~") ; skip() break case '[': var s = cur skip() var set = ""; while( !is(']') ) { set += peek() ; skip() } transition(s, cur, set) ; skip() ; epsilon(cur-1, cur) break default: transition(cur, cur+1, peek()) ; skip() break } } REGEX() dst = cur /////////////////////////////// 適当にランダム生成するよ ////////////////////////////////// function tip() { return Math.random()>0.5 } function choose(a) { return a[Math.floor(a.length*Math.random())] } function chooseS(s) { return s.charAt(Math.floor(s.length*Math.random())) } return function() { var instance = "" var s = src for(;;) { if( eps[s] && (!trn[s] || tip()) ) s = choose(eps[s]) // イプシロン遷移してみるてすと if( s == dst ) return instance // 受理状態に来た if( !trn[s] ) continue // いくとこがない if( tip() ) { var t = choose(trn[s]) s = t.to instance += chooseS(t.tr) // 1文字のばしてみる } } } }