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

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. 用拓扑排序检测有向图中是否有环
  2. before与after的一些应用总结
  3. MySQL基础之控制台常用命令
  4. python-多继承
  5. [Be a Coding Plasterer] Components 1:get Basic Things
  6. python指数函数,幂函数
  7. 信息系统综合知识二 信息化基础知识
  8. windows下把SD卡格式化成NTFS格式
  9. 微信小程序 share-element page-container 组件的使用
  10. 计算机无法连接苹果手机软件,iphone连不上itunes
  11. Spring 团队开源 nohttp;西部数据将中止与华为的战略合作
  12. 三维实时云渲染平台解决方案
  13. 手机设计软件有哪些(合集)
  14. unity添加android res资源,Unity3d常用两种加载资源方案:Resources.Load和AssetBundle
  15. 致远OA漏洞学习——帆软组件 ReportServer 目录遍历漏洞
  16. win10企业版无法访问共享文件夹
  17. 日消息量突破 50 亿,谈小米的高可用推送系统设计
  18. 国信证券金色阳光版修改增强,还有闪电下单爽啊
  19. 会声会影X3常见问题80个解答
  20. Zotero + connected papers论文顺藤摸瓜

热门文章

  1. MATLAB Symbolic Math Toolbox
  2. springboot启动时,排除某些自动配置类
  3. 笛卡尔坐标系中八个卦限对应的位置
  4. “海盗湾”副本网站上线:IPFS分布式技术搭建
  5. 微机原理与接口技术:微型计算机输入输出接口 详细笔记与例题
  6. 流体力学基础——流体静力学
  7. request.setattribute详解
  8. linux 服务器下查看防火墙
  9. js内存溢出和内存泄漏
  10. 数据库系统概念 实验1~实验9