forked from rperlste/UniversalCompiler
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathParser.cpp
89 lines (76 loc) · 2.55 KB
/
Parser.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
#include "Parser.h"
ParserDriver::ParserDriver( const Grammar& grammar, ParseTable* parseTable ){
this->grammar = grammar;
this->parseTable = new ParseTable(*parseTable);
}
void ParserDriver::LLDriver( std::fstream& programFile, bool printOutput ){
Scanner scanner( &programFile );
Token currentInputToken;
Symbol topStackSymbol;
std::string parseAction = "";
int position = 0;
if( printOutput ){
std::cout << "\n\n Parser Action RemainingInput Parse Stack\n"
<< " ---------------------------------------------------------------------------";
}
std::fstream* scannerFile = scanner.getProgramFile();
parseStack.push(grammar.getStartSymbol());
while( !isStackEmpty() ){
topStackSymbol = parseStack.top();
position = scanner.getScannerFilePosition();
currentInputToken = scanner.scan();
if( grammar.nonterminalSet.contains( topStackSymbol )){
try{
// Find production: X -> Y1 Y2 ... Ym
Production production = parseTable->getPredictProduction(
topStackSymbol, currentInputToken.getTokenTypeString() );
// Remove production X so that it can be replaced with it's derived production.
parseStack.pop();
if( printOutput ){
std::stringstream parseAction;
parseAction << grammar.productions.getIndex( production );
std::cout << "\n " << parseAction.str();
scannerFile->clear();
scannerFile->seekg( position );
std::string out;
if( !scannerFile->eof() ){
getline(*scannerFile, out);
std::cout << " " << out;
}
std::cout << " ";
for( int i = 0; i < production.getRHS().size(); i++ ){
std::cout << production[i] << " ";
}
scannerFile->clear();
scannerFile->seekg( position );
}
// Push production onto stack
for( int i = production.getRHS().size(); i > 0; i-- ){
parseStack.push(production[i-1]);
}
}
catch( ProductionNotFound e ){
std::string reason = "Error in production: ";
reason += topStackSymbol;
reason += " => Error occured at value: ";
reason += currentInputToken.getTokenTypeString();
throw SyntaxError( reason );
}
}
else if( grammar.terminalSet.contains( topStackSymbol )){
if( topStackSymbol == currentInputToken.getTokenTypeString() ){
parseStack.pop();
currentInputToken = scanner.scan();
}
}
else {
throw SyntaxError( "Error occured at value: " + currentInputToken.getTokenTypeString());
}
}
}
bool ParserDriver::isStackEmpty(){
return parseStack.empty();
}
ParserDriver::~ParserDriver(){
delete parseTable;
}