Java ANTLR的基本帮助

Java ANTLR的基本帮助,java,antlr,parser-generator,Java,Antlr,Parser Generator,我正在尝试创建一个解析器,它可以将跨语言的英语句子在画布上绘制成图形。例如: “创建一个红色方框”应该在画布上创建一个红色方框 我从你的维基教程中找到了这个语法文件。不知道是否正确,如果有人能检查一下就好了=) 然后我使用这段代码来生成lexer和解析器。我的下一步是什么。例如,如何使用解析器将“创建”转换为对象的创建。有人能给我指出正确的方向吗 由于WS规则中的{skip();},您的lexer将永远不会创建任何WS标记。因此,包含WS的解析器规则,如语句规则,将永远不会匹配。从这个意义上说,

我正在尝试创建一个解析器,它可以将跨语言的英语句子在画布上绘制成图形。例如: “创建一个红色方框”应该在画布上创建一个红色方框

我从你的维基教程中找到了这个语法文件。不知道是否正确,如果有人能检查一下就好了=)

然后我使用这段代码来生成lexer和解析器。我的下一步是什么。例如,如何使用解析器将“创建”转换为对象的创建。有人能给我指出正确的方向吗

由于
WS
规则中的
{skip();}
,您的lexer将永远不会创建任何
WS
标记。因此,包含
WS
的解析器规则,如
语句
规则,将永远不会匹配。从这个意义上说,你的语法是错误的

理查德写道:

创建一个对象

编辑 您可以为解析器提供自定义属性,例如要在其上绘制的
图形
对象(请参阅下面语法的
@parser::members{…}
部分)。并在
{
}
之间的语法规则中嵌入自定义代码。作为一个演示,我只添加了一些
System.out.println
,当然,你应该用你的实际绘画来替换它们。我还从解析器规则中删除了
WS
标记(还要注意
Create
不等于
Create
!)

修改后的语法:

grammar Shrdlu;

tokens {

    //operational tokens
    MOVE        = 'move';
    TRANSFORM   = 'transform';
    CREATE      = 'create';
    MAKE        = 'make';
    ADD         = 'add';
    REMOVE      = 'remove';
    DELETE      = 'delete';

    //shape tokens
    BOX         = 'box';
    RECTANGLE   = 'rectangel';
    CIRCLE      = 'circle';
    TRIANGLE    = 'triangle';
    SHAPE       = 'shape';
    SQUARE      = 'square';

    //color tokens
    RED         = 'red';
    BLUE        = 'blue';
    GREEN       = 'green';
    BLACK       = 'black';
    PURPLE      = 'purple';
    YELLOW      = 'yellow';
    ORANGE      = 'orange';
    PINK        = 'pink';

    //size tokens
    BIG         = 'big';
    LARGE       = 'large';
    TALL        = 'tall';
    SMALL       = 'small';
    TINY        = 'tiny';
    SHORT       = 'short';

    //relation size
    BIGGEST     = 'biggest';
    LARGEST     = 'largest';
    TALLEST     = 'tallest';
    SMALLEST    = 'smallest';   
    SHORTEST    = 'shortest';

    //argument size
    BIGGER      = 'bigger';
    SMALLER     = 'smaller';
    SHORTER     = 'shorter';
    TALLER      = 'taller';
    LARGER      = 'larger';

    //alignment tokens
    LEFT        = 'left';
    RIGHT       = 'right';
    OVER        = 'over';
    UNDER       = 'under';
    ABOVE       = 'above';
    BELOW       = 'below';
    TOP         = 'top';
    BOTTOM      = 'bottom';

    //prefix tokens
    A           = 'a';
    AN          = 'an';
    ALL         = 'all';
    ANY         = 'any';
    EACH        = 'each';
    THE         = 'the';

}

@parser::members {

  private java.awt.Graphics graphics;

  public ShrdluParser(TokenStream tokens, java.awt.Graphics g) {
    super(tokens);
    graphics = g;
  }
}

/*------------------------------------------------------------------
 * PARSER RULES
 *------------------------------------------------------------------*/

command
    :   sentence EOF
    |
    ;

sentence
    :   action object argument?
    ;

action

    :   MOVE
    |   TRANSFORM
    |   CREATE    {System.out.println("I should create a ...");}
    |   MAKE
    |   ADD
    |   REMOVE
    |   DELETE
    ;

object
    :   prefix property?  shape (relation object)?
    ;

argument
    :   color
    |   sizearg
    |   alignment
    ;

prefix
    :   A
    |   AN
    |   ALL
    |   ANY
    |   EACH
    |   THE
    ;

shape
    :   BOX       {System.out.println("box ...");}
    |   RECTANGLE
    |   CIRCLE
    |   TRIANGLE
    |   SHAPE
    |   SQUARE
    ;

property
    :   size property?
    |   color property?
    ;


size
    :   BIG
    |   LARGE
    |   TALL
    |   SMALL
    |   TINY
    |   SHORT
    ;

sizearg
    :   BIGGER
    |   LARGER
    |   SMALLER
    |   TALLER
    |   SHORTER 
    ;

relsize
    :   BIGGEST
    |   SMALLEST
    |   TALLEST
    |   LARGEST
    ;   


relation
    :   alignment
    |   relsize
    ;

color
    :   RED   {System.out.println("red ...");}
    |   BLUE
    |   GREEN
    |   BLACK
    |   PURPLE
    |   YELLOW
    |   ORANGE
    |   PINK
    ;

alignment
    :   LEFT
    |   RIGHT
    |   OVER
    |   UNDER
    |   ABOVE
    |   BELOW
    |   TOP
    |   BOTTOM
    ;

NEWLINE
    :   '\r'? '\n'
    ;

WS
    :   (' '|'\t'|'\n'|'\r')+ {skip();}
    ;
可通过以下类别进行测试:

import org.antlr.runtime.*;

public class Main {
    public static void main(String[] args) throws Exception {
        ANTLRStringStream in = new ANTLRStringStream("create a red box");
        ShrdluLexer lexer = new ShrdluLexer(in);
        CommonTokenStream tokens = new CommonTokenStream(lexer);
        java.awt.Graphics g = null;
        ShrdluParser parser = new ShrdluParser(tokens, g);
        parser.command();
    }
}
根据语法创建lexer和parser:

java -cp antlr-3.3.jar org.antlr.Tool Shrdlu.g 并运行主类:

# *nix java -cp .:antlr-3.3.jar Main # Windows java -cp .;antlr-3.3.jar Main #*尼克斯 java-cp.:antlr-3.3.jar Main #窗户 java-cp。;antlr-3.3.jar Main 将生成以下输出:

I should create a ... red ... box ... 我应该创造一个。。。 红色 盒子。。。
最后一件事是,您可能可以删除
换行规则:您的
WS
规则捕获这些字符(并忽略它们)。

下一步应该是创建一个AST并遍历它,以便在查找节点时采取措施

嗯,(对我来说)解释如何继续这本书有点困难,但我强烈建议你买这本由Antll作者写的书。它清楚地描述了如何进行


我希望这能有所帮助。

对于这样一种简单的语言,我认为没有必要使用AST。从Richard描述的语言中创建一些有意义的输出,可以使用“语法定向解释器”来完成。因此,可以在解析器规则中简单地混合一些自定义代码来动态解释解析的源代码,而不需要AST。语言实现模式中的模式24提到了这样一种技术。画布控件应在其上绘制一个红色框:) # *nix java -cp .:antlr-3.3.jar Main # Windows java -cp .;antlr-3.3.jar Main I should create a ... red ... box ...