如何使用JJTree实现给定语法的AST

时间:2019-03-07 10:43:44

标签: grammar javacc

我试图实现从LaTeX到HTML的解析器,以完成我的练习,我需要编写JavaCC语法,生成Abstract语法树,并实现访问者来解析代码。

我已经编写了.jj语法文件,现在我对如何使用jjtree生成基于语法文件的AST感到困惑。有人可以帮助我吗? 如果可以的话,这是我的语法文件。

ArrayList<LaTeXObject> LaTeX() :
{
    ArrayList<LaTeXObject> objects;
}
{
    objects = ObjectList() <EOF>

    {
        return objects;
    }
}

ArrayList<LaTeXObject> ObjectList() :
{
    ArrayList<LaTeXObject> objects = new ArrayList<LaTeXObject>();

    LaTeXObject object;
}
{
    ( object = Object() { objects.add(object); } )*

    {
        return objects;
    }
}

LaTeXObject Object() :
{
    LaTeXObject object;
}
{
    (
        object = Command()
        |
        object = Group()
        |
        object = String()
    )

    {
        return object;
    }
}

LaTeXCommand Command() :
{
    String name;
}
{
    <BACKSLASH>
    (
        name = Name() Whitespace()
        |
        name = SpecialCharacter()
        |
        name = NonSpecialCharacter()
    )

    {
        return new LaTeXCommand(name);
    }
}

String Name() :
{
    StringBuilder sb = new StringBuilder();

    Token token;
}
{
    token = <ASCII_LETTER> { sb.append(token.image); } ( LOOKAHEAD( <ASCII_LETTER> ) token = <ASCII_LETTER> { sb.append(token.image); } )*

    {
        return sb.toString();
    }
}

void Whitespace() :
{}
{
    ( LOOKAHEAD( WhitespaceCharacter() ) WhitespaceCharacter() )*
}

String WhitespaceCharacter() :
{
    Token token;
}
{
    token = <WHITESPACE>

    {
        return token.image;
    }
}

String SpecialCharacter() :
{
    Token token;
}
{
    (
        token = <BACKSLASH>
        |
        token = <LBRACE>
        |
        token = <RBRACE>
        |
        token = <SPECIAL>
    )

    {
        return token.image;
    }
}

String NonSpecialCharacter() :
{
    Token token;
}
{
    token = <NON_SPECIAL>

    {
        return token.image;
    }
}

LaTeXGroup Group() :
{
    ArrayList<LaTeXObject> objects;
}
{
    <LBRACE> objects = ObjectList() <RBRACE>

    {
        return new LaTeXGroup(objects);
    }
}

LaTeXString String() :
{
    StringBuilder sb = new StringBuilder();
    String string;
}
{
    string = TextCharacter() { sb.append(string); } ( LOOKAHEAD( TextCharacter() ) string = TextCharacter() { sb.append(string); } )*

    {
        return new LaTeXString(sb.toString());
    }
}

String TextCharacter() :
{
    Token token;
}
{
    (
        token = <WHITESPACE>
        |
        token = <NON_SPECIAL>
        |
        token = <SPECIAL> 
        |
        token = <ASCII_LETTER>
        |
        token = <ASCII_DIGIT>
        |
        token = <LATIN_SUPPLEMENT>
        |
        token = <UNICODE_LETTER>
    )

    {
        return token.image;
    }
}

1 个答案:

答案 0 :(得分:0)

因此,您现在所拥有的确实构建了一个抽象语法树。如果对此感到满意,则根本不需要JJTree。

如果您真的想使用JJTree,则应该删除所有构成LatexObject对象的代码。只要使所有非终端产品返回void。还将文件从.jj重命名为.jjt。现在,以您的.jjt文件作为输入运行JJTree。低下,您将看到一个新的.jj文件,该文件将构建一个抽象语法树。现在摆弄.jjt文件,直到它产生的抽象语法树成为您满意的树为止。