使用MGrammar解析行注释块

时间:2010-06-08 18:36:16

标签: parsing grammar mgrammar

如何用MGrammar解析行注释块?

我想解析一行注释。每个旁边的行注释应分组在MGraph输出中。

我无法将线条评论块分组在一起。我当前的语法使用“\ r \ n \ r \ n”来终止一个块但是在所有情况下都不起作用,例如在文件末尾或我引入其他语法时。

示例输入可能如下所示:

/// This is block
/// number one

/// This is block
/// number two

我目前的语法如下:

module MyModule
{
    language MyLanguage
    {       
        syntax Main = CommentLineBlock*;

        token CommentContent = !(
                                 '\u000A' // New Line
                                 |'\u000D' // Carriage Return
                                 |'\u0085' // Next Line
                                 |'\u2028' // Line Separator
                                 |'\u2029' // Paragraph Separator
                                );   

        token CommentLine = "///" c:CommentContent* => c;
        syntax CommentLineBlock = (CommentLine)+ "\r\n\r\n";

        interleave Whitespace = " " | "\r" | "\n";   
    }
}

1 个答案:

答案 0 :(得分:1)

问题是,你交错了所有的空格 - 所以在解析了令牌并来到词法分析器之后,它们只是“不存在”了。

在您的情况下,CommentLineBlock为syntax,但您需要在tokens中完全使用注释块...

language MyLanguage
{       
    syntax Main = CommentLineBlock*;

    token LineBreak = '\u000D\u000A'
                         | '\u000A' // New Line
                         |'\u000D' // Carriage Return
                         |'\u0085' // Next Line
                         |'\u2028' // Line Separator
                         |'\u2029' // Paragraph Separator
                        ;  

    token CommentContent = !(
                             '\u000A' // New Line
                             |'\u000D' // Carriage Return
                             |'\u0085' // Next Line
                             |'\u2028' // Line Separator
                             |'\u2029' // Paragraph Separator
                            );   

    token CommentLine = "//" c:CommentContent*;
    token CommentLineBlock = c:(CommentLine LineBreak?)+ => Block {c};

    interleave Whitespace = " " | "\r" | "\n";   
}

但问题是,CommentLine中的suboken-rules将不会被处理 - 你可以解析普通的字符串。

Main[
  [
    Block{
      "/// This is block\r\n/// number one\r\n"
    },
    Block{
      "/// This is block\r\n/// number two"
    }
  ]
]

今晚我可能会尝试找到更好的方式: - )