-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathLRParser.cpp
65 lines (56 loc) · 1.48 KB
/
LRParser.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
#include "LRParser.hpp"
#include "LRAction.hpp"
#include "LRState.hpp"
#include "Grammar.hpp"
#include "Production.hpp"
#include <iostream>
/********************----- CLASS: LRParser -----********************/
LRParser::LRParser(LRTable::Type const i_type, size_t const i_k, Grammar const &i_grammar)
:m_table(i_type, i_grammar)
{
m_stackState.push(LRState(0));
}
bool LRParser::parse(Lex &i_lex)
{
bool accepted=false;
Symbol token = i_lex.pop();
while(!m_stackState.empty())
{
LRState state=m_stackState.top();
LRAction const &action=m_table.action(state, token);
#ifndef NDEBUG
std::cout << "(" + std::to_string(state) + " + " + token.toString() + ") --> " + action.toString() << std::endl;
#endif
if(action.isShift())
{
m_stackSymbol.push(token);
m_stackState.push(action.state());
token=i_lex.pop();
}
else if(action.isReduce())
{
Production const &p = action.production();
Symbol const &leftSymbol = p.left()[0];
SymbolList const &right = p.right();
size_t const popCount = right.count();
for(size_t x=0; x<popCount; ++x)
{
m_stackSymbol.pop();
m_stackState.pop();
}
m_stackSymbol.push(leftSymbol);
m_stackState.push(m_table.path(state, leftSymbol));
}
else if(action.isAccept())
{
accepted=true;
break;
}
else
{
throw std::runtime_error("NOES!");
}
}
return accepted;
}
/**************************************************/