快速业务通道

一个简单的语言的语法(二):ANTLR的重写规则 - 编程入门网

作者 佚名技术 来源 NET编程 浏览 发布时间 2012-06-14
edence规则所生成的树;而如果匹配到了op运算符,则每匹配到一次就生成一个新的 以op为根节点的、前后两个较低优先级的表达式节点为子节点的树。

这个树改写规则如果要显式指定,就得写成:

Java代码

exprWithHigherPrecedence
  : exprWithLowerPrecedence
      ( op exp=exprWithLowerPrecedence
          -> ^( op $exprWithHigherPrecedence $exp )
      )*
  ;

后者相比之下麻烦多了,所以一般都会使用前者。

可惜C风格的变量声明语句的语法很麻烦,结果variableDeclaration在修改后膨胀了好多 T T

最不爽的地方就是C风格的数组变量声明是把数组的维度写在变量名后面的。这就使得语句开头的类型 (例如int、char等)可能只是变量的实际类型的一部分,而另一部分要在变量名的之前(例如表示指针 的星号(''*''))或之后(例如表示数组的方括号(''['' '']''))。

就不能把整个类型写在一起么……T T 于是衍生出来的Java和C#明显都吸取了这个教训。

在语法的program规则中,我们添加了一条嵌入语法动作,让生成的解析器在匹配完program规则后将 其对应的抽象语法树以字符串的形式输出出来。

如果是在ANTLRWorks里编辑该语法文件,可以在菜单里选择Generate -> Generate Code来生成出 解析器的源码。这里例子中我们会得到JerryLexer.java和JerryParser.java。

一个简单的语言的语法(二):ANTLR的重写规则(4)

时间:2011-10-07 javaeye RednaxelaFX

要运行这个解析器,还需要写一个简单的启动程序来调用生成出来的JerryLexer和JerryParser。源码 如下:

TestJerry.java

Java代码

import org.antlr.runtime.*;

public class TestJerry {
    public static void main(String[] args) throws Exception {
        // Create an input character stream from standard in
        ANTLRInputStream input = new ANTLRInputStream(System.in);
        // Create an JerryLexer that feeds from that stream
        JerryLexer lexer = new JerryLexer(input);
        // Create a stream of tokens fed by the lexer
        CommonTokenStream tokens = new CommonTokenStream(lexer);
        // Create a parser that feeds off the token stream
        JerryParser parser = new JerryParser(tokens);
        // Begin parsing at rule prog
        parser.program();
    }
}

它指定从标准输入流得到要解析的Jerry代码,然后通过JerryLexer将代码解析成token流,再将token 流叫给JerryParser进行句法分析。

将JerryLexer.java、JerryParser.java和TestJerry.java放在跟ANTLRWorks同一目录下,然后编译它 们:

引用

javac -Xlint:unchecked -cp antlrworks-1.2.2.jar JerryLexer.java JerryParser.java 

TestJerry.java

(因为ANTLRWorks里含有ANTLR的运行时库,而我正好又是用ANTLRWorks来编辑语法文件的,所以直接 用ANTLRWorks的JAR包放在classpath里来得到需要的ANTLR运行时类。实际开发的话可以从ANTLR官网获得 只含有ANTLR运行时库的JAR包并在编译和运行的时候将其添加到classpath里。)

上一篇的最后有这样的一段Jerry例子:

C代码

// line comment
// declare variables with/without initializers
int i = 1, j;
int x = i + 2 * 3 - 4 / ( 6 - - 7 );
int array[2][3] = {
  { 0, 1, 2 },
  { 3, 4, 6 }
};

/*
  block comment
*/

while (i < 10) i = i + 1;
while (!x > 0 && i < 10) {
  x = x - 1;
  if (i < 5) break;
  else read i;
}

write x - j;

(语法是符合要求的,至于代码的意义就别追究了,只是用来演示各种语法结构随便

凌众科技专业提供服务器租用、服务器托管、企业邮局、虚拟主机等服务,公司网站:http://www.lingzhong.cn 为了给广大客户了解更多的技术信息,本技术文章收集来源于网络,凌众科技尊重文章作者的版权,如果有涉及你的版权有必要删除你的文章,请和我们联系。以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢!

分享到: 更多

Copyright ©1999-2011 厦门凌众科技有限公司 厦门优通互联科技开发有限公司 All rights reserved

地址(ADD):厦门软件园二期望海路63号701E(东南融通旁) 邮编(ZIP):361008

电话:0592-5908028 传真:0592-5908039 咨询信箱:web@lingzhong.cn 咨询OICQ:173723134

《中华人民共和国增值电信业务经营许可证》闽B2-20100024  ICP备案:闽ICP备05037997号