æè¿, Jisonã使ããã¨ãã¦ãã人ãã¡ãã»ãè¦ãã®ã§, ã¡ãã£ã¨å ¥éçãªãã¤ãæ¸ãã¦ã¿ã.
å®ç¾©(ã¦ãã¨ã¼
- Jisonã¨ããã®ã¯, JavaScriptã§æ¸ããããã¼ãµã¼ãåããã¨ãã§ãã, ãã¼ãµã¸ã§ãã¬ã¼ã¿ã¼ã®ä¸ã¤
ç¾å¨Jison㯠https://github.com/zaach/jison ã§å
¥æå¯è½ã§ã.
è²ã
説æããããã©, æ§æ解æã¨ãLALRã¨ã説æãã ããã, ãããåºãé£ããã®ã§, ...
åãæ¢ããJisonã®exampleã試ãã¦ã¿ãã!!!
ã¾ãã¯, narwhalãã¤ã³ã¹ãã¼ã«ãã¾ããã
https://github.com/280north/narwhal
ããè½ã¨ãã¦, PATHãéã.
narwhalã¨å©ãã¦JavaScriptã®ã¤ã³ã¿ã©ã¯ãã£ããªç°å¢ãç«ã¡ä¸ãã£ããå¤åOK.
(ã¨ãããnarwhalã®è©³ãããã¨ã¯åã¯ããåãããªã...)
Jisonã®gitãªãã¸ããªããã¼ã«ã«ã«cloneããã!
$ git clone git://github.com/zaach/jison.git
$ cd jison/
(gitå ¥ãã¦ãªãã¦ãzipã§è½ã¨ãã¦è§£åããã°ä½¿ããã)
exampleãã©ã«ããããã®ã§, æ©é, 試ãã¦ã¿ãã.
$ cd example/ $ cat calculator.jison /* description: Parses end executes mathematical expressions. */ /* lexical grammar */ %lex %% \s+ /* skip whitespace */ [0-9]+("."[0-9]+)?\b return 'NUMBER' "*" return '*' "/" return '/' "-" return '-' "+" return '+' "^" return '^' "!" return '!' "%" return '%' "(" return '(' ")" return ')' "PI" return 'PI' "E" return 'E' <<EOF>> return 'EOF' . return 'INVALID' /lex /* operator associations and precedence */ %left '+' '-' %left '*' '/' %left '^' %right '!' %right '%' %left UMINUS %start expressions %% /* language grammar */ expressions : e EOF { typeof console !== 'undefined' ? console.log($1) : print($1); return $1; } ; e : e '+' e {$$ = $1+$3;} | e '-' e {$$ = $1-$3;} | e '*' e {$$ = $1*$3;} | e '/' e {$$ = $1/$3;} | e '^' e {$$ = Math.pow($1, $3);} | e '!' {{ $$ = (function fact (n) { return n==0 ? 1 : fact(n-1) * n })($1); }} | e '%' {$$ = $1/100;} | '-' e %prec UMINUS {$$ = -$2;} | '(' e ')' {$$ = $2;} | NUMBER {$$ = Number(yytext);} | E {$$ = Math.E;} | PI {$$ = Math.PI;} ; $ narwhal ../bin/jison ./calculator.jison
jisonã«, calculator.jisonãã¡ã¤ã«ã渡ãã¦ãããã¨, calculator.jsãã¡ã¤ã«ãåããã£ã¬ã¯ããªã«åºæ¥ã¾ã
calculator.js , ã§ããããª?
$ cat calculator.js /* Jison generated parser */ var calculator = (function(){ var parser = {trace: function trace() { } , yy: {}, ##### çç¥ ##### $ narwhal calculator.js Error: Usage: calculator.js FILE
ãã, ãã¡ã¤ã«ãæå®ããã®ã...
$ echo '100 * (1 + 2)' > caltest.txt $ narwhal calculator.js caltest.txt 300 $ echo '10!' > caltest.txt $ narwhal calculator.js caltest.txt 3628800
(â©Â´âï½)â©ï¾ï½°ï½²
åãæ¢ãã, ãã (calculator.jison) ãåããã, Jisonã使ããããããªããã£ã¦æãã¦ãã, ãã!!!
ã, ã¾ãã³ã³ã½ã¼ã«ã§ã¯åãäº, åãã£ããã©...
Jisonã®åããJavaScriptãã¡ã¤ã«ãHTMLã§ä½¿ããããã ãã©
大ä¸å¤«!!!
ã¡ãã£ã¨ãã¹ããæ¸ãã¦ã¿ã¾ããã
å ã»ã©ã®calculator.jsã¨åãã¨ããã«calculator.htmlã¨ãã¦æ¬¡ã®ããã«æ¸ãã¦ã¿ã¾ã
<!DOCTYPE HTML> <html lang="en"> <head> <meta charset="UTF-8"> <title>jisonã«ããè¨ç®æ©</title> <script src="./calculator.js" type="text/javascript"></script> <script type="text/javascript"> onload = function () { var exprTextArea = document.getElementById('expression'), resultTextArea = document.getElementById('result'), expr, ans; exprTextArea.addEventListener('keydown', function () { setTimeout(function () { expr = exprTextArea.value; try { ans = calculator.parse(expr); // ââ ããéè¦ã ããè¦ãã¦ãããª!!!! resultTextArea.innerText = ans; } catch (e) { resultTextArea.innerText = e; } }, 20); }); } </script> </head> <body> <textarea id="expression" rows="20" cols="50"></textarea> <textarea id="result" rows="20" cols="50"></textarea> <br /> æ°å¼ãå ¥ãã¦ãã ãã </body> </html>
ãã©ã¦ã¶ã¼ã§éãã¦ã¿ã¦, å·¦ã®textareaã«æ¸ããå¼ã®çµæãã¡ããã¨è¨ç®ã§ãã¦ããOK.
fc2ã®æ¹ã«ããµã³ãã«ãã¢ãããã¦ããã!
http://itchyny.web.fc2.com/calculator/
ãã¼ã, ãã®ããã¼ã¼!!!
æ§æ解æã¯???
è¨ç®æ©ãã§ããã®ã¯ãããã©, è¨ç®æ¨ãä½ããããã â !!!
ã£ã¦ãã¨ã§, ãããããµãã«æ¸ãã¦ã¿ãã!
$ cat calculator2.jison %lex %% \s+ /* skip whitespace */ [0-9]+("."[0-9]+)?\b return 'NUMBER' "*" return '*' "/" return '/' "-" return '-' "+" return '+' "^" return '^' "!" return '!' "%" return '%' "(" return '(' ")" return ')' "PI" return 'PI' "E" return 'E' <<EOF>> return 'EOF' . return 'INVALID' /lex /* operator associations and precedence */ %left '+' '-' %left '*' '/' %left '^' %right '!' %right '%' %left UMINUS %start expressions %% /* language grammar */ expressions : e EOF { return $1; } ; e : e '+' e {$$ = new Add($1, $3);} | e '-' e {$$ = new Sub($1, $3);} | e '*' e {$$ = new Mul($1, $3);} | e '/' e {$$ = new Div($1, $3);} | e '^' e {$$ = new Pow($1, $3);} | e '!' {$$ = new Factorial($1);} | e '%' {$$ = new Percentage($1);} | '-' e %prec UMINUS {$$ = new Minus($2);} | '(' e ')' {$$ = $2;} | NUMBER {$$ = Number ($1);} | E {$$ = E;} | PI {$$ = PI;} ; $ narwhal ../bin/jison/ ./calculator2.jison $
ããã«è¨ç®ãã¡ãããã«, ãªãã¸ã§ã¯ããä½ããã ã!
ä¾ãã°,
function Add (x, y) { this.left = x; this.right = y; }
ã¿ããã«å®ç¾©ãã¦ããã¨, 左辺ã¨å³è¾ºãå ¥ãã!
ã§, ãªãã¸ã§ã¯ããè¿ã£ã¦ãããã, å帰ã§ããããåã£ã¦ã¿ããããããããªãããª!!
ã£ã¦ãã¨ã§, ãµã³ãã«ã¯ãã¡ãâ
http://itchyny.web.fc2.com/calculator2/
ã¡ãã£ã¨èª¬æãå ãã¦ããã
- hoge.jisonãjisonã§å¦çããã¨, hoge.jsãã¡ã¤ã«ãã§ããã
- ãã®ä¸ã®, hoge.parseé¢æ°ã使ãã
- jisonãã¡ã¤ã«ã«æ¸ã, %startã«æ³¨æ. ãã¼ã¹ã¯ããããå§ã¾ãã
- "{ $$ = ... ;}" ãçç¥ããã¨, $1ã®å¤ããã©ã¼ã«ããã (å¤å
- ãã¼ã¯ã³ãèªã¿è¾¼ãããã®ï½¢æ£è¦è¡¨ç¾ï½£ãç¹å¾´ããå½¢ã ãã, ãµã³ãã«ãåèã«ããã»ããããã
jsparser
Jisonã¯CoffeeScriptã®å¦çç³»ã«ã使ããã¦ããããã ãã, è²ã ã§ãããã ã!!!
èªåãJisonã§, (äºã¶æã»ã©åã«) ä½ã£ããã®ã¯, ããâ
http://itchyny.web.fc2.com/jsparser/
JavaScriptã®ãã¼ãµã¼ãä½ãã¡ãããã ã!!! *1
ã¿ããªãJisonã§éãã§ã¿ãã!!!
楽ããã§ãã!!! ã! ã! ï¼Ïï¼ï¾ï½¼
*1:å®ã¯, æ£è¦è¡¨ç¾å¨ãã§ãµãã£ã¦ããã¨ããããã£ã¦, var x = 1 / 2 / 3; ã¿ãããªå¼ãå¦çã§ãã¾ããorz. ã§ã, ã»ãã³ãã³æ¿å ¥ã®å¦çã¯å²ã¨é å¼µã£ããã, ããã§çãå°½ãã.