最近在研究把CoffeeScript编译到.Net CLR环境上运行的可能性,在几个CoffeeScript compiler的实现中,没有发现对文法定义的specification,如果要人肉重建不仅工作量忧桑,还有可能导致兼容性问题。于是看了下源代码,发现略施小计就能解决这个问题。
CoffeeScript的Parser使用jison生成的,所有的文法都在grammar.coffee里定义了。这个代码非常好改,去掉对jison的调用,把语法定义用JSON.stringify() format了再输出,执行修改后的代码:1
coffee grammar.coffee
就会得到一大串jison格式的文法定义:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22{
"tokens":" TERMINATOR TERMINATOR TERMINATOR STATEMENT INDENT OUTDENT INDENT OUTDENT IDENTIFIER NUMBER STRING JS REGEX BOOL = = INDENT OUTDENT : : INDENT OUTDENT RETURN RETURN HERECOMMENT PARAM_START PARAM_END -> => , , ... = ... . ?. :: :: INDEX_START INDEX_END INDEX_SOAK { } , TERMINATOR INDENT OUTDENT CLASS CLASS CLASS EXTENDS CLASS EXTENDS CLASS CLASS CLASS EXTENDS CLASS EXTENDS SUPER SUPER FUNC_EXIST CALL_START CALL_END CALL_START CALL_END THIS @ @ [ ] [ ] .. ... [ ] , TERMINATOR INDENT OUTDENT INDENT OUTDENT , TRY TRY TRY FINALLY TRY FINALLY CATCH THROW ( ) ( INDENT OUTDENT ) WHILE WHILE WHEN UNTIL UNTIL WHEN LOOP LOOP FOR FOR FOR OWN , FORIN FOROF FORIN WHEN FOROF WHEN FORIN BY FORIN WHEN BY FORIN BY WHEN SWITCH INDENT OUTDENT SWITCH INDENT ELSE OUTDENT SWITCH INDENT OUTDENT SWITCH INDENT ELSE OUTDENT LEADING_WHEN LEADING_WHEN TERMINATOR IF ELSE IF ELSE POST_IF POST_IF UNARY - + -- ++ -- ++ ? + - MATH SHIFT COMPARE LOGIC RELATION COMPOUND_ASSIGN COMPOUND_ASSIGN INDENT OUTDENT EXTENDS",
"bnf":
{
"Root":
[
["","return $$ = new yy.Block;",null],
["Body","return $$ = $1;",null],
["Block TERMINATOR","return $$ = $1;",null]
],
"Body":
[
["Line","$$ = yy.Block.wrap([$1]);",null],
["Body TERMINATOR Line","$$ = $1.push($3);",null],
["Body TERMINATOR","$$ = $1;",null]
],
"Line":
[
["Expression","$$ = $1;",null],
["Statement","$$ = $1;",null]
],
...
这样已经算是可用了,但可读性依然不高,经过一番搜索发现一个jison-to-w3c文法标记格式的转换器,得到文法:1
Root ::= Body?
Body ::= Line ( TERMINATOR Line | TERMINATOR )*
Line ::= Expression
| Statement
Statement
::= Return
| Comment
| STATEMENT
Expression
::= Value
| Invocation
| Code
| Operation
| Assign
| If
| Try
| While
| For
| Switch
| Class
| Throw
...
最后找到一个可视化文法的网站Railroad Diagram Generator将其可视化,just for fun:
完整的图在:http://project.catx.me/other/coffee-grammar.xhtml
源代码+完整的文法定义:https://gist.github.com/akfish/8827385