现在完成的是一个词法分析器,那么怎么将它与语法分析相连?
话说,基本上所有的编译器构造相关的文章都是把词法分析丢在语法分析之前,类似这样:
预处理(C语言为代表,Jerry没这一环) -> 词法分析 -> 语法分析 -> 语义分析 -> 中间代码生成和代码优化 ->目标代码
貌似互相独立的过程。然而从某种程度上来说,语法和词法应该“混为一谈”,并且建立语法树与后面的部分又相对分离(只共享数据结构信息)。
为了达到这一目的,就得利用词法分析抽出的接口firstToken,nextToken,eofToken这三个函数。如果采用LR分析法(我采用的语法分析的实现是SLR(1)的),那么流程可以这样:
firstToken:初始化(LR分析预测表),将一个特殊LR项目和对应状态值压入LR分析栈;
每一次nextToken:调用分析函数,将当前读入的符号扔进语法分析模块中处理,它可能被直接压入分析栈(移进项目),或者等待栈顶完成规约后再移进(规约项目);
eofToken:将特殊符号END传入扔进分析函数,然后结束语法分析,得到最终的语法树。
从这个实现来看,语法分析是个急性子,它并不等所有的词法分析结束后再去符号池中从头到尾扫荡一次,而是每当词法分析获取一个符号就进行一次语法分析。
附:贴出所有Jerry语言的语法产生式,不过它们与上文内容无关(#表示注释一行)
# Jerry语言
Jerry -> BasicBlock <END>
# 基本块
# 严格地说, 基本块这样定义是不正确的, 不过在没有恼人的跳转语句( 包括goto 和 switch-case )的情况下, 可以这么搞
BasicBlock -> ε
BasicBlock -> Sentence BasicBlock
# 语句
Sentence -> <EOS>
Sentence -> IfElseBranch
Sentence -> WhileLoop
Sentence -> Declaration
Sentence -> <IO> Variable <EOS>
Sentence -> Assignment <EOS>
Sentence -> <BREAK> <EOS>
Sentence -> <LBRACE> BasicBlock <RBRACE>
# if-else 分支
IfElseBranch -> <IF> <LPARENT> Assignment <RPARENT> BasicBlock ElseBlock
ElseBlock -> <ELSE> BasicBlock
ElseBlock -> ε
# while 循环
WhileLoop -> <WHILE> <LPARENT> Assignment <RPARENT> BasicBlock
# 声明
# 初始化尚不支持数组
Declaration -> <TYPE> VariableRegister <EOS>
VariableRegister -> VariableRegister <COMMA> Variable Initialization
VariableRegister -> Variable Initialization
Initialization -> <ASSIGN> Assignment
Initialization -> ε
# 下面的产生式都是运算相关的劳什子
# 优先级高的运算, 要优先规约, 从产生式编写的角度来看, 它们在更靠后更"深"的地方
# 赋值 右结合所以递归定义的方式与其他的节点都不一样. 又因为等号优先级最低, 所以作为最"根部"的语法节点类型
Assignment -> Condition <ASSIGN> Assignment
Assignment -> Condition
# 条件 比较运算和逻辑运算符的结晶
Condition -> Condition <OR> ConjunctiveCondition
Condition -> ConjunctiveCondition
ConjunctiveCondition -> NegativeCondition
ConjunctiveCondition -> ConjunctiveCondition <AND> NegativeCondition
NegativeCondition -> <NOT> Comparison
NegativeCondition -> Comparison
# 比较运算
Comparison –> Comparison <COMPARATOR> Expression
Comparison -> Expression
# 表达式
Expression -> Expression <OP_MUL_DIV> Term
Expression -> Term
# 项
Term –> UnaryFactor
Term -> Term <OP_PLS_MNS> UnaryFactor
# 一元因子, 可能有正负号
UnaryFactor -> SimpleFactor
UnaryFactor -> <OP_PLS_MNS> SimpleFactor
# 简单因子
SimpleFactor -> <INTEGER>
SimpleFactor -> <REAL>
SimpleFactor -> Variable
SimpleFactor -> <LPARENT> Assignment <RPARENT>
# 变量( 包括数组下标等信息 )
Variable -> <IDENT> Dimensions
Dimensions -> <LBRACKET> Assignment <RBRACKET> Dimensions
Dimensions -> ε
分享到:
相关推荐
设计、编制并调试一个语法分析程序,加深对语法分析原理的理解。
编译器设计之语法分析算法:SLR Parser
编译器设计之语法分析算法:Predictive Parser
编译器设计之语法分析算法:LALR Parser
编译器设计之语法分析算法:LR Parser
编译器设计之语法分析算法:Earley Parser
编译器设计之语法分析算法:LL Parser
编译器设计之语法分析算法:CYK Algorithm
编译器设计之语法分析算法:Operator Precedence Parser
编译器设计之语法分析算法:Recursive Descent Parser
编译器设计之语法分析算法:Shift-Reduce Parser
### 自顶向下的语法分析:递归下降法 #### 一、引言 在编译原理中,语法分析是编译过程的一个重要阶段,它的主要任务是对由词法分析器提供的单词序列进行语法检查和结构分析,判断这些单词是否构成符合语法规则的...
LL1语法分析源程序 LL(1)语法分析是编译原理中的一种重要技术,它可以对输入的符号串进行语法分析,从而检测出语法错误。下面将详细介绍LL(1)语法分析的基本原理、构造方法和驱动程序的构造方法。 一、LL(1)语法...
在编译原理中,语法分析是编译器设计的关键阶段之一,主要任务是根据语法规则解析源代码,构建抽象语法树(AST),为后续的语义分析和代码生成提供结构化信息。本实验——“北邮编译原理实验二:语法分析程序的设计...
4. **错误检测**:分析器应能检测并报告语法错误,比如括号不匹配、未结束的字符串、非法字符等。 5. **扩展到其他文件类型**:这可能意味着分析器被设计成可配置或可扩展的,能够处理类似C++或Python等其他编程...
编译原理中的语法分析程序 编译原理是一门研究计算机如何分析和解释程序代码的学科,其中语法分析是编译器的核心组件之一。语法分析的目的是检查源代码是否符合语法规则,保证编译器能够正确地编译代码。本文介绍了...
实验二 LL(1) 语法分析实验 (4 学时) 【实验目的】 1. 了解 LL(1)语法分析是如何根据语法规则逐一分析词法分析所得到的单 词,检查语法错误,即掌握语法分析过程。 2. 掌握 LL(1)语法分析器的设计与调试。 ...
1 要求使用LL(1)文法 算符优先文法 LR 1 文法三种分析方法之一进行语法分析 2 输入上下文无关文法 输出语法分析程序 3 输入待检测的Token串 输出检测结果 同时可以处理分析中的异常和错误 ">编译原理课程设计 ...
实验二:TINY扩充语言的语法分析 扩充的语法规则有:实现 while、do while、for语句和求余计算式子,具体文法规则自行构造。 可参考:P97及P136的文法规则。 (1) While-stmt --> while exp do stmt-sequence end...
自顶向下的语法分析:LL(1)分析法 在编译原理课程中,语法分析是编译器的重要组成部分。语法分析的任务是对源程序进行语法检查和分析,以确定源程序是否符合语言的语法规则。在本次实验中,我们将学习自顶向下的...