[语法分析]LR语法分析器的构造

    LR分析器的consumeNonTerminal函数在上一节提到过,其实跟Goto表没有关系:如果在分析器内部规约得到一个非终结符,那么规约函数执行结束之后,马上就会根据传入宏的“leftPart”在Goto表中查找对应的目标状态并压栈,而根本不用执行consumeNonTerminal函数。这个成员函数的用武之地在于接受其它分析器得到的非终结符,并在Goto表中“额外”的那一列里查找对应状态并压栈//

#define wrapname(name) name ## _LRAnalyser

static void wrapname(consumeNonTerminal)(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]);
}

    接下来是consumeToken函数,这个函数的职责是在SLR(1)分析预测表中寻找函数入口地址并进入。如果在表内对应的项目为NULL,那么就中断。中断的原因有这么几个:错误;当前LR分析器是个受委托的分析器,遇到外层反花括号;当前分析结束,已经转到状态LRState1(留心观察一下预测分析表的构造,状态LRState1对任何终结符都没有兴趣)。现在我们需要将正常状态和错误状态进行区分。首先,如果在中断时当前状态栈栈顶是状态LRState1,那么这时一个基本块已经被正确识别了;然后,如果当前栈顶的是状态LRState0,那么有一种情况也是正常的,那就是遇到的是一个反花括号,也就是说输入是 "{ }" 空的语句块,读入正花括号后委托进入一个新LR分析器,接着这个分析器马上就遇到了反括号,因此栈顶还是初始状态。除此之外,就是出现了错误情况。

static void wrapname(consumeToken)(void* self, struct Token* token)
{
    struct LRAnalyser* lra = (struct LRAnalyser*)self;
    struct LRState* lrState = (struct LRState*)
                              (lra->stateStack->peek(lra->stateStack));
    if(NULL != lrState->actions[token->type]) {
        lrState->actions[token->type](lra, token); // 正常action
    } else {
        struct AbstractSyntaxNode* ret;
        struct LRState* topState = (struct LRState*)(lra->stateStack->pop(lra->stateStack));
        if((jerryLRStates + LRState0 == topState && RBRACE == token->type)
           || jerryLRStates + LRState1 == topState) {
            ret = lra->symbolStack->pop(lra->symbolStack); // 如果是空语句块,那么得到的是 NULL
            // 清理当前分析器
            struct SyntaxAnalyser* analyser = (struct SyntaxAnalyser*)
                                             (analyserStack->peek(analyserStack));
            analyser->consumeNonTerminal(analyser, ret);
            analyser = (struct SyntaxAnalyser*)
                       (analyserStack->peek(analyserStack));
            analyser->consumeToken(analyser, token);
        } else {
            // 出错
        }
    }
}

    在没有错误的情况下清理分析器是一件简单的事情,因为此时符号栈应该已经空了,所以只需要调用栈的析构函数,而不需关心非终结符。

static void wrapname(cleanup)(struct LRAnalyser* self)
{
    struct AbstractSyntaxNode* node;
    self->symbolStack->finalize(self->symbolStack);
    revert(self->symbolStack);
    self->stateStack->finalize(self->stateStack);
    revert(self->stateStack);

    analyserStack->pop(analyserStack); // 弹出自己
    revert(self);
}

    最后就是分析器的构造函数了。

struct SyntaxAnalyser* newLRAnalyser(void)
{
    struct LRAnalyser* analyser = (struct LRAnalyser*)
                                          allocate(sizeof(struct LRAnalyser));

    analyser->symbolStack = newStack();
    analyser->stateStack = newStack();
    analyser->stateStack->push(analyser->stateStack, jerryLRStates);

    analyser->consumeToken = wrapname(consumeToken);
    analyser->consumeNonTerminal = wrapname(consumeNonTerminal);

    return (struct SyntaxAnalyser*)analyser;
}

在构造时,会向状态栈中压入初始状态jerryLRStates( + 0),也就是状态LRState0。这样一个LR分析器就完成了。

附:LR分析器及预测分析表不含错误处理部分的代码

    错误处理会在某个时候集中进行。

 

#include<stdlib.h>
#include"datastruct.h"
#include"syntax-analyser.h"
#include"syntax-node.h"

#include"COOL/MemoryAllocationDebugger.h"
#include"COOL/Stack/Stack.h"

extern struct Stack* analyserStack;
extern struct SyntaxAnalyser* newVariableAnalyser(void);
extern struct SyntaxAnalyser* newOperationAnalyser(void);

