2013-07-31 23:51:05 -04:00
# include "RNGLRParser.h"
2013-07-28 19:45:08 -04:00
2013-07-31 23:51:05 -04:00
RNGLRParser : : RNGLRParser ( ) {
//
}
RNGLRParser : : ~ RNGLRParser ( ) {
//
}
NodeTree < Symbol * > * RNGLRParser : : parseInput ( std : : string inputString ) {
2013-07-28 19:45:08 -04:00
//Check for no tokens
2013-07-31 23:51:05 -04:00
bool accepting = false ;
2013-07-28 19:45:08 -04:00
if ( inputString = = " " ) {
2013-07-31 23:51:05 -04:00
std : : vector < ParseAction * > * zeroStateActions = table . get ( 0 , EOFSymbol ) ;
for ( int i = 0 ; i < zeroStateActions - > size ( ) ; i + + ) {
if ( ( * zeroStateActions ) [ i ] - > action = = ParseAction : : REDUCE )
accepting = true ;
}
if ( accepting )
2013-07-28 19:45:08 -04:00
std : : cout < < " Accepted! " < < std : : endl ;
else
std : : cout < < " Rejected, no input (with no accepting state) " < < std : : endl ;
2013-07-31 23:51:05 -04:00
return new NodeTree < Symbol * > ( ) ;
2013-07-28 19:45:08 -04:00
}
lexer . setInput ( inputString ) ;
//Now fully lex our input because this algorithm was designed in that manner and simplifies this first implementation.
//It could be converted to on-line later.
Symbol * currentToken = lexer . next ( ) ;
input . push_back ( currentToken ) ;
2013-07-31 23:51:05 -04:00
while ( * currentToken ! = * EOFSymbol ) {
std : : cout < < EOFSymbol - > toString ( ) < < " " < < currentToken - > toString ( ) < < std : : endl ;
2013-07-28 19:45:08 -04:00
currentToken = lexer . next ( ) ;
input . push_back ( currentToken ) ;
}
2013-07-31 23:51:05 -04:00
std : : cout < < " \n \n \n Done with Lexing \n \n \n " < < std : : endl ;
for ( int i = 0 ; i < input . size ( ) ; i + + )
std : : cout < < " | " < < input [ i ] - > toString ( ) < < " | " ;
std : : cout < < std : : endl ;
std : : cout < < " Setting up 0th frontier, first actions, toShift, toReduce " < < std : : endl ;
2013-07-28 19:45:08 -04:00
//Frontier 0, new node with state 0
2013-07-28 23:48:10 -04:00
NodeTree < int > * v0 = gss . newNode ( 0 ) ;
2013-07-28 19:45:08 -04:00
gss . addToFrontier ( 0 , v0 ) ;
2013-07-31 23:51:05 -04:00
std : : cout < < " Done setting up new frontier " < < std : : endl ;
std : : vector < ParseAction * > firstActions = * ( table . get ( 0 , input [ 0 ] ) ) ;
2013-07-28 19:45:08 -04:00
for ( std : : vector < ParseAction * > : : size_type i = 0 ; i < firstActions . size ( ) ; i + + ) {
if ( firstActions [ i ] - > action = = ParseAction : : SHIFT )
2013-07-31 23:51:05 -04:00
toShift . push ( std : : make_pair ( v0 , firstActions [ i ] - > shiftState ) ) ;
else if ( firstActions [ i ] - > action = = ParseAction : : REDUCE & & firstActions [ i ] - > reduceRule - > getRightSide ( ) . size ( ) = = 0 ) {
toReduce . push ( std : : make_pair ( std : : make_pair ( v0 , firstActions [ i ] - > reduceRule - > getLeftSide ( ) ) , 0 ) ) ;
2013-07-28 19:45:08 -04:00
}
}
2013-07-31 23:51:05 -04:00
std : : cout < < " GSS: \n " < < gss . toString ( ) < < std : : endl ;
std : : cout < < " Starting parse loop " < < std : : endl ;
2013-07-28 19:45:08 -04:00
for ( int i = 0 ; i < input . size ( ) ; i + + ) {
2013-07-31 23:51:05 -04:00
std : : cout < < " Checking if frontier " < < i < < " is empty " < < std : : endl ;
if ( gss . frontierIsEmpty ( i ) ) {
std : : cout < < " Frontier " < < i < < " is empty. " < < std : : endl ;
2013-07-28 19:45:08 -04:00
break ;
2013-07-31 23:51:05 -04:00
}
while ( toReduce . size ( ) ! = 0 ) {
std : : cout < < " Reducing for " < < i < < std : : endl ;
//std::cout << "GSS:\n" << gss.toString() << std::endl;
2013-07-28 19:45:08 -04:00
reducer ( i ) ;
2013-07-31 23:51:05 -04:00
}
std : : cout < < " Shifting for " < < i < < std : : endl ;
2013-07-28 19:45:08 -04:00
shifter ( i ) ;
2013-07-31 23:51:05 -04:00
std : : cout < < " GSS: \n " < < gss . toString ( ) < < std : : endl ;
2013-07-28 19:45:08 -04:00
}
2013-07-31 23:51:05 -04:00
std : : cout < < " Done with parsing loop, checking for acceptance " < < std : : endl ;
if ( gss . frontierHasAccState ( input . size ( ) - 1 ) )
2013-07-28 19:45:08 -04:00
std : : cout < < " Accepted! " < < std : : endl ;
else
std : : cout < < " Rejected! " < < std : : endl ;
2013-07-31 23:51:05 -04:00
std : : cout < < " GSS: \n " < < gss . toString ( ) < < std : : endl ;
return new NodeTree < Symbol * > ( ) ;
2013-07-28 19:45:08 -04:00
}
2013-07-31 23:51:05 -04:00
void RNGLRParser : : reducer ( int i ) {
2013-07-28 23:48:10 -04:00
std : : pair < std : : pair < NodeTree < int > * , Symbol * > , int > reduction = toReduce . front ( ) ;
2013-07-31 23:51:05 -04:00
toReduce . pop ( ) ;
std : : cout < < " Doing reduction of length " < < reduction . second < < " from state " < < reduction . first . first - > getData ( ) < < " to symbol " < < reduction . first . second - > toString ( ) < < std : : endl ;
int pathLength = reduction . second > 0 ? reduction . second - 1 : 0 ;
2013-07-28 23:48:10 -04:00
std : : vector < NodeTree < int > * > * reachable = gss . getReachable ( reduction . first . first , pathLength ) ;
for ( std : : vector < NodeTree < int > * > : : size_type j = 0 ; j < reachable - > size ( ) ; j + + ) {
NodeTree < int > * currentReached = ( * reachable ) [ j ] ;
2013-07-31 23:51:05 -04:00
std : : cout < < " Getting the shfit state for state " < < currentReached - > getData ( ) < < " and symbol " < < reduction . first . second - > toString ( ) < < std : : endl ;
int toState = table . getShift ( currentReached - > getData ( ) , reduction . first . second ) - > shiftState ;
2013-07-28 23:48:10 -04:00
NodeTree < int > * toStateNode = gss . inFrontier ( i , toState ) ;
2013-07-28 19:45:08 -04:00
if ( toStateNode ) {
if ( ! gss . hasEdge ( toStateNode , currentReached ) ) {
gss . addEdge ( toStateNode , currentReached ) ;
if ( reduction . second ! = 0 ) {
2013-07-31 23:51:05 -04:00
//Do all non null reduction
std : : vector < ParseAction * > actions = * ( table . get ( toState , input [ i ] ) ) ;
for ( std : : vector < ParseAction * > : : size_type k = 0 ; k < actions . size ( ) ; k + + )
if ( actions [ k ] - > action = = ParseAction : : REDUCE & & actions [ k ] - > reduceRule - > getRightSize ( ) ! = 0 )
toReduce . push ( std : : make_pair ( std : : make_pair ( currentReached , actions [ k ] - > reduceRule - > getLeftSide ( ) ) , actions [ k ] - > reduceRule - > getRightSize ( ) ) ) ;
2013-07-28 19:45:08 -04:00
}
}
} else {
toStateNode = gss . newNode ( toState ) ;
gss . addToFrontier ( i , toStateNode ) ;
gss . addEdge ( toStateNode , currentReached ) ;
2013-07-31 23:51:05 -04:00
std : : vector < ParseAction * > actions = * ( table . get ( toState , input [ i ] ) ) ;
2013-07-28 19:45:08 -04:00
for ( std : : vector < ParseAction * > : : size_type k = 0 ; k < actions . size ( ) ; k + + ) {
//Shift
if ( actions [ k ] - > action = = ParseAction : : SHIFT )
2013-07-31 23:51:05 -04:00
toShift . push ( std : : make_pair ( toStateNode , actions [ k ] - > shiftState ) ) ;
else if ( actions [ k ] - > action = = ParseAction : : REDUCE & & actions [ k ] - > reduceRule - > getRightSize ( ) ! = 0 )
toReduce . push ( std : : make_pair ( std : : make_pair ( currentReached , actions [ k ] - > reduceRule - > getLeftSide ( ) ) , actions [ k ] - > reduceRule - > getRightSize ( ) ) ) ;
else if ( actions [ k ] - > action = = ParseAction : : REDUCE & & actions [ k ] - > reduceRule - > getRightSize ( ) = = 0 )
toReduce . push ( std : : make_pair ( std : : make_pair ( toStateNode , actions [ k ] - > reduceRule - > getLeftSide ( ) ) , actions [ k ] - > reduceRule - > getRightSize ( ) ) ) ;
2013-07-28 19:45:08 -04:00
}
}
}
}
2013-07-31 23:51:05 -04:00
void RNGLRParser : : shifter ( int i ) {
if ( i ! = input . size ( ) - 1 ) {
std : : queue < std : : pair < NodeTree < int > * , int > > nextShifts ;
2013-07-28 19:45:08 -04:00
while ( ! toShift . empty ( ) ) {
2013-07-28 23:48:10 -04:00
std : : pair < NodeTree < int > * , int > shift = toShift . front ( ) ;
2013-07-31 23:51:05 -04:00
toShift . pop ( ) ;
std : : cout < < " Current potential shift from " < < shift . first - > getData ( ) < < " to " < < shift . second < < std : : endl ;
2013-07-28 23:48:10 -04:00
NodeTree < int > * shiftTo = gss . inFrontier ( i + 1 , shift . second ) ;
2013-07-28 19:45:08 -04:00
if ( shiftTo ) {
2013-07-31 23:51:05 -04:00
std : : cout < < " State already existed, just adding edge " < < std : : endl ;
2013-07-28 19:45:08 -04:00
gss . addEdge ( shiftTo , shift . first ) ;
2013-07-31 23:51:05 -04:00
std : : vector < ParseAction * > actions = * ( table . get ( shift . second , input [ i + 1 ] ) ) ;
2013-07-28 19:45:08 -04:00
for ( std : : vector < ParseAction * > : : size_type j = 0 ; j < actions . size ( ) ; j + + ) {
2013-07-31 23:51:05 -04:00
if ( actions [ j ] - > action = = ParseAction : : REDUCE & & actions [ j ] - > reduceRule - > getRightSize ( ) ! = 0 )
toReduce . push ( std : : make_pair ( std : : make_pair ( shift . first , actions [ j ] - > reduceRule - > getLeftSide ( ) ) , actions [ j ] - > reduceRule - > getRightSize ( ) ) ) ;
2013-07-28 19:45:08 -04:00
}
} else {
2013-07-31 23:51:05 -04:00
std : : cout < < " State did not already exist, adding " < < std : : endl ;
2013-07-28 19:45:08 -04:00
shiftTo = gss . newNode ( shift . second ) ;
gss . addToFrontier ( i + 1 , shiftTo ) ;
gss . addEdge ( shiftTo , shift . first ) ;
2013-07-31 23:51:05 -04:00
std : : vector < ParseAction * > actions = * ( table . get ( shift . second , input [ i + 1 ] ) ) ;
2013-07-28 19:45:08 -04:00
for ( std : : vector < ParseAction * > : : size_type j = 0 ; j < actions . size ( ) ; j + + ) {
2013-07-31 23:51:05 -04:00
std : : cout < < " Adding action " < < actions [ j ] - > toString ( ) < < " to either nextShifts or toReduce " < < std : : endl ;
2013-07-28 19:45:08 -04:00
//Shift
if ( actions [ j ] - > action = = ParseAction : : SHIFT )
2013-07-31 23:51:05 -04:00
nextShifts . push ( std : : make_pair ( shiftTo , actions [ j ] - > shiftState ) ) ;
else if ( actions [ j ] - > action = = ParseAction : : REDUCE & & actions [ j ] - > reduceRule - > getRightSize ( ) ! = 0 )
toReduce . push ( std : : make_pair ( std : : make_pair ( shift . first , actions [ j ] - > reduceRule - > getLeftSide ( ) ) , actions [ j ] - > reduceRule - > getRightSize ( ) ) ) ;
else if ( actions [ j ] - > action = = ParseAction : : REDUCE & & actions [ j ] - > reduceRule - > getRightSize ( ) = = 0 )
toReduce . push ( std : : make_pair ( std : : make_pair ( shiftTo , actions [ j ] - > reduceRule - > getLeftSide ( ) ) , actions [ j ] - > reduceRule - > getRightSize ( ) ) ) ;
2013-07-28 19:45:08 -04:00
}
}
}
toShift = nextShifts ;
}
}