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
本文深入解析LR分析器的工作原理,包括consumeNonTerminal和consumeToken函数的实现细节,以及如何通过Goto表和预测分析表进行状态转移和错误处理。文章还提供了LR分析器的构造过程及其核心组件的代码示例。
2143

被折叠的 条评论
为什么被折叠?



