王朝网络
分享
 
 
 

ANTLR(语言识别的另一工具)的简介之二[翻译]

王朝other·作者佚名  2006-01-08
宽屏版  字体: |||超大  

亲和的ANTLR语法的介绍

通过例子来逐渐学习ANTLR是最好的。 一个简单计算器常被用来入门,原因很简单:它简单易懂。这有许多给ANTLR的相似例子和教程,但是我会使用我自己的语言来描述一个计算器。首先我们会创建一些可以直接对简单表达式求值的程序。然后,我会生成树结构,并计算这些树来得到同样的答案。

当你知道最终你需要将一个字符输入流分解成多个记号时,则好的开始就是去思考一个表达式的文法结构。

语法向导执行

语言识别

我们接受了包含+,-和*的算术表达式,如3+4*5-1,或是可以增强求值顺序的括号表达式,如(3+4)*5。

全部ANTLR语法都是lexer,语法解析程序和语法树解析程序的子类。既然你应该开始在文法层面思考问题,你因该创建一个文法解析程序的子类。在类的声明之后,你可以使用扩展巴柯斯范式符号指定规则:

class ExprParser extends Parser;

expr: mexpr ((PLUS|MINUS) mexpr)*

;

mexpr

: atom (STAR atom)*

;

atom: INT

| LPAREN expr RPAREN

;

lexer遵从相似的模式,它只需要定义一些操作符和空白符。把lexer放进相同的文件,如expr.g,是要做的最容易的事情:

class ExprLexer extends Lexer;

options {

k=2; // needed for newline junk

charVocabulary='\u0000'..'\u007F'; // allow ascii

}

LPAREN: '(' ;

RPAREN: ')' ;

PLUS : '+' ;

MINUS : '-' ;

STAR : '*' ;

INT : ('0'..'9')+ ;

WS : ( ' '

| '\r' '\n'

| '\n'

| '\t'

)

{$setType(Token.SKIP);}

;

从这个语法定义文件expr.g生成程序(Java),可以运行ANTLR如下:

$ java antlr.Tool expr.g

ANTLR Parser Generator Version 2.7.2 1989-2003 jGuru.com

$

ANTLR 产生什么?

当发现没有必要完成这个教程时,你可能看到ANTLR在识别程序文件里面生成了什么,并发现这很有启发。ANTLR生成了识别程序,这些程序模拟你通过手工递归下推的语法分析程序来创建的东西;而另一方面,yacc及其朋友在模拟下推自动机的时候生成满是整形数的表。

ANTLR 将产生下列文件:

ExprLexer.java

ExprParser.java

ExprParserTokenTypes.java

ExprParserTokenTypes.txt

如果你看一下里面的内容,比如ExprParser.java,你会看到它为文件expr.g中有解析语法定义的每条规则生成一个方法。比如,mexpr合atom规则的代码看起来类似如下代码:

public void mexpr() {

atom();

while ( LA(1)==STAR ) {

match(STAR);

atom();

}

}

public void atom() {

switch ( LA(1) ) { // switch on lookahead token type

case INT :

match(INT);

break;

case LPAREN :

match(LPAREN);

expr();

match(RPAREN);

break;

default :

// error

}

}

注意到规则定义被翻译成了方法调用,而记号定义则被译成match(TOKEN)函数调用。则关于创建一种语法parser中仅有的难事就是计算前瞻信息。

记号类别类定义了你的词法分析程序(lexer)和parser所使用到的所有记号类别数字常量:

// $ANTLR 2.7.2: "expr.g" -> "ExprParser.java"$

public interface ExprParserTokenTypes {

int EOF = 1;

int NULL_TREE_LOOKAHEAD = 3;

int PLUS = 4;

int MINUS = 5;

int STAR = 6;

int INT = 7;

int LPAREN = 8;

int RPAREN = 9;

int WS = 10;

}

测试lexer/parser

为了在实际中使用在ExprParser.java中作为结果的parser,须像如下所示来使用main()函数:

import antlr.*;

public class Main {

public static void main(String[] args) throws Exception {

ExprLexer lexer = new ExprLexer(System.in);

ExprParser parser = new ExprParser(lexer);

parser.expr();

}

}

$ java Main

3+(4*5)

$

给错误的输入:

$ java Main

3++

line 1:3: unexpected token: +

$

或者

$ java Main

3+(4

line 1:6: expecting RPAREN, found 'null'

$

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
>>返回首页<<
推荐阅读
 
 
频道精选
 
静静地坐在废墟上,四周的荒凉一望无际,忽然觉得,凄凉也很美
© 2005- 王朝网络 版权所有