forked from rperlste/UniversalCompiler
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathParserDriver.cpp
93 lines (77 loc) · 2.81 KB
/
ParserDriver.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
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
#include "ParserDriver.h"
ParserDriver::ParserDriver( const Grammar& grammar ){
this->grammar = grammar;
this->parseTable = new ParseTable( grammar );
parseTable->GenerateTable();
}
void ParserDriver::parse( std::fstream& programFile, bool printOutput ){
Scanner scanner( &programFile );
Token currentInputToken;
Symbol topStackSymbol;
// Formatting for output
int fileWidth = scanner.getProgramFileLength();
std::string currentStackValues = "";
//Push(S); � � Push the Start Symbol onto an empty stack
parseStack.push_front( grammar.getStartSymbol() );
// let a be the current input token
currentInputToken = scanner.peekNextToken();
if( printOutput ){
std::cout << "\n\n RemainingInput" << std::string( fileWidth - (fileWidth - 11), ' ' )
<< "\t Action\t" << "ParseStack\n"
<< " --------------------------------------------------------------------------------";
}
while( !parseStack.empty() ){
if( printOutput ){
std::cout << "\n";
scanner.printRemainingFile();
std::cout << std::string(
fileWidth - (fileWidth - scanner.getScannerBufferPosition()), ' ' ) << "\t ";
currentStackValues = "";
for( int indexStack = parseStack.size() -1; indexStack > -1 ; indexStack -- ){
currentStackValues += parseStack[indexStack] + " ";
}
}
// let X be the top stack symbol; let a be the current input token
topStackSymbol = parseStack.front();
//if X in nonterminals
if( grammar.nonterminalSet.contains( topStackSymbol ) ){
// if T(X, a) = X �> Y1Y2. . .Ym
try{
Production production = parseTable->getPredictProduction(
topStackSymbol,
(tokenEnumsValues[currentInputToken.getTokenType()] != "" )
? tokenEnumsValues[currentInputToken.getTokenType()]
: currentInputToken.getTokenTypeString() );
//Expand nonterminal, replace X with Y1Y2. . .Ym on the stack
parseStack.pop_front();
for( int indexRHS = production.getRHS().size() - 1; indexRHS > -1; indexRHS -- ){
if( production.getRHS()[indexRHS] != ""
&& production.getRHS()[indexRHS][0] != '#' )
parseStack.push_front( production.getRHS()[indexRHS] );
}
if( printOutput ){
std::cout << parseTable->getPredictIndex( topStackSymbol,
(tokenEnumsValues[currentInputToken.getTokenType()] != "" )
? tokenEnumsValues[currentInputToken.getTokenType()]
: currentInputToken.getTokenTypeString() );
}
} catch ( IndexOutOfBounds e ) {
throw SyntaxError("Syntax error at: " + currentInputToken.getTokenValue());
}
}
// X in terminals
else {
// Match of X worked
parseStack.pop_front();
scanner.scannerDriver();
if( !scanner.isDoneScanning() )
currentInputToken = scanner.peekNextToken();
if( printOutput ){
std::cout << "MATCH";
}
}
if( printOutput ){
std::cout << "\t\t" << currentStackValues;
}
}
}