static struct LRState* jerryLRStates = NULL;

#define linkName(f, l) f ## _m_ ## l

#define popStateStack(stack, nr) (stack)->pops(stack, nr, NULL)
static void linkName(BasicBlock, Null)(struct LRAnalyser* analyser)
{
    analyser->symbolStack->push(analyser->symbolStack, NULL);
}

static void linkName(BasicBlock, SentenceBasicBlock)
                                 (struct LRAnalyser* analyser)
{
    struct AbstractSyntaxNode* block = (struct AbstractSyntaxNode*)
                            (analyser->symbolStack->pop(analyser->symbolStack));
    struct AbstractSyntaxNode* sentence = (struct AbstractSyntaxNode*)
                            (analyser->symbolStack->pop(analyser->symbolStack));
    if(NULL != sentence) {
        sentence->nextNode = block;
        block = sentence;
    }
    analyser->symbolStack->push(analyser->symbolStack, block);
    popStateStack(analyser->stateStack, 2);
}

static void linkName(Sentence, EoS)(struct LRAnalyser* analyser)
{
    analyser->symbolStack->push(analyser->symbolStack, NULL);
    popStateStack(analyser->stateStack, 1);
}

static void linkName(Sentence, IfElseBranch)(struct LRAnalyser* analyser)
{
    struct AbstractSyntaxNode* invalidSuit = (struct AbstractSyntaxNode*)
                            (analyser->symbolStack->pop(analyser->symbolStack));
    struct AbstractSyntaxNode* validSuit = (struct AbstractSyntaxNode*)
                            (analyser->symbolStack->pop(analyser->symbolStack));
    struct AbstractValueNode* condition = (struct AbstractValueNode*)
                            (analyser->symbolStack->pop(analyser->symbolStack));
    analyser->symbolStack->push(analyser->symbolStack,
                              newIfElseNode(condition, validSuit, invalidSuit));
    popStateStack(analyser->stateStack, 6);
}

static void linkName(Sentence, WhileLoop)(struct LRAnalyser* analyser)
{
    struct AbstractSyntaxNode* loop = (struct AbstractSyntaxNode*)
                            (analyser->symbolStack->pop(analyser->symbolStack));
    struct AbstractValueNode* condition = (struct AbstractValueNode*)
                            (analyser->symbolStack->pop(analyser->symbolStack));
    analyser->symbolStack->push(analyser->symbolStack,
                                newWhileNode(condition, loop));
    popStateStack(analyser->stateStack, 5);
}

static void linkName(Sentence, TypeVariableRegisterEoS)
                               (struct LRAnalyser* analyser)
{
    popStateStack(analyser->stateStack, 3);
}

static void linkName(Sentence, IOAssignmentEoS)(struct LRAnalyser* analyser)
{
    struct AbstractValueNode* expression = (struct AbstractValueNode*)
                            (analyser->symbolStack->pop(analyser->symbolStack));
    struct IONode* node = (struct IONode*)(analyser->symbolStack->
                                           peek(analyser->symbolStack));
    node->expression = expression;
    popStateStack(analyser->stateStack, 3);
}

static void linkName(Sentence, AssignmentEoS)(struct LRAnalyser* analyser)
{
    struct AbstractValueNode* arith = (struct AbstractValueNode*)
                            (analyser->symbolStack->pop(analyser->symbolStack));
    analyser->symbolStack->push(analyser->symbolStack,
                                newArithmaticNode(arith));
    popStateStack(analyser->stateStack, 2);
}

static void linkName(Sentence, BreakEoS)(struct LRAnalyser* analyser)
{
    analyser->symbolStack->push(analyser->symbolStack, newBreakNode());
    popStateStack(analyser->stateStack, 2);
}

static void linkName(ElseBlock, Null)(struct LRAnalyser* analyser)
{
    analyser->symbolStack->push(analyser->symbolStack, NULL);
}

static void linkName(ElseBlock, ElseBasicBlock)(struct LRAnalyser* analyser)
{
    popStateStack(analyser->stateStack, 2);
}

static void linkName(Initialization, Null)(struct LRAnalyser* analyser)
{
    analyser->symbolStack->push(analyser->symbolStack, NULL);
}

static void linkName(Sentence, LBraceBasicBlockRBrace)
                               (struct LRAnalyser* analyser)
{
    struct AbstractSyntaxNode* innerBlock = (struct AbstractSyntaxNode*)
                            (analyser->symbolStack->pop(analyser->symbolStack));
    analyser->symbolStack->push(analyser->symbolStack,
                                newBasicBlockNode(innerBlock));
    popStateStack(analyser->stateStack, 3);
}

