感觉语法分析器在编译器前端是一个较为庞大的东西,因此打算分两篇博客来描述,第一篇着重描述思想,第二篇具体论述实现。

1、语法分析器要做什么

在编写任何一个东西的的时候,都要先弄明白这个玩意儿是做什么的,接受什么输入,产生什么输出。

一个语法分析器要接受词法分析器所产生的词素作为输入,产生一个抽象语法树给中间代码生成器,然后再由中间代码生成器生成中间代码并递交给编译器后端。当然在某些理解中可以把抽象语法树就当做是一种中间代码的表示形式,直接递交给后端。不管怎么说,总之就是语法分析器是一个生成抽象语法树的东西。

值得注意的是,语法分析器不仅要生成抽象语法树,而且还要在这个生成过程中找出各种语法错误并生成和维护符号表。

2、符号表

什么是符号表?符号表有什么用?

所谓符号表就是一个记录各种标识符(也就是终结符号id,词素id)及其属性的表,比如记录一个int变量x的类型为int,它的作用域,记录一个函数名,记录其函数类型,参数列表等。

符号表有作用域,比如一段简单的代码:

public void function()
{
int i=0;
while(true)
{
int i=1;
}
}

因此一个符号表的构造一定是一个树状结构,我们在编译器中用以下结构来描述一个符号表:

package ravaComplier.symTable;
import java.util.*;
public class SymTable {
private SymTable fatherSymTable;
private ArrayList<SymTable> blockSymTables;
private HashMap<String,Symbol> table;
private String blockid;
public SymTable(SymTable st,String str)
{
fatherSymTable=st;
blockid=str;
blockSymTables=new ArrayList<SymTable>();
table=new HashMap<String,Symbol>();
}
public void addSym(Symbol sym)
{
table.put(sym.id, sym);
}
public Symbol getSym(String id)
{
Symbol result=table.get(id);
if(result==null && fatherSymTable!=null)
{
return fatherSymTable.getSym(id);
}
return result;
}
public void addSymTable(SymTable st)
{
blockSymTables.add(st);
}
}

代码很简单以至于注释都懒得写了。

通过fatherSymTable来记录此符号表的父表,用于不断的向上回溯查找符号(getSym)使用。
blockid算是给此表一个id,用于打印调试信息时使用。
addSym在此表增加符号。除此之外还有个addSymTables来加入子表。
另外此类还重载了toString()方法,用于debug信息,限于篇幅这个方法没贴到博客里,可在我上传的资源里拿到完整的源文件。
也许在之后的分析描述写代码的过程中我会发现需要给这个类添加新的函数,到那时再对此类进行补充。
接下来看看简单的Symbol类,也就是表示一个符号的类:

package ravaComplier.symTable;
public class Symbol {
public String id;
public int type;
public Object value;
public Symbol(String i,int t,Object v)
{
id=i;
type=t;
value=v;
}
public static int TYPE_CLASSNAME=0;
public static int TYPE_MEMBERVAR=1;
public static int TYPE_LOCALVAR=2;
public static int TYPE_FUNCNAME=3;
public static int TYPE_CONSFUNC=4;
}

分为3个域,id,也就是标识符,type,枚举值已列出,value,根据不用的枚举值定义了不同的value,之后若用到了再贴代码吧。
总共分为5类符号:类名、成员变量、局部变量、函数名和构造函数名。
当然若之后根据需要,或许会使用新的符号也可以灵活的添加。

3、语法树的表示
一棵语法树不能使用普通的树结构因为每个不同的节点的行为、值太多且不同。语法树中的节点为非终结符号或者终结符号,对于其中的id,我们就让它指向符号表中的符号即可,对于非终结符号,每个非终结符号我们都建立一个新的类来描述其行为,对于非id的终结符号,其信息要么不记录(比如无意义的分好括号等),要么简单记录其类型(比如各种运算符)。
所以这种情况下每一个节点的建立都比较灵活,下面举两个例子:
对于产生式:ops --> bitop | logiop | artmop | cprop
我们建立如下的类来描述ops:

package ravaComplier.syntax.nodes;
public class ops {
private int type;
private Object value; //must be bitop,logiop,artmop,cprop
public ops()
{
//not implements
}
public static int TYPE_BITOP=0;
public static int TYPE_LOGIOP=1;
public static int TYPE_ARTMOP=2;
public static int TYPE_CPROP=3;
}

int描述运算符类型,然后根据响应的类型让value为具体的运算符类。接着给出cprop的类:

package ravaComplier.syntax.nodes;
public class cprop {
public cprop()
{
//not implemets
}
private int type;
public static int  TYPE_GREATER = 0;//>
public static int TYPE_GREATEREQUAL=1;//>=;
public static int TYPE_LESS=2;//<;
public static int TYPE_LESSEQUEAL=3;//<=;
public static int TYPE_EQUAL=4;//==
}

这是一个终结符,所以只有一个域来记录运算符的类型。

本篇文章到此就结束了,下篇文章讲着重分析语法树的展开过程。

