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