编辑: 梦里红妆 2013-10-19

='

expr ;

void assign(根据规则assign生成的方法 match(ID)比较ID和当前输入符号然后消费 match('

='

);

expr(通过调用expr()匹配表达式 } 递归下降语法分析器最酷的部分是通过调用方法prog()、assign()和expr()跟踪出的调用关系图 反映了内部的语法分析树节点.match()的调用对应语法分析树叶子.为了在一个手工构建的 语法分析器中手动构建一颗语法分析树,我们需要在每个规则方法的开始处插入 添加新子树 根 操作,以及给match()一个 添加新叶子节点 操作. 方法assign()只是检查确保所有必要的记号存在且以正确的顺序.当语法分析器进入assign() 时,它不必在多个选项之间进行选择.选项是规则定义右边的选择之一.例如,调用assign的prog规则可能有其它类型的语句. 基本概念

10 /** 匹配起始于当前输入位置的任何语句 */ prog : assign // 第一个选项('

|'

是选项分隔符) | ifstat // 第二个选项 | whilestat ... ;

prog的分析规则看起来像一条switch语句: void prog() { switch ( ?current input token? ) { CASE ID : assign();

break;

CASE IF : ifstat();

break;

// IF是关键字'

if'

的记号类型 CASE WHILE : whilestat();

break;

default : ?raise no viable alternative exception? } } 方法prog()必须通过检查下一个输入记号作出分析决定或预测.分析决定预判哪一个选项将会 成功.在本例中,当看到WHILE关键字时会预判是规则prog的第三个选项.规则方法prog()然 后就会调用whilestat().你以前可能听说过术语预读记号,那只是下一个输入记号.预读记号 可以是语法分析器在匹配和消费它之前嗅探的任何记号. 有时候,语法分析器需要一些预读记号去预判哪个选项会成功.它甚至必须考虑从当前位置 直到文件结尾的所有的记号!ANTLR默默地为你处理所有的这些事情,但是对决策过程有个 基本的了解是有帮助的,可以让调试生成的语法分析器更容易. 为更好地理解分析决定,想象有个单一入口和单一出口的迷宫,有单词写在地板上.每个沿 着从入口到出口路径的单词序列表示一个句子.迷宫的结构与定义一门语言的语法规则类 似.为测试一个句子在一门语言中的成员身份,我们在穿越迷宫时把句子的单词和沿着地板 的单词作比较.如果通过句子的单词我们能到达出口,那么句子是有效的. 为了通过迷宫,我们必须在每个岔口选择一条有效路径,正如我们必须在语法分析器中选择 选项.我们必须决定该走哪条路,通过把我们句子中下一个单词(们)和沿着来自每个岔口 的每条路径上可见的单词比较.我们能从岔口看到的单词与预读记号类似.当每条路径以唯 一的单词开始时决定是相当容易的.在规则prog中,每个选项从唯一的记号开始,因此prog() 可以通过查看第一个预读记号识别选项. 当单词从一个岔口重叠部分开始每条路径时,语法分析器需要继续往前看,扫描可以识别选 项的单词.ANTLR根据需要为每个决定自动上下调节预读数量.如果预读的结果是多条同样 的到出口的路径,即当前的........

下载(注:源文件不在本站服务器,都将跳转到源网站下载)
备用下载
发帖评论
相关话题
发布一个新话题