自制编译器:语法分析器(一)相关推荐

  1. 计算机组成要素六:编译器 语法分析器

    高级语言要编译转换成中间文件,首先需要语法分析也就是理解高级语言所表达的内容,然后是代码生成就是把理解的内容转化成正真的代码.对高级语言进行语法分析的步骤如下,第一步转化成字元,然后根据语法规则进行组 ...

  2. 自制编译器:语法分析器(二)

    这篇博文拖了好久才写完,其一是语法分析器本身的难度实在有点超出我的预料,以至于反复重构多次才完成,其二是因为弄了个xbox玩,占用了一部分的课余时间= =!. 本篇博文将分为以下几个部分来描述一下语法 ...

  3. java实现语法分析器_200 行 JS 代码,带你实现代码编译器

    一.前言 对于前端同学来说,编译器可能适合神奇的魔盒 ,表面普通,但常常给我们惊喜. 编译器,顾名思义,用来编译,编译什么呢?当然是编译代码咯 . 其实我们也经常接触到编译器的使用场景: React ...

  4. 编译器入门 语法分析器 java_从零开始写个编译器吧 - Parser 语法分析器

    Parser(语法分析器)的编写相对于 Tokenizer (词法分析器)要复杂得多,因此,在编写之前可能也会铺垫得更多一些.当然,本系列旨在"写出"一个编译器,所以理论方面只会简 ...

  5. 自己动手开发编译器(十)miniSharp语法分析器

    经过前面四篇的铺垫,我们终于拥有了编写语法分析器的强大工具,现在可以正式开发一门编程语言的语法分析器了.我们先来定义miniSharp的语法规则,然后根据LL文法的特点进行一些调整,最后借助解析器组合 ...

  6. 简易编译器实现(二)使用Bison创建语法分析器

    你也可以通过我的独立博客 -- www.huliujia.com 获取本篇文章 简易编译器实现(一)使用Flex创建词法分析器一文介绍了编译器的概念和七个阶段,并说明了如何使用Flex创建词法分析器. ...

  7. java实现语法分析器_语法分析 | 语法分析的任务

    在之前,我们有对编译器做过一定的介绍,我们认为编译器是具有一定流水线结构的软件系统.它可以分为前端,中端和后端这样的不同的阶段. 编译器前端 对于我们正在研究的前端,我们已经通过词法分析的学习掌握了从 ...

  8. Java中语法分析器_语法分析器(java语法分析器)

    亲这是一款采用递归下降语法分析器,是一种适合手写语法编译器的方法,且非常简单.递归下降法对语言所用的文法有一些限制,但递归下降是现阶段主流的语法分析方法,因为它可以由开发人员高度控制,在提供错误信息方 ...

  9. 《编译原理》实验报告——基于YACC的TINY语法分析器的构建

    一.实验要求 运用YACC,针对TINY语言,构造一个语法分析器.给出实验方案,实施并描述结果. 二.实验方案 (1)设计基于LEX的TINY词法分析器 (2)设计基于YACC的TINY语法分析器 ( ...

最新文章

  1. 提高工作效率的 7 个 Vim 使用技巧!
  2. 关于NB-IoT的十大问题和答案【转】
  3. 对于150kHz导航信号放大接收模块测试实验
  4. python中国大学排名爬虫写明详细步骤-python爬虫爬取2020年中国大学排名
  5. 如何理解subplot绘制不规则子图的参数设置
  6. 3 操作系统第二章 进程管理 进程定义、特征、组织、状态与转换
  7. 前端工程师面试题汇总--技术
  8. 案例演示按角色的form认证实现过程
  9. OPPO K9 Pro将于9月26日登场:搭载天玑1200旗舰游戏芯
  10. 【ZJCPC2019 第16届 浙江省赛】The 16th Zhejiang Provincial Collegiate Programming Contest(GFHIJ 5题)
  11. MySQL索引. ref_mysql中索引利用情况(explain用法)
  12. 电子邮箱官网地址是什么,企业邮箱官网地址登录入口讲解
  13. VRay Next(4.0) for SketchUp之BIG分析图制作教程
  14. 用python分析股票收益影响因素的方法_Python3对股票的收益和风险进行分析
  15. 基于CANoe的ECU Bootloader刷写软件
  16. 测试工程师进阶之测试用例发散思维(二)
  17. cαr怎么发音_最全英语口语发音规则与技巧
  18. WIFI驱动配置实战(Linux驱动开发篇)
  19. 用马悦凌的养生方法--减肥
  20. 学生信息管理系统(C语言版本+源码)

热门文章

  1. 《微型计算机原理与接口技术》复习笔记(三)
  2. CY7C68013A在WIN7下64位的USB驱动程序安装过程
  3. 模拟信号标准三隔离信号分配器0-10V转4-20mA导轨式模块
  4. Spring Advice 有哪些类型?
  5. 《曹云社》走进东软:奇妙的HR数字化
  6. WIN10企业版系统安装(KB12特供版:采用大白菜启动盘)
  7. 数字化时代,企业应该如何看待商业智能BI
  8. 【C++】7-41 互评成绩(PTA)
  9. PTA 互评成绩(sort函数)
  10. lc滤波电路电感电容值选择_几种常见的无源滤波电路