我想可视化一个语法文件(实际上是咖啡脚本的Jison语法)。所以输入文件是一个 Bison/Yacc 风格的语法文件。预期的输出可能是 Graphviz 点文件或类似文件。
我不一定要寻找完整的 IDE,例如GOLD。但是能够处理 LALR 输入很重要,这就是为什么优秀的ANLTRWorks没有考虑在内的原因。
我还检查了Wikipedia 上的解析器比较,但它仅包括 IDE 支持,但不包括可视化。
这是我真正想要可视化的咖啡脚本语法文件。
我想可视化一个语法文件(实际上是咖啡脚本的Jison语法)。所以输入文件是一个 Bison/Yacc 风格的语法文件。预期的输出可能是 Graphviz 点文件或类似文件。
我不一定要寻找完整的 IDE,例如GOLD。但是能够处理 LALR 输入很重要,这就是为什么优秀的ANLTRWorks没有考虑在内的原因。
我还检查了Wikipedia 上的解析器比较,但它仅包括 IDE 支持,但不包括可视化。
这是我真正想要可视化的咖啡脚本语法文件。
以下是创建语法图的说明。
grammar.coffee的内容是可执行代码,必须运行才能获得真正的 Jison 语法。在将 Jison 调用替换为 Javascript 警报后,我使用Try CoffeeScript页面对其进行编译。然后运行生成的 Javascript 以获取语法,如下所示:
{
"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 语法转换器,得到这样的语法:
Root ::= ( Body | Block TERMINATOR )?
Body ::= Line ( TERMINATOR Line | TERMINATOR )*
Line ::= Expression
| Statement
...
从这里我们可以让铁路图生成器创建一个语法图:
. . .
请注意,转换器仅评估语法的“bnf”部分,因此它不考虑标记定义。这可以通过对 W3C 风格的语法进行一些手动后处理来改进。
所以我再次尝试并立即发现了我最明显的错误——我发布的 json 错误地使用了单引号而不是双引号。让我详细说明工作流程;这很简单,如果你已经在 NodeJS 上运行 CoffeeScript,你就可以开始了:
node_modules/coffee-script/lib/coffee-script/grammar.js
在文件系统中找到模块;
将该文件的代码复制并粘贴到js2coffee站点上的 js->coffee 窗格的源窗格中 (您可以跳过它,但我发现编辑 CS 比摆弄 JS 更合适)。
将翻译后的代码保存到node_modules/coffee-script/lib/coffee-script/grammar.coffee
;
去定位
exports.parser = new Parser(
tokens: tokens.join(" ")
bnf: grammar
operators: operators.reverse()
startSymbol: "Root"
)
在代码中;将其替换为
console.log JSON.stringify
tokens: tokens.join " "
bnf: grammar
operators: operators.reverse()
startSymbol: "Root"
同时注意使用完全相同的缩进(第一行两个空格,其余四个空格)。
从命令行,运行 sth like coffee node_modules/coffee-script/lib/coffee-script/grammar.coffee > /tmp/coffee.grammar
;
将生成的文件的代码复制并粘贴到语法转换器中;
将生成的 EBNF 语法从转换器复制并粘贴到铁路图生成器的语法编辑器中;
转到“查看图表”选项卡,然后 — 高兴!
做所有这些复制'n'pastish 的东西是一件苦差事,但对于任何一次性的可视化来说肯定足够好。我一直在网上搜索一个合理的 RR 图生成器,这个特定的生成器绝对是输出最漂亮的生成器之一。当您想到真正简单的铁路图时,您会感到有些惊讶。