static void linkName(Initialization, AssignAssignment)
                               (struct LRAnalyser* analyser)
{
    popStateStack(analyser->stateStack, 2);
}

static void linkName(VariableRegister, VariableInitialization)
                                       (struct LRAnalyser* analyser)
{
    void* initialValue = analyser->symbolStack->pop(analyser->symbolStack);
    void* variable = analyser->symbolStack->pop(analyser->symbolStack);

    struct DeclarationNode* decl = (struct DeclarationNode*)
                                       (analyser->symbolStack->
                                                 peek(analyser->symbolStack));
    decl->vars->enqueue(decl->vars, variable);
    decl->initVals->enqueue(decl->initVals, initialValue);
    popStateStack(analyser->stateStack, 2);
}

#define shift(current, encounter, target)                                 \
    static void linkName(current, encounter)(struct LRAnalyser* self,     \
                                             struct Token* t)             \
    {                                                                     \
        self->stateStack->push(self->stateStack, jerryLRStates + target); \
    } /*******************************************************************/
shift(Sentence_AssignmentEoS_1, EOS, Sentence_AssignmentEoS_2)
shift(Sentence_BreakEoS_1, EOS, Sentence_BreakEoS_2)
shift(Sentence_LBraceBasicBlockRBrace_2, RBRACE,
      Sentence_LBraceBasicBlockRBrace_3)
shift(IfElseBranch_1, LPARENT, IfElseBranch_2)
shift(IfElseBranch_3, RPARENT, IfElseBranch_4)
shift(IfElseBranch_5, ELSE, ElseBlock_1)
shift(WhileLoop_1, LPARENT, WhileLoop_2)
shift(WhileLoop_3, RPARENT, WhileLoop_4)
shift(VariableRegister_VariableInitialization_1, ASSIGN,
      Initialization_AssignAssignment_1)
shift(DeclarationVariableRegister, EOS, Declaration_3)
shift(Sentence_IOAssignmentEoS_2, EOS, Sentence_IOAssignmentEoS_3)
#define shiftFirstSentence(current)                                         \
    shift(current, EOS,    Sentence_EoS_1)                                  \
    shift(current, LBRACE, Sentence_LBraceBasicBlockRBrace_1)               \
    shift(current, IF,     IfElseBranch_1)                                  \
    shift(current, WHILE,  WhileLoop_1)                                     \
    shift(current, BREAK,  Sentence_BreakEoS_1)                             \
    static void linkName(current, INTEGER_TYPE)(struct LRAnalyser* self,    \
                                                 struct Token* t)           \
    {                                                                       \
        self->symbolStack->push(self->symbolStack,                          \
                                newDeclarationNode(t->type));               \
        self->stateStack->push(self->stateStack,                            \
                               jerryLRStates + Declaration_1);              \
    }                                                                       \
                                                                            \
    static void linkName(current, REAL_TYPE)(struct LRAnalyser* self,       \
                                              struct Token* t)              \
    {                                                                       \
        self->symbolStack->push(self->symbolStack,                          \
                                newDeclarationNode(t->type));               \
        self->stateStack->push(self->stateStack,                            \
                               jerryLRStates + Declaration_1);              \
    }                                                                       \
                                                                            \
    static void linkName(current, READ)(struct LRAnalyser* self,            \
                                        struct Token* t)                    \
    {                                                                       \
        self->symbolStack->push(self->symbolStack, newIONode(t->type));     \
        self->stateStack->push(self->stateStack,                            \
                               jerryLRStates + Sentence_IOAssignmentEoS_1); \
    }                                                                       \
                                                                            \
    static void linkName(current, WRITE)(struct LRAnalyser* self,           \
                                         struct Token* t)                   \
    {                                                                       \
        self->symbolStack->push(self->symbolStack, newIONode(t->type));     \
        self->stateStack->push(self->stateStack,                            \
                               jerryLRStates + Sentence_IOAssignmentEoS_1); \
    } /*********************************************************************/
shiftFirstSentence(LRState0)
shiftFirstSentence(BasicBlock_SentenceBasicBlock_1)
shiftFirstSentence(IfElseBranch_4)
shiftFirstSentence(WhileLoop_4)
shiftFirstSentence(ElseBlock_1)
#undef shiftFirstSentence
#undef shift

