可视化LALR语法

时间:2011-11-16 16:08:34

标签: coffeescript visualization graphviz lalr

我想想象一个语法文件(实际上是咖啡脚本的Jison语法)。因此输入文件是Bison / Yacc样式的语法文件。预期的输出可能是Graphviz点文件或类似的东西。

我不一定在寻找一个完整的IDE,比如GOLD。但是能够处理LALR输入很重要,这就是为什么不考虑优秀的ANLTRWorks

我还检查了comparison of parsers on Wikipedia,但它仅包含IDE支持,但不包括可视化。

这是我想要实现的coffeescript grammar file

2 个答案:

答案 0 :(得分:12)

以下是创建语法图的说明。

grammar.coffee的内容是可执行代码,必须运行该代码才能获得实际的Jison语法。在用Javascript警报替换了Jison调用之后,我使用了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 grammar converter 在这样的语法中:

Root     ::= ( Body | Block TERMINATOR )?
Body     ::= Line ( TERMINATOR Line | TERMINATOR )*
Line     ::= Expression
           | Statement
...

从这里我们可以让Railroad Diagram Generator创建一个语法图:

CoffeeScript Syntax Diagram

。 。

请注意,转换器仅评估语法的“bnf”部分,因此不考虑令牌定义。这可以通过对W3C样式语法进行一些手动后处理来改进。

答案 1 :(得分:0)

所以我再次尝试,发现我最明显的错误 - 我发布的json错误地使用单引号而不是双引号。让我详细说明工作流程;这很简单,如果您已经在NodeJS上运行CoffeeScript,那么您已经准备好了:

  • 在文件系统中找到node_modules/coffee-script/lib/coffee-script/grammar.js模块;

  • copy&amp;将该文件的代码粘贴到js2coffee网站上js-&gt;咖啡窗格的源窗格中(您可以跳过它,但我发现编辑CS比编写JS更加友好)。< / p>

  • 将已翻译的代码保存到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"
    

    同时注意使用完全相同的缩进(第一行有两个空格,其余为四个空格)。

  • 从命令行运行,如coffee node_modules/coffee-script/lib/coffee-script/grammar.coffee > /tmp/coffee.grammar;

  • 将生成的文件的代码复制并粘贴到the grammar converter;

  • 将生成的EBNF语法从转换器复制并粘贴到railroad diagram generator上的语法编辑器中;

  • 转到View Diagram选项卡,然后 - 欢喜!

完成所有这些copy'n'pastish的东西是一件苦差事,但对于任何一次性可视化来说肯定是足够好的。我一直在网上搜索一个合理的RR图生成器,这个特别的一个肯定是具有最漂亮输出的那个。当你想到铁路图的真实性时,会有些惊讶。