惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

SecWiki News
SecWiki News
量子位
The Cloudflare Blog
美团技术团队
T
The Exploit Database - CXSecurity.com
博客园 - 【当耐特】
Spread Privacy
Spread Privacy
P
Proofpoint News Feed
C
CXSECURITY Database RSS Feed - CXSecurity.com
博客园 - 三生石上(FineUI控件)
T
Tor Project blog
博客园 - 司徒正美
宝玉的分享
宝玉的分享
T
Threatpost
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
S
Secure Thoughts
T
Threat Research - Cisco Blogs
Hacker News: Ask HN
Hacker News: Ask HN
Jina AI
Jina AI
博客园 - 聂微东
A
Arctic Wolf
I
Intezer
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
Know Your Adversary
Know Your Adversary
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
爱范儿
爱范儿
Hugging Face - Blog
Hugging Face - Blog
C
Cyber Attacks, Cyber Crime and Cyber Security
小众软件
小众软件
T
Tailwind CSS Blog
The Hacker News
The Hacker News
L
LINUX DO - 最新话题
Hacker News - Newest:
Hacker News - Newest: "LLM"
WordPress大学
WordPress大学
S
SegmentFault 最新的问题
TaoSecurity Blog
TaoSecurity Blog
Project Zero
Project Zero
博客园 - 叶小钗
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
Cloudbric
Cloudbric
雷峰网
雷峰网
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
大猫的无限游戏
大猫的无限游戏
D
Darknet – Hacking Tools, Hacker News & Cyber Security
T
Troy Hunt's Blog
酷 壳 – CoolShell
酷 壳 – CoolShell
V2EX - 技术
V2EX - 技术
The GitHub Blog
The GitHub Blog
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
P
Privacy & Cybersecurity Law Blog

博客园 - Bang

在Windows使用VC编译ICU (基于Java)编写编译器和解释器-第11章:解析程序、过程和函数-第二部分 (基于Java)编写编译器和解释器-第11章:解析程序、过程和函数-第一部分 (基于Java)编写编译器和解释器-第10章:类型检查-第二部分 install Wireless driver on OpenSuse 12.2 (基于Java)编写编译器和解释器-第10章:类型检查-第一部分 (基于Java)编写编译器和解释器-第9章:解析声明-第三部分(连载) 自动化运维体系下的Agent概念,场景及实现 将Java封装成Windows Service并添加启动托盘(Tray) (基于Java)编写编译器和解释器-第9章:解析声明-第二部分(连载) (基于Java)编写编译器和解释器-第9章:解析声明-第一部分(连载) (基于Java)编写编译器和解释器-第8章:解释Pascal控制语句(连载) (基于Java)编写编译器和解释器-第7章:解析(Parsing)控制语句-第二部分(连载) (基于Java)编写编译器和解释器-第7章:解析(Parsing)控制语句-第一部分(连载) (基于Java)编写编译器和解释器-第6章:解释执行表达式和赋值语句(连载) (基于Java)编写编译器和解释器-第5A章:基于Antlr解析表达式和赋值语句及计算(连载) (基于Java)编写编译器和解释器-第5章:解析表达式和赋值语句-第二部分(连载) (基于Java)编写编译器和解释器-第5章:解析表达式和赋值语句-第一部分(连载) (基于Java)编写编译器和解释器-第4章:符号表(连载)
(基于Java)编写编译器和解释器-第8A章:基于Antlr解析&解释执行Pascal控制语句(连载)
Bang · 2012-07-29 · via 博客园 - Bang

在第7,8章我们分别学习了Pascal控制语句的解析,解释执行,还涉及到了一点点优化,虽然好像花的时间不多,但是用Antlr之后就会发现还是很啰嗦。Antlr对于编译器作者来说,或许不是性能最好的,但是对于语言前期的论证,运行时原型的快速构建都有非常重要意义,尤其语法较多(也就是EBNF Rule条数很多)。更进一步说,即使有很多优化,Antlr的源代码和代码生成(Codegen)这一块完全可以定制。我们可以在语言,运行时稳定之后来个手写版:)。好了,废话不多说了,先看控制语句的语法。

