简单的C语言解释运行器实现(三)—— 定义语法

本文介绍了在实现简单的C语言解释器时,如何定义和处理文法,包括定义文法、文法提取、递归文法的构造以及如何避免二义性。通过实例展示了如何为八进制数、运算符优先级等建立无歧义的文法规则。
摘要由CSDN通过智能技术生成

好的,词法分析就结束了,我们开始语法分析吧。

首先为了简化问题,我们对C语言作出如下限制:
1. 没有switch语句
2. 不支持函数指针
3. 没有结构体、联合体
4. 以及一些其他的语句

预处理器将在第七篇中讲到。编译阶段将不会有预处理指令(#include等)。

我们要处理的语法将在下面列出。

文法

定义文法

首先我们定义一条文法是这样的:

NAME ::= SOME_THING

这表示我们定义了一条文法,代号是NAME,可以匹配SOME_THING,比如我们定义

D ::= 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7

表示我们定义八进制数位,可匹配0~7所有的数字,其中竖线|表示或的意思,就是可接受0或1或2或3或…或7。

文法提取

定义文法可能有很多重复的地方,我们可以提取。

R ::= Ua | Ub | Uc | Ud | ... | Uz

提取成

R ::= U(a | b | c | ... | z)

下面的sizeof的定义将采取这种方式:sizeof((TYPE | ID))表示sizeof(TYPE) | sizeof(ID)

递归文法

我们要定义一种文法,可以匹配多次的,比如我们要匹配一个八进制整数,显然位数在理想情况下是可以无限长的,为了匹配这种文法,我们引入递归文法,比如定义八进制整数:

N ::= D | ND

表示接受一位8进制数,或者一位8进制数后面继续接8进制整数。那么匹配123的时候就是:

N -> ND -> NDD -> DDD

首先N展开成ND,ND中的N再次展开成ND,最后N展开成D完成匹配。
必须要注意的是我们不能这样定义:N ::= ND,这样就是死递归,停不下来了。

当然我们也可以定义 N::=D

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值