static void linkName(DeclarationVariableRegister, COMMA)
                                      (struct LRAnalyser* self, struct Token* t)
{
    popStateStack(self->stateStack, 1);
}

#undef popStateStack

#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

#define reduce(current, encounter, leftPart, rightPart)                    \
static void linkName(current, encounter)(struct LRAnalyser* self,          \
                                         struct Token* t)                  \
{                                                                          \
    linkName(leftPart, rightPart)(self);                                   \
    struct LRState* target = ((struct LRState*)self->stateStack->          \
                                peek(self->stateStack))->gotoes[leftPart]; \
    self->stateStack->push(self->stateStack, target);                      \
    self->consumeToken(self, t);                                           \
} /************************************************************************/
reduce(LRState0, END,    BasicBlock, Null)
reduce(LRState0, RBRACE, BasicBlock, Null)
reduce(LRState0, ELSE,   BasicBlock, Null)

reduce(BasicBlock_SentenceBasicBlock_1, END,    BasicBlock, Null)
reduce(BasicBlock_SentenceBasicBlock_1, RBRACE, BasicBlock, Null)
reduce(BasicBlock_SentenceBasicBlock_1, ELSE,   BasicBlock, Null)

reduce(VariableRegister_VariableInitialization_1, EOS,   Initialization, Null)
reduce(VariableRegister_VariableInitialization_1, COMMA, Initialization, Null)

reduce(IfElseBranch_5, RBRACE, ElseBlock, Null)
reduce(IfElseBranch_5, END,    ElseBlock, Null)
#define reduceFirstSentence(current, leftPart, rightPart) \
    reduce(current, IF,           leftPart, rightPart)    \
    reduce(current, WHILE,        leftPart, rightPart)    \
    reduce(current, READ,         leftPart, rightPart)    \
    reduce(current, WRITE,        leftPart, rightPart)    \
    reduce(current, BREAK,        leftPart, rightPart)    \
    reduce(current, INTEGER_TYPE, leftPart, rightPart)    \
    reduce(current, REAL_TYPE,    leftPart, rightPart)    \
    reduce(current, INTEGER,      leftPart, rightPart)    \
    reduce(current, REAL,         leftPart, rightPart)    \
    reduce(current, NOT,          leftPart, rightPart)    \
    reduce(current, PLUS,         leftPart, rightPart)    \
    reduce(current, MINUS,        leftPart, rightPart)    \
    reduce(current, IDENT,        leftPart, rightPart)    \
    reduce(current, EOS,          leftPart, rightPart)    \
    reduce(current, LBRACE,       leftPart, rightPart)    \
    reduce(current, LPARENT,      leftPart, rightPart) /**/
reduceFirstSentence(IfElseBranch_5, ElseBlock, Null)
#define reduceAny(current, leftPart, rightPart)        \
    reduceFirstSentence(current, leftPart, rightPart)  \
    reduce(current, END,          leftPart, rightPart) \
    reduce(current, ELSE,         leftPart, rightPart) \
    reduce(current, MULTIPLY,     leftPart, rightPart) \
    reduce(current, DIVIDE,       leftPart, rightPart) \
    reduce(current, ASSIGN,       leftPart, rightPart) \
    reduce(current, LT,           leftPart, rightPart) \
    reduce(current, LE,           leftPart, rightPart) \
    reduce(current, EQ,           leftPart, rightPart) \
    reduce(current, GT,           leftPart, rightPart) \
    reduce(current, GE,           leftPart, rightPart) \
    reduce(current, NE,           leftPart, rightPart) \
    reduce(current, AND,          leftPart, rightPart) \
    reduce(current, OR,           leftPart, rightPart) \
    reduce(current, COMMA,        leftPart, rightPart) \
    reduce(current, RPARENT,      leftPart, rightPart) \
    reduce(current, LBRACKET,     leftPart, rightPart) \
    reduce(current, RBRACKET,     leftPart, rightPart) \
    reduce(current, RBRACE,       leftPart, rightPart)