==>> 本章中文版源代码下载:svn co http://wci.googlecode.com/svn/branches/ch8_antlr/ 源代码使用了UTF-8编码,下载到本地请修改!

控制语句的语法

这几个控制语句,FOR最复杂,CASE其次,下面的语法描述严格遵循第7章的分析树显示。

   1: statement:
   2:   compound_statement | assignment_statement | control_statement;
   3: control_statement:
   4:   while_statement | repeat_statement | for_statement | if_statement | case_statement;
   5: while_statement:
   6:   WHILE t1=expression DO s1=statement ->^(LOOP ^(NOT $t1) $s1);
   7: repeat_statement:
   8:   REPEAT s1=statement_list UNTIL t1=expression ->^(LOOP $s1 $t1);
   9: for_statement 
  10: @init{
  11:   PascalNode id_node = null;
  12:   PascalNode id_cp1=null;
  13:   PascalNode id_cp2=null;
  14:   PascalNode id_cp3=null;
  15:   PascalNode op_node=null;
  16:   boolean increment = true;
  17:   PascalNode one_constant = (PascalNode)adaptor.create(NUMBER,"1");
  18:   ((PascalAntlrToken)one_constant.getToken()).setValue(new Integer(1));
  19: }:
  20:   (FOR a1=assignment_statement {
  21:           id_node =(PascalNode) ((PascalNode)a1.getTree()).getChild(0); 
  22:           id_cp1 = (PascalNode)id_node.dupNode(); 
  23:           id_cp2=  (PascalNode)id_node.dupNode();
  24:           id_cp3=  (PascalNode)id_node.dupNode();
  25:          }
  26:     (TO{op_node=(PascalNode) adaptor.create(PLUS,"+");} | DOWNTO{increment=false;op_node=(PascalNode) adaptor.create(MINUS,"-");}) 
  27:         q=(e11=expression->{increment}?^(GT {id_cp1} $e11)->^(LT {id_cp1} $e11))
  28:               DO s2=statement) ->^(COMPOUND $a1 ^(LOOP ^(TEST $q) $s2 ^(ASSIGN {id_cp2} ^({op_node} {id_cp3} {one_constant}))));
  29: if_statement:
  30:   IF t1=expression THEN s1=statement ((ELSE)=>ELSE s2=statement)? -> ^(IF $t1 $s1 $s2?);
  31: case_statement:
  32:   CASE e1=expression OF bhs=case_branches END ->^(SELECT $e1 $bhs);
  33: case_branches:
  34:   case_branch (SEMI case_branch)* SEMI? -> case_branch+;
  35: case_branch:
  36:   c1=constant_list COLON s1=statement ->^(SELECT_BRANCH $c1 $s1);
  37: constant_list:
  38:   constant(COMMA constant)* -> ^(SELECT_CONSTANTS constant+);
  39: constant:
  40:   NUMBER | NUMBER_REAL | STRING;

这个语法有几个地方要说明一下:

  • 第1行:在语句的集合里面加入5个控制语句
  • 第10行:Antlr的Rule Action,一般有@init和@@after,@init表示在rule代码生成前插入代码,@after表示rule代码生成后插入的代码。
  • 第22行到28行:我们分别使用了语义预测(Semantic Predication)嵌套的Antlr Rewrite(重写功能)。
  • 第30行:针对"dangling else"的情况使用了语法预测(Syntax Predication)。在"ElSE"后使用=>的语法预测表示如果发现ELSE,马上在同一条规则内解析接下来的语句,即贪婪型解析法。

如果使用了如下的"foo.txt"进行语法树构建

   1: BEGIN {FOR statements}
   2:     j := 1;
   3:  
   4:     FOR k := j TO 5 DO n := k;
   5:  
   6:     FOR k := n DOWNTO 1 DO j := k;
   7:  
   8:     FOR i := 1 TO 2 DO BEGIN
   9:         FOR j := 1 TO 3 DO BEGIN
  10:             k := i*j
  11:         END
  12:     END
  13: END.

那么Antlr生成的分析树图形将会是(图太大,只截取后面两个循环的):

image

控制语句的语义(即解释执行)