`
NeuronR
  • 浏览: 58976 次
  • 性别: Icon_minigender_1
  • 来自: 武汉
社区版块
存档分类
最新评论

[语法分析]LR分析器与其它分析器的交互

 
阅读更多

    Action表中还有一小部分没有填完,就是LR分析器委托其他分析器识别非终结符的那一部分。其中包括在变量定义时委托VariableAnalyser识别变量,在识别循环条件或赋值语句等状态中委托OperationAnalyser识别运算式,以及在识别正反花括号内部的基本块时委托一个新的LRAnalyser去识别它。这些Action也可以用宏来实现,大家应该已经轻车熟路,这里就不多说了,直接看代码吧

#define switchAnalyser(current, encounter, analyser)                  \
    static void linkName(current, encounter)(struct LRAnalyser* self, \
                                             struct Token* t)         \
    {                                                                 \
        struct SyntaxAnalyser* delegateAnalyser = (analyser);         \
        analyserStack->push(analyserStack, delegateAnalyser);         \
        delegateAnalyser->consumeToken(delegateAnalyser, t);          \
    } /***************************************************************/
switchAnalyser(Declaration_1, IDENT,  newVariableAnalyser())
#define switchAnalyserFirstAssignment(current, analyser) \
    switchAnalyser(current, PLUS,    analyser)           \
    switchAnalyser(current, MINUS,   analyser)           \
    switchAnalyser(current, NOT,     analyser)           \
    switchAnalyser(current, INTEGER, analyser)           \
    switchAnalyser(current, REAL,    analyser)           \
    switchAnalyser(current, IDENT,   analyser)           \
    switchAnalyser(current, LPARENT, analyser) /*********/
switchAnalyserFirstAssignment(LRState0,       newOperationAnalyser())
switchAnalyserFirstAssignment(IfElseBranch_2, newOperationAnalyser())
switchAnalyserFirstAssignment(WhileLoop_2,    newOperationAnalyser())
switchAnalyserFirstAssignment(IfElseBranch_4, newOperationAnalyser())
switchAnalyserFirstAssignment(WhileLoop_4,    newOperationAnalyser())
switchAnalyserFirstAssignment(ElseBlock_1,    newOperationAnalyser())
switchAnalyserFirstAssignment(Sentence_IOAssignmentEoS_1,
                              newOperationAnalyser())
switchAnalyserFirstAssignment(BasicBlock_SentenceBasicBlock_1,
                              newOperationAnalyser())
switchAnalyserFirstAssignment(Initialization_AssignAssignment_1,
                              newOperationAnalyser())
#define switchAnalyserFirstSentence(current, analyser) \
    switchAnalyser(current, IF,           analyser)    \
    switchAnalyser(current, WHILE,        analyser)    \
    switchAnalyser(current, READ,         analyser)    \
    switchAnalyser(current, WRITE,        analyser)    \
    switchAnalyser(current, BREAK,        analyser)    \
    switchAnalyser(current, INTEGER_TYPE, analyser)    \
    switchAnalyser(current, REAL_TYPE,    analyser)    \
    switchAnalyser(current, EOS,          analyser)    \
    switchAnalyser(current, LBRACE,       analyser)    \
    switchAnalyserFirstAssignment(current, analyser) ///
switchAnalyserFirstSentence(Sentence_LBraceBasicBlockRBrace_1, newLRAnalyser())
switchAnalyser(Sentence_LBraceBasicBlockRBrace_1, RBRACE, newLRAnalyser())
#undef switchAnalyserFirstSentence
#undef switchAnalyserFirstAssignment
#undef switchAnalyser

在状态Sentence_LBraceBasicBlockRBrace_1下,除了遇见First(Sentence),还可能遇见<RBRACE>,因为一个语句块可能是空的,这时仍然委托一个LR分析器来分析它。其实这里也可以换一种思路实现,就是增加一条产生式

Sentence -> <LBRACE> <RBRACE>

这样在状态Sentence_LBraceBasicBlockRBrace_1遇到<RBRACE>时,将它规约为一个空语句就可以了。

委托分析器的返回与comsumeNonTerminal函数

    当一个委托分析器返回一个非终结符给LR分析器时,LR分析器必须做一次Goto状态转移。然而现在有个小问题:非终结符并没有像Token那样有一个type成员,还记得reduce宏函数的的实现吗?规约之后查询Goto表的那一列其实是通过传递给宏的参数leftPart来确定的,也就是说这个是静态绑定的。

    为了实现consumeNonTerminal成员函数,除了为非终结符也添加上一个类型成员以外,当然还是有其它方案的。在设计LRState状态时,我们留下过一个“后门”,Goto表的列数比实际需要多1,现在就可以利用这个后门来确定接受非终结符之后的Goto目标状态。这很大程度上跟Jerry语言的LR分析器比较简单有关:每个委托分析器状态只可能委托给一种分析器。也就是说,在某个特定的状态下,如果调用consumeNonTerminal成员函数,那么传入的非终结符类型是确定的,如状态IfElseBranch_2如果接受一个非终结符,那么它一定是Assignment,而状态Declaration_1接受的一定是Variable,等等;对应的,这时状态IfElseBranch_2一定会Goto到状态IfElseBranch_3,而状态Declaration_1一定会Goto状态VariableRegister_VariableInitialization_1。因此,可以将这些特殊的Goto目标存放在多出的那一列中。

    #define extraGoto(source, target)                                         \
    jerryLRStates[source].gotoes[NR_GOTO_TABLE_COLUMN] = jerryLRStates + target
    extraGoto(LRState0,                        Sentence_AssignmentEoS_1);
    extraGoto(IfElseBranch_4,                  Sentence_AssignmentEoS_1);
    extraGoto(ElseBlock_1,                     Sentence_AssignmentEoS_1);
    extraGoto(WhileLoop_4,                     Sentence_AssignmentEoS_1);
    extraGoto(BasicBlock_SentenceBasicBlock_1, Sentence_AssignmentEoS_1);

    extraGoto(Sentence_LBraceBasicBlockRBrace_1,
              Sentence_LBraceBasicBlockRBrace_2);
    extraGoto(IfElseBranch_2, IfElseBranch_3);
    extraGoto(WhileLoop_2, WhileLoop_3);
    extraGoto(Sentence_IOAssignmentEoS_1, Sentence_IOAssignmentEoS_2);
    extraGoto(Initialization_AssignAssignment_1,
              Initialization_AssignAssignment_2);
    extraGoto(Declaration_1, VariableRegister_VariableInitialization_1);
    #undef extraGoto

而对应的,consumeNonTerminal成员函数的实现是

void consumeNonTerminal_LRAnalyser(void* self,
                                         struct AbstractSyntaxNode* nonTerminal)
{
    struct LRAnalyser* lra = (struct LRAnalyser*)self;
    struct LRState* currentState = (struct LRState*)
                                   (lra->stateStack->peek(lra->stateStack));
    lra->symbolStack->push(lra->symbolStack, nonTerminal);
    lra->stateStack->push(lra->stateStack,
                          currentState->gotoes[NR_GOTO_TABLE_COLUMN]);
}

 

分享到:
评论
2 楼 NeuronR 2009-02-17  
jindw 写道

轻声问一句,楼主这是在写什么语言的编译器呢?

自定义语言,hoho
@see [url]http://neuronr.iteye.com/blogs/309770[/url]
1 楼 jindw 2009-02-17  
轻声问一句,楼主这是在写什么语言的编译器呢?

相关推荐

    语法分析器LR(0)

    在这个Java实现的版本中,LR(0)语法分析器通过图形用户界面(GUI)提供了友好的交互体验。下面我们将深入探讨LR(0)分析器的工作原理以及与其相关的编程实现细节。 LR(0)分析器的核心思想是基于状态转移的自动机,它...

    LR(1)语法分析器

    LR(1)分析器基于LR分析,其中L代表自左至右扫描输入,R代表右most衍生,1则表示分析器在每个决策点会查看一个输入符号(即当前输入符号)以确定下一步行动。LR(1)分析器是自底向上的分析方法,通过构造一个有限状态...

    C#可视化 LR语法分析器

    LR分析器是一种自底向上的语法分析方法,"L"代表“Left-to-right”,表示从输入串的左侧开始扫描;"R"代表“Rightmost derivation”,指的是最右推导,即从输入串的最右侧开始构造语法树。LR分析器通过一种称为LR(0)...

    LR(1)语法分析器-QT,C++

    LR分析器全称为“Left-to-right,Rightmost derivation”的分析器,即从左到右扫描输入串,并尝试构造右派生。LR(1)是在此基础上增加了向前看一位的能力,即在进行决策时会考虑下一个输入符号的信息,从而提高了分析...

    编译原理 LR语法分析

    LR分析器从左到右扫描输入符号,尝试将它们组合成文法的句型,直到最终得到文法的起始符号。 LR分析的核心在于LR(k)分析器,其中k表示向前查看的输入符号数。LR(0)是最基础的版本,不看任何未来的输入;而LR(1)则...

    编译原理词法分析器、语法分析器python实现

    LR0分析器通过构造解析表来确定何时进行归约操作,从而构建出抽象语法树(AST),这有助于理解程序的结构和语义。 Python中的实现通常会涉及递归下降解析(Recursive Descent Parsing)或使用现成的解析库,如PLY...

    编译原理(词法分析器及语法分析器)

    《编译原理——词法分析器与语法分析器详解》 在计算机科学领域,编译原理是理解程序设计语言如何转换成计算机可执行代码的基础。其中,词法分析器和语法分析器是编译器的核心组成部分,它们负责将源代码转化为...

    词法分析器与语法分析器

    词法分析器与语法分析器是编译原理中的核心组成部分,它们在计算机程序设计语言的编译或解释过程中起着至关重要的作用。本课程报告主要探讨了如何使用C++实现这两种关键工具。 词法分析器,又称为扫描器,是编译器...

    SLR(1)语法分析器

    - LR分析器的优化技术,如LALR(1)和GLR(1),以解决SLR(1)的局限性。 - 形式语言理论,包括正则表达式、Chomsky层次等。 8. **实际应用**: SLR(1)分析器在实际编程语言的编译器、解释器、词法分析器和语法分析器...

    语法分析器

    在实际应用中,语法分析器可能还需要与其他组件结合,如集成开发环境(IDE)的自动补全功能,或者用于语法高亮的词法分析器。总的来说,语法分析器的开发涉及到编译原理、图形界面设计和特定库的使用,是一项集理论...

    语法分析器_编译原理_语法分析器;_collegevm5_

    因此,语法分析器不仅会解析源代码,还可能与虚拟机的指令集交互,将源代码转化为虚拟机可以执行的指令序列。 总之,这个项目涵盖了编译器设计的核心概念,包括语法分析器的实现和C++编程技术。通过这个实践,学生...

    Java实现PL0词法分析、语法分析、语义分析

    Java实现的词法分析器会通过正则表达式或其他方法匹配这些模式,生成标记流供后续阶段使用。 接下来是语法分析(Syntax Analysis),通常由解析器(Parser)完成。语法分析器根据词法分析产生的标记流,依据语法...

    编译原理语法分析器

    6. **LR分析器的构造**:包括状态机的构造、分析表的生成、冲突的解决等步骤。 7. **源代码和可执行程序**:实验中可能包含用特定语言(如C++或Java)实现的语法分析器源码,以及编译后的可执行程序,供用户测试和...

    VC++词法语法分析器源码.rar

    这些文件可能包含了词法分析器和语法分析器的具体实现,以及其他与界面交互或特定功能相关的代码。 例如,`FenXi.cpp`很可能包含了语法分析的实现,而`SSView.cpp`和`SourceEditView.cpp`可能涉及到源代码的显示和...

    编译原理课程实验 LR1分析器

    LR1分析器是一种自底向上的语法分析方法,广泛应用于编译器构造中。 首先,我们要理解LR分析的基本概念。LR分析(Look-Ahead Right-to-Left)是一种上下文无关文法的解析技术,它通过构建一个状态转移的有限自动机...

    编译原理中VC实现语法分析器

    VC实现的语法分析器可能使用自底向上或自顶向下的方法,如LL(1)、LR(1)、LALR(1)或递归下降解析等。 4. **VC实现** 使用VC(Visual C++)来实现语法分析器,意味着我们可以利用C++的强大功能,包括类、模板、STL库...

    pl0语法分析 词法分析 语义分析

    在实际的编译器实现中,词法分析、语法分析和语义分析通常由专门的工具和算法支持,如LR分析器用于语法分析,LL解析器则常用于词法分析。而现代编译器可能会结合使用这些方法,或者采用更高级的解析技术,如递归下降...

    编译原理解释器词法语法分析器c语言版

    这通常由解析器(parser)完成,它可以是递归下降解析器、LR分析器或LL分析器等。C语言的语法遵循BNF(巴科斯范式),解析器会检查记号序列是否符合C语言的语法规则,如果符合,就构建出表示程序结构的抽象语法树。 ...

    基于QT实现词法语法分析器,类似于编译器,可以进行词法语法分析.zip

    【标题】"基于QT实现词法语法分析器,类似于编译器,可以进行词法语法分析.zip" 提供了一个项目,旨在使用QT框架构建一个工具,该工具能够执行词法和语法分析,这是编译器设计与实现过程中的关键步骤。QT是一个流行...

    编译原理-语法分析器

    一个编译器通常由词法分析器、语法分析器、语义分析器和目标代码生成器等部分组成。在这个实验中,我们重点关注的是语法分析器,它是连接词法分析器和语义分析器的桥梁。 语法分析器的主要任务是解析由词法分析器...

Global site tag (gtag.js) - Google Analytics