reduceAny(Sentence_EoS_1, Sentence, EoS)
reduceAny(BasicBlock_SentenceBasicBlock_2, BasicBlock, SentenceBasicBlock)
reduceAny(Sentence_IOAssignmentEoS_3, Sentence, IOAssignmentEoS)
reduceAny(IfElseBranch_6, Sentence, IfElseBranch)
reduceAny(ElseBlock_2, ElseBlock, ElseBasicBlock)
reduceAny(WhileLoop_5, Sentence, WhileLoop)
reduceAny(Sentence_AssignmentEoS_2, Sentence, AssignmentEoS)
reduceAny(Sentence_BreakEoS_2, Sentence, BreakEoS)
reduceAny(Declaration_3, Sentence, TypeVariableRegisterEoS)
reduceAny(Sentence_LBraceBasicBlockRBrace_3, Sentence, LBraceBasicBlockRBrace)
reduceAny(Initialization_AssignAssignment_2, Initialization, AssignAssignment)
reduceAny(VariableRegister_VariableInitialization_2, VariableRegister,
          VariableInitialization)
#undef reduceAny
#undef reduce

void initialLRStates(void)
{
    jerryLRStates = (struct LRState*)
                            allocate(NR_LR_STATE * sizeof(struct LRState));
    memset(jerryLRStates, 0, NR_LR_STATE * sizeof(struct LRState));
#define setAction(state, encounter)                                    \
        jerryLRStates[state].actions[encounter] = linkName(state, encounter)
    setAction(LRState0, END);
    setAction(LRState0, RBRACE);
    setAction(LRState0, ELSE);
    setAction(BasicBlock_SentenceBasicBlock_1, END);
    setAction(BasicBlock_SentenceBasicBlock_1, RBRACE);
    setAction(BasicBlock_SentenceBasicBlock_1, ELSE);
    setAction(Sentence_AssignmentEoS_1, EOS);
    setAction(Sentence_BreakEoS_1, EOS);
    setAction(Sentence_LBraceBasicBlockRBrace_2, RBRACE);
    setAction(IfElseBranch_1, LPARENT);
    setAction(IfElseBranch_3, RPARENT);
    setAction(IfElseBranch_5, ELSE);
    setAction(IfElseBranch_5, RBRACE);
    setAction(IfElseBranch_5, END);
    setAction(WhileLoop_1, LPARENT);
    setAction(WhileLoop_3, RPARENT);
    setAction(VariableRegister_VariableInitialization_1, ASSIGN);
    setAction(DeclarationVariableRegister, EOS);
    setAction(DeclarationVariableRegister, COMMA);
    setAction(Sentence_IOAssignmentEoS_2, EOS);
    setAction(VariableRegister_VariableInitialization_1, EOS);
    setAction(VariableRegister_VariableInitialization_1, COMMA);
    setAction(Declaration_1, IDENT);
    #define setActionFirstAssignment(state) \
        setAction(state, PLUS);             \
        setAction(state, MINUS);            \
        setAction(state, NOT);              \
        setAction(state, INTEGER);          \
        setAction(state, REAL);             \
        setAction(state, IDENT);            \
        setAction(state, LPARENT) /*********/
    setActionFirstAssignment(IfElseBranch_2);
    setActionFirstAssignment(WhileLoop_2);
    setActionFirstAssignment(Sentence_IOAssignmentEoS_1);
    setActionFirstAssignment(Initialization_AssignAssignment_1);
    #define setActionFirstSentence(state) \
        setAction(state, EOS);            \
        setAction(state, READ);           \
        setAction(state, WRITE);          \
        setAction(state, IF);             \
        setAction(state, WHILE);          \
        setAction(state, BREAK);          \
        setAction(state, INTEGER_TYPE);   \
        setAction(state, REAL_TYPE);      \
        setAction(state, LBRACE);         \
        setActionFirstAssignment(state) ///
    setActionFirstSentence(LRState0);
    setActionFirstSentence(BasicBlock_SentenceBasicBlock_1);
    setActionFirstSentence(IfElseBranch_4);
    setActionFirstSentence(IfElseBranch_5);
    setActionFirstSentence(WhileLoop_4);
    setActionFirstSentence(ElseBlock_1);
    setActionFirstSentence(Sentence_LBraceBasicBlockRBrace_1);
    setAction(Sentence_LBraceBasicBlockRBrace_1, RBRACE);
    #define setActionAny(state)         \
        setAction(state, END);          \
        setAction(state, ELSE);         \
        setAction(state, MULTIPLY);     \
        setAction(state, DIVIDE);       \
        setAction(state, ASSIGN);       \
        setAction(state, LT);           \
        setAction(state, LE);           \
        setAction(state, EQ);           \
        setAction(state, GT);           \
        setAction(state, GE);           \
        setAction(state, NE);           \
        setAction(state, AND);          \
        setAction(state, OR);           \
        setAction(state, COMMA);        \
        setAction(state, RPARENT);      \
        setAction(state, LBRACKET);     \
        setAction(state, RBRACKET);     \
        setAction(state, RBRACE);       \
        setActionFirstSentence(state) ///
    setActionAny(Sentence_EoS_1);
    setActionAny(BasicBlock_SentenceBasicBlock_2);
    setActionAny(Sentence_IOAssignmentEoS_3);
    setActionAny(IfElseBranch_6);
    setActionAny(ElseBlock_2);
    setActionAny(WhileLoop_5);
    setActionAny(Sentence_AssignmentEoS_2);
    setActionAny(Sentence_BreakEoS_2);
    setActionAny(Sentence_LBraceBasicBlockRBrace_3);
    setActionAny(Initialization_AssignAssignment_2);
    setActionAny(VariableRegister_VariableInitialization_2);
    setActionAny(Declaration_3);
    #undef setActionFirstAssignment
    #undef setActionFirstSentence
    #undef setActionAny
    #undef setAction

    #define setGoto(state, nonTerminal, target)                         \
        jerryLRStates[state].gotoes[nonTerminal] = jerryLRStates + target
    setGoto(LRState0, BasicBlock, LRState1);
    setGoto(LRState0, Sentence, BasicBlock_SentenceBasicBlock_1);
    setGoto(BasicBlock_SentenceBasicBlock_1, Sentence,
            BasicBlock_SentenceBasicBlock_1);
    setGoto(BasicBlock_SentenceBasicBlock_1, BasicBlock,
            BasicBlock_SentenceBasicBlock_2);
    setGoto(WhileLoop_4, Sentence, WhileLoop_5);
    setGoto(IfElseBranch_4, Sentence, IfElseBranch_5);
    setGoto(IfElseBranch_5, ElseBlock, IfElseBranch_6);
    setGoto(ElseBlock_1, Sentence, ElseBlock_2);
    setGoto(VariableRegister_VariableInitialization_1, Initialization,
            VariableRegister_VariableInitialization_2);
    setGoto(Declaration_1, VariableRegister, DeclarationVariableRegister);
    #undef setGoto

    #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
}

#undef linkName

void destructLRStates(void)
{
    revert(jerryLRStates);
    jerryLRStates = NULL;
}

#define wrapname(name) name ## _LRAnalyser
static void wrapname(cleanup)(struct LRAnalyser* self)
{
    struct AbstractSyntaxNode* node;
    self->symbolStack->finalize(self->symbolStack);
    self->stateStack->finalize(self->stateStack);

    analyserStack->pop(analyserStack);
    revert(self);
}

static void wrapname(consumeToken)(void* self, struct Token* token)
{
    struct LRAnalyser* lra = (struct LRAnalyser*)self;
    struct LRState* lrState = (struct LRState*)
                              (lra->stateStack->peek(lra->stateStack));
    if(NULL != lrState->actions[token->type]) {
        lrState->actions[token->type](lra, token);
    } else {
//        printf("Interrupt LR\n");
        struct AbstractSyntaxNode* ret;
        struct LRState* topState = (struct LRState*)
                                        (lra->stateStack->pop(lra->stateStack));
        if((jerryLRStates + LRState0 == topState && RBRACE == token->type)
           || jerryLRStates + LRState1 == topState) {
            ret = lra->symbolStack->pop(lra->symbolStack);
            wrapname(cleanup)(lra);
//        printf("Cleaned...\n");
            struct SyntaxAnalyser* analyser = (struct SyntaxAnalyser*)
                                           (analyserStack->peek(analyserStack));
            analyser->consumeNonTerminal(analyser, ret);
            analyser = (struct SyntaxAnalyser*)
                       (analyserStack->peek(analyserStack));
            analyser->consumeToken(analyser, token);
        } else {
            printf("LR ERR\n");
            printf("%s\n", token->image);
            exit(0);
        }
    }
}

static void wrapname(consumeNonTerminal)(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]);
}

struct SyntaxAnalyser* newLRAnalyser(void)
{
    struct LRAnalyser* analyser = (struct LRAnalyser*)
                                          allocate(sizeof(struct LRAnalyser));

    analyser->symbolStack = newStack();
    analyser->stateStack = newStack();
    analyser->stateStack->push(analyser->stateStack, jerryLRStates);

    analyser->consumeToken = wrapname(consumeToken);
    analyser->consumeNonTerminal = wrapname(consumeNonTerminal);

    return (struct SyntaxAnalyser*)analyser;
}
#undef wrapname

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值