- 浏览: 58987 次
- 性别:
- 来自: 武汉
最新评论
-
NeuronR:
之前自搭 blog, 太累. 最近在研究 C艹 语言的错误处理 ...
C++ 中处理除零错误 -
lwwin:
话说很久没有看到你更新BLOG了,最近在研究LINUX开发^^ ...
C++ 中处理除零错误 -
lwwin:
RednaxelaFX 写道我的见识还是太少了……最近在某在x ...
[优化]删去 NOP 指令 -
RednaxelaFX:
我的见识还是太少了……最近在某在x86上跑的东西的手写汇编里的 ...
[优化]删去 NOP 指令 -
NeuronR:
lwwin 写道没想到一个NOP把FX也拉来了^^关于代码…… ...
[优化]删去 NOP 指令
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
评论
嗯,编译没通过,shift的移除了,这个也去掉吧~
360. setAction(IfElseBranch_5, RBRACE);
我真会挑刺(-3-~
setAction(IfElseBranch_5, RBRACE);
这个不是根据shift来的,而是根据reduce来的。对应的那句宏函数在285行
reduce(IfElseBranch_5, RBRACE, ElseBlock, Null)
不知道你是不是弄掉了这个。
PS: 谢谢挑刺。
360. setAction(IfElseBranch_5, RBRACE);
我真会挑刺(-3-~
相关推荐
编译原理语法分析,C语言,自下而上分析法
LR语法分析器是一种用于解析上下文无关文法的高效工具,广泛应用于编译器设计中。LR分析器从左向右扫描输入字符串,并自底向上地进行语法分析,旨在判断输入字符串是否符合文法的语句。以下是关于LR分析器设计的一些...
java编写的LR语法分析器(编译原理实验) 本实验是基于java语言实现的LR语法分析器,旨在演示编译原理中的LR语法分析技术。LR语法分析器是编译原理中的一种重要技术,用于分析和识别源代码中的语法结构。 LR语法...
通过LR分析表及三个栈形成对输入表达式的判断! 。
本项目是基于LR语法分析器的课程设计源码,旨在帮助学习者深入理解和实践编译器构造的核心概念。 LR语法分析器的全称是“左到右扫描,右部优先”的语法分析器,其工作原理是自左向右读取输入符号串,并通过一套状态...
关键词:LR分析器,语法分析器,编译原理,文法判定 综上所述,LR(k)分析法是编译器设计中的关键部分,尤其是LR(1)分析器,它通过增加预测信息,有效地解决了LR(0)分析器可能出现的冲突问题,提高了语法分析的精确...
在描述中提到的"加上框架代码,构造出LR1语法分析程序",意味着LR1生成器不仅生成状态转换表,还会提供一些基础的框架代码,这些代码可以与状态转换表结合,用于构建完整的LR1解析器。框架代码通常包括输入符号的...
《编译原理上机源代码LR语法分析器》 编译原理是计算机科学中的核心领域,涉及语言处理、解析技术等方面。LR语法分析是编译器设计中的一个重要环节,用于将高级语言转换为机器可执行的指令。这篇实验报告详细介绍了...
LR(0)语法分析器是一种在编译原理中常见的解析技术,主要应用于处理上下文无关文法。这个程序是用C语言编写的,因此具备高度的可移植性和效率。 LR(0)分析器的核心思想是基于状态转移表,通过自底向上的方式逐层解析...
总的来说,这个Java编写的LR(0)语法分析器提供了一个实践编译原理中LR分析方法的实例,对于学习编译器构造和理解LR解析算法具有很高的价值。通过阅读和研究这些类的源代码,我们可以更深入地了解LR(0)分析器的工作...
LR0分析器是一种自底向上的语法分析方法,"LR"代表“Left-to-Right扫描输入,Rightmost derivation推导”,"0"表示它使用的是最简单的项集构造算法。它通过构建一个有限状态机来识别语言,这个状态机被称为分析表。...
本实验重点聚焦于语法分析阶段,特别是LR语法分析器的实现。LR分析器是一种自底向上的解析技术,常用于编译器设计,用于将源代码解析成抽象语法树(AST),从而进行后续的编译或解释工作。 LR语法分析器的全称是...
LR(1)语法分析器是一种在编译原理中广泛使用的解析技术,主要用于处理上下文无关文法。这种分析器能够处理更复杂的语言结构,而不仅仅是简单的左递归或右递归表达式。以下是对LR(1)语法分析器及其相关知识点的详细...
学校老师布置的作业,编译原理实验LR(1)语法分析器,使用C++语言,已经通过VS2019调试通过,欢迎大家下载!
LR(0)语法分析器是一种基于上下文无关文法(Context-Free Grammar, CFG)的自动分析工具,广泛应用于编译器设计中。它通过构造一个LR(0)解析表,根据输入符号序列来决定如何进行分析,从而确定该序列是否符合文法...
LR(0)语法分析器是一种用于解析符合特定类型的上下文无关文法的工具。它基于LR分析方法,其中"LR"代表“从左到右扫描输入,从右most衍生树构造”。"0"表示分析器不使用任何前瞻信息。在本文中,我们将讨论如何使用...
在使用此Java版本的LR1语法分析器之前,建议读者熟悉编译器的基本概念,特别是有关词法分析、语法分析和解析表构造的部分。 LR1分析器的核心思想是自底向上地构建一个解析树,通过对输入符号串进行一系列的 shift-...
根据题目提供的代码片段,我们可以看到这是一个基于LR(1)分析法的语法分析器实现。下面对代码进行详细解读: 1. **预处理指令定义**: - `#define SIZE 20`: 定义了栈的大小为20。 - `#define sSIZE 12`: 定义了...
LR语法分析器是编译器设计中的一种重要工具,用于解析程序源代码,将其转化为中间形式,以便后续的编译阶段进行处理。本实验报告将深入探讨LR(0)语法分析器的工作原理及其应用。 LR分析,全称为“Left-to-Right,...