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 ( ) {
//
}
2014-06-30 01:57:50 -07:00
void RNGLRParser : : printReconstructedFrontier ( int frontier ) {
std : : vector < int > lastFrontier = gss . getFrontier ( frontier ) ;
for ( int j = 0 ; j < lastFrontier . size ( ) ; j + + ) {
std : : cout < < " State: " < < lastFrontier [ j ] < < std : : endl ;
std : : vector < std : : pair < std : : string , ParseAction > > stateParseActions = table . stateAsParseActionVector ( lastFrontier [ j ] ) ;
std : : set < std : : pair < std : : string , ParseAction > > noRepeats ;
for ( auto k : stateParseActions )
noRepeats . insert ( k ) ;
for ( auto k : noRepeats )
std : : cout < < k . first < < " " < < k . second . toString ( false ) < < std : : endl ;
std : : cout < < std : : endl ;
}
}
2013-10-02 03:15:20 -04:00
NodeTree < Symbol > * RNGLRParser : : parseInput ( std : : string inputString ) {
2013-12-31 23:43:49 -06:00
input . clear ( ) ;
gss . clear ( ) ;
while ( ! toReduce . empty ( ) ) toReduce . pop ( ) ;
while ( ! toShift . empty ( ) ) toReduce . pop ( ) ;
SPPFStepNodes . clear ( ) ;
nullableParts . clear ( ) ;
packedMap . clear ( ) ;
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 ;
}
2013-08-08 02:44:17 -04:00
if ( accepting ) {
2013-07-28 19:45:08 -04:00
std : : cout < < " Accepted! " < < std : : endl ;
2013-08-09 04:39:43 -04:00
return getNullableParts ( ( * ( stateSets [ 0 ] - > getBasis ( ) ) ) [ 0 ] - > getLeftSide ( ) ) ;
2013-08-08 02:44:17 -04:00
} else {
2015-03-14 02:42:07 -04:00
std : : cerr < < " Rejected, no input (with no accepting state) " < < std : : endl ;
2013-08-08 02:44:17 -04:00
}
2013-10-02 03:15:20 -04:00
return new NodeTree < Symbol > ( ) ;
2013-07-28 19:45:08 -04:00
}
2013-12-31 23:43:49 -06:00
lexer . reset ( ) ;
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.
2013-10-02 03:15:20 -04:00
Symbol currentToken = lexer . next ( ) ;
2013-07-28 19:45:08 -04:00
input . push_back ( currentToken ) ;
2013-10-02 03:15:20 -04:00
while ( currentToken ! = EOFSymbol ) {
2013-07-28 19:45:08 -04:00
currentToken = lexer . next ( ) ;
2013-11-01 02:52:18 -04:00
//std::cout << "CurrentToken is " << currentToken.toString() << std::endl;
if ( currentToken = = invalidSymbol ) {
2015-03-14 02:42:07 -04:00
std : : cerr < < " Invalid Symbol! " < < std : : endl ;
2013-11-01 02:52:18 -04:00
throw " Invalid Symbol, cannot lex " ;
}
2013-10-02 03:15:20 -04:00
input . push_back ( currentToken ) ;
2013-07-28 19:45:08 -04:00
}
2014-01-01 17:29:19 -06:00
// std::cout << "\nDone with Lexing, length:" << input.size() << std::endl;
// std::cout << input[0].toString() << std::endl;
2013-07-31 23:51:05 -04:00
2014-06-30 01:57:50 -07:00
2013-08-16 00:03:26 -04:00
// for (int i = 0; i < input.size(); i++)
// std::cout << "|" << input[i]->toString() << "|";
// std::cout << std::endl;
2013-07-31 23:51:05 -04:00
2014-01-01 17:29:19 -06:00
//std::cout << "Setting up 0th frontier, first actions, toShift, toReduce" << std::endl;
2013-07-31 23:51:05 -04:00
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 ) ;
2014-01-01 17:29:19 -06:00
//std::cout << "Done setting up new frontier" << std::endl;
2013-07-31 23:51:05 -04:00
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 ) ) ;
2013-08-13 14:01:53 -04:00
else if ( firstActions [ i ] - > action = = ParseAction : : REDUCE & & fullyReducesToNull ( firstActions [ i ] - > reduceRule ) ) {
2013-08-12 00:02:50 -04:00
Reduction newReduction = { v0 , firstActions [ i ] - > reduceRule - > getLeftSide ( ) , 0 , getNullableParts ( firstActions [ i ] - > reduceRule ) , NULL } ;
2013-08-08 02:44:17 -04:00
toReduce . push ( newReduction ) ;
2013-07-28 19:45:08 -04:00
}
}
2013-08-16 00:03:26 -04:00
// std::cout << "GSS:\n" << gss.toString() << std::endl;
2013-07-31 23:51:05 -04:00
2014-01-01 17:29:19 -06:00
//std::cout << "Starting parse loop" << std::endl;
2013-07-31 23:51:05 -04:00
2013-07-28 19:45:08 -04:00
for ( int i = 0 ; i < input . size ( ) ; i + + ) {
2013-08-16 00:03:26 -04:00
// std::cout << "Checking if frontier " << i << " is empty" << std::endl;
2013-07-31 23:51:05 -04:00
if ( gss . frontierIsEmpty ( i ) ) {
2014-02-20 18:24:04 -05:00
//std::cout << "Frontier " << i << " is empty." << std::endl;
2015-03-14 02:42:07 -04:00
std : : cerr < < " Parsing failed on " < < input [ i ] . toString ( ) < < std : : endl ;
std : : cerr < < " Problem is on line: " < < findLine ( i ) < < std : : endl ;
std : : cerr < < " Nearby is: " < < std : : endl ;
2014-06-30 01:57:50 -07:00
int range = 10 ;
2013-08-27 13:23:37 -04:00
for ( int j = ( i - range > = 0 ? i - range : 0 ) ; j < ( i + range < input . size ( ) ? i + range : input . size ( ) ) ; j + + )
2013-12-18 18:05:21 -06:00
if ( j = = i )
2015-03-14 02:42:07 -04:00
std : : cerr < < " ||*||*|| " < < input [ j ] . toString ( ) < < " ||*||*|| " ;
2013-12-18 18:05:21 -06:00
else
2015-03-14 02:42:07 -04:00
std : : cerr < < input [ j ] . toString ( ) < < " " ;
std : : cerr < < std : : endl ;
2014-07-02 01:18:27 -07:00
range = 1 ;
2014-07-18 08:52:15 -07:00
/* std::cout << "\n\n\nThe states in the GSS at last frontiers:" << std::endl;
2014-06-30 01:57:50 -07:00
for ( int j = ( i - range > = 0 ? i - range : 0 ) ; j < i ; j + + ) {
std : : cout < < " Frontier: " < < j < < " (would get): " < < input [ j ] . toString ( ) < < std : : endl ;
printReconstructedFrontier ( j ) ;
}
std : : cout < < " \n \n \n \n " < < std : : endl ;
2014-07-18 08:52:15 -07:00
*/ break ;
2013-07-31 23:51:05 -04:00
}
2013-08-08 02:44:17 -04:00
//Clear the vector of SPPF nodes created every step
SPPFStepNodes . clear ( ) ;
2013-07-31 23:51:05 -04:00
while ( toReduce . size ( ) ! = 0 ) {
2013-08-16 00:03:26 -04:00
//std::cout << "Reducing for " << i << std::endl;
2013-07-31 23:51:05 -04:00
//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
}
2013-08-16 00:03:26 -04:00
// std::cout << "Shifting for " << i << std::endl;
2013-07-28 19:45:08 -04:00
shifter ( i ) ;
2013-08-16 00:03:26 -04:00
//std::cout << "GSS:\n" << gss.toString() << std::endl;
2013-07-28 19:45:08 -04:00
}
2014-01-01 17:29:19 -06:00
//std::cout << "Done with parsing loop, checking for acceptance" << std::endl;
2013-08-09 04:39:43 -04:00
NodeTree < int > * accState = gss . frontierGetAccState ( input . size ( ) - 1 ) ;
2013-08-08 02:44:17 -04:00
if ( accState ) {
2013-07-28 19:45:08 -04:00
std : : cout < < " Accepted! " < < std : : endl ;
2013-08-08 02:44:17 -04:00
return gss . getEdge ( accState , v0 ) ;
}
2013-07-31 23:51:05 -04:00
2015-03-14 02:42:07 -04:00
std : : cerr < < " Rejected! " < < std : : endl ;
2014-02-20 18:24:04 -05:00
// std::cout << "GSS:\n" << gss.toString() << std::endl;
2013-08-08 02:44:17 -04:00
return NULL ;
2013-07-28 19:45:08 -04:00
}
2013-07-31 23:51:05 -04:00
void RNGLRParser : : reducer ( int i ) {
2013-08-08 02:44:17 -04:00
Reduction reduction = toReduce . front ( ) ;
2013-07-31 23:51:05 -04:00
toReduce . pop ( ) ;
2013-08-16 00:03:26 -04:00
//std::cout << "Doing reduction of length " << reduction.length << " from state " << reduction.from->getData() << " to symbol " << reduction.symbol->toString() << std::endl;
2013-08-08 02:44:17 -04:00
int pathLength = reduction . length > 0 ? reduction . length - 1 : 0 ;
//Get every reachable path
std : : vector < std : : vector < NodeTree < int > * > > * paths = gss . getReachablePaths ( reduction . from , pathLength ) ;
for ( std : : vector < std : : vector < NodeTree < int > * > > : : size_type j = 0 ; j < paths - > size ( ) ; j + + ) {
std : : vector < NodeTree < int > * > currentPath = ( * paths ) [ j ] ;
//Get the edges for the current path
2013-10-02 03:15:20 -04:00
std : : vector < NodeTree < Symbol > * > pathEdges = getPathEdges ( currentPath ) ;
2013-08-10 18:24:37 -04:00
std : : reverse ( pathEdges . begin ( ) , pathEdges . end ( ) ) ;
2013-08-08 02:44:17 -04:00
//If the reduction length is 0, label as passed in is null
if ( reduction . length ! = 0 )
pathEdges . push_back ( reduction . label ) ;
2013-08-10 18:24:37 -04:00
//The end of the current path
NodeTree < int > * currentReached = currentPath [ currentPath . size ( ) - 1 ] ;
2013-08-08 02:44:17 -04:00
2014-01-01 17:29:19 -06:00
//std::cout << "Getting the shift state for state " << currentReached->getData() << " and symbol " << reduction.symbol.toString() << std::endl;
2013-08-08 02:44:17 -04:00
int toState = table . getShift ( currentReached - > getData ( ) , reduction . symbol ) - > shiftState ;
//If reduction length is 0, then we make the new label the appropriate nullable parts
2013-10-02 03:15:20 -04:00
NodeTree < Symbol > * newLabel = NULL ;
2013-08-08 02:44:17 -04:00
if ( reduction . length = = 0 ) {
2013-08-12 00:02:50 -04:00
newLabel = reduction . nullableParts ;
2013-08-08 02:44:17 -04:00
} else {
//Otherwise, we create the new label if we haven't already
int reachedFrontier = gss . getContainingFrontier ( currentReached ) ;
2013-10-02 03:15:20 -04:00
for ( std : : vector < std : : pair < NodeTree < Symbol > * , int > > : : size_type k = 0 ; k < SPPFStepNodes . size ( ) ; k + + ) {
if ( SPPFStepNodes [ k ] . second = = reachedFrontier & & SPPFStepNodes [ k ] . first - > getData ( ) = = reduction . symbol ) {
2013-08-08 02:44:17 -04:00
newLabel = SPPFStepNodes [ k ] . first ;
break ;
}
}
if ( ! newLabel ) {
2013-10-02 03:15:20 -04:00
newLabel = new NodeTree < Symbol > ( " frontier: " + intToString ( reachedFrontier ) , reduction . symbol ) ;
2013-08-08 02:44:17 -04:00
SPPFStepNodes . push_back ( std : : make_pair ( newLabel , reachedFrontier ) ) ;
}
}
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 ) ) {
2013-08-08 02:44:17 -04:00
gss . addEdge ( toStateNode , currentReached , newLabel ) ;
if ( reduction . length ! = 0 ) {
2013-07-31 23:51:05 -04:00
//Do all non null reduction
2013-08-16 00:03:26 -04:00
//std::cout << "Checking for non-null reductions in states that already existed" << std::endl;
2013-07-31 23:51:05 -04:00
std : : vector < ParseAction * > actions = * ( table . get ( toState , input [ i ] ) ) ;
2013-08-08 02:44:17 -04:00
for ( std : : vector < ParseAction * > : : size_type k = 0 ; k < actions . size ( ) ; k + + ) {
2013-08-13 14:01:53 -04:00
if ( actions [ k ] - > action = = ParseAction : : REDUCE & & ! fullyReducesToNull ( actions [ k ] - > reduceRule ) ) {
Reduction newReduction = { currentReached , actions [ k ] - > reduceRule - > getLeftSide ( ) , actions [ k ] - > reduceRule - > getIndex ( ) , getNullableParts ( actions [ k ] - > reduceRule ) , newLabel } ;
2013-08-08 02:44:17 -04:00
toReduce . push ( newReduction ) ;
}
}
2013-07-28 19:45:08 -04:00
}
}
} else {
toStateNode = gss . newNode ( toState ) ;
gss . addToFrontier ( i , toStateNode ) ;
2013-08-08 02:44:17 -04:00
gss . addEdge ( toStateNode , currentReached , newLabel ) ;
2014-06-30 01:57:50 -07:00
2013-08-16 00:03:26 -04:00
//std::cout << "Adding shifts and reductions for a state that did not exist" << std::endl;
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 + + ) {
2014-01-01 17:29:19 -06:00
//std::cout << "Action is " << actions[k]->toString() << std::endl;
2013-08-08 02:44:17 -04:00
if ( actions [ k ] - > action = = ParseAction : : SHIFT ) {
2013-07-31 23:51:05 -04:00
toShift . push ( std : : make_pair ( toStateNode , actions [ k ] - > shiftState ) ) ;
2013-08-13 14:01:53 -04:00
} else if ( actions [ k ] - > action = = ParseAction : : REDUCE & & fullyReducesToNull ( actions [ k ] - > reduceRule ) ) {
2013-08-12 00:02:50 -04:00
Reduction newReduction = { toStateNode , actions [ k ] - > reduceRule - > getLeftSide ( ) , 0 , getNullableParts ( actions [ k ] - > reduceRule ) , NULL } ;
2013-08-08 02:44:17 -04:00
toReduce . push ( newReduction ) ;
2013-08-13 14:01:53 -04:00
} else if ( reduction . length ! = 0 & & actions [ k ] - > action = = ParseAction : : REDUCE & & ! fullyReducesToNull ( actions [ k ] - > reduceRule ) ) {
Reduction newReduction = { currentReached , actions [ k ] - > reduceRule - > getLeftSide ( ) , actions [ k ] - > reduceRule - > getIndex ( ) , getNullableParts ( actions [ k ] - > reduceRule ) , newLabel } ;
2013-08-08 02:44:17 -04:00
toReduce . push ( newReduction ) ;
}
2013-07-28 19:45:08 -04:00
}
}
2013-08-08 02:44:17 -04:00
if ( reduction . length ! = 0 )
2013-08-12 00:02:50 -04:00
addChildren ( newLabel , & pathEdges , reduction . nullableParts ) ;
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-10-02 03:15:20 -04:00
NodeTree < Symbol > * newLabel = new NodeTree < Symbol > ( " frontier: " + intToString ( i ) , input [ i ] ) ;
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 ( ) ;
2014-01-01 17:29:19 -06:00
//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-08-16 00:03:26 -04:00
//std::cout << "State already existed, just adding edge" << std::endl;
2013-08-09 04:39:43 -04:00
gss . addEdge ( shiftTo , shift . first , newLabel ) ;
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-08-13 14:01:53 -04:00
if ( actions [ j ] - > action = = ParseAction : : REDUCE & & ! fullyReducesToNull ( actions [ j ] - > reduceRule ) ) {
Reduction newReduction = { shift . first , actions [ j ] - > reduceRule - > getLeftSide ( ) , actions [ j ] - > reduceRule - > getIndex ( ) , getNullableParts ( actions [ j ] - > reduceRule ) , newLabel } ;
2013-08-08 02:44:17 -04:00
toReduce . push ( newReduction ) ;
}
2013-07-28 19:45:08 -04:00
}
} else {
2013-08-16 00:03:26 -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 ) ;
2013-08-08 02:44:17 -04:00
gss . addEdge ( shiftTo , shift . first , newLabel ) ;
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 + + ) {
2014-01-01 17:29:19 -06:00
//std::cout << "Adding action " << actions[j]->toString() << " to either nextShifts or toReduce" << std::endl;
2013-07-28 19:45:08 -04:00
//Shift
2013-08-08 02:44:17 -04:00
if ( actions [ j ] - > action = = ParseAction : : SHIFT ) {
2013-07-31 23:51:05 -04:00
nextShifts . push ( std : : make_pair ( shiftTo , actions [ j ] - > shiftState ) ) ;
2013-08-13 14:01:53 -04:00
} else if ( actions [ j ] - > action = = ParseAction : : REDUCE & & ! fullyReducesToNull ( actions [ j ] - > reduceRule ) ) {
Reduction newReduction = { shift . first , actions [ j ] - > reduceRule - > getLeftSide ( ) , actions [ j ] - > reduceRule - > getIndex ( ) , getNullableParts ( actions [ j ] - > reduceRule ) , newLabel } ;
2013-08-08 02:44:17 -04:00
toReduce . push ( newReduction ) ;
2013-08-13 14:01:53 -04:00
} else if ( actions [ j ] - > action = = ParseAction : : REDUCE & & fullyReducesToNull ( actions [ j ] - > reduceRule ) ) {
2013-08-12 00:02:50 -04:00
Reduction newReduction = { shiftTo , actions [ j ] - > reduceRule - > getLeftSide ( ) , 0 , getNullableParts ( actions [ j ] - > reduceRule ) , NULL } ;
2013-08-08 02:44:17 -04:00
toReduce . push ( newReduction ) ;
}
2013-07-28 19:45:08 -04:00
}
}
}
toShift = nextShifts ;
}
2013-08-02 02:47:01 -04:00
}
2013-10-02 03:15:20 -04:00
void RNGLRParser : : addChildren ( NodeTree < Symbol > * parent , std : : vector < NodeTree < Symbol > * > * children , NodeTree < Symbol > * nullableParts ) {
2013-08-12 00:02:50 -04:00
if ( nullableParts )
children - > push_back ( nullableParts ) ;
2013-08-13 14:01:53 -04:00
2013-08-06 01:49:45 -04:00
if ( ! belongsToFamily ( parent , children ) ) {
if ( parent - > getChildren ( ) . size ( ) = = 0 ) {
parent - > addChildren ( children ) ;
} else {
if ( ! arePacked ( parent - > getChildren ( ) ) ) {
2013-10-02 03:15:20 -04:00
NodeTree < Symbol > * subParent = new NodeTree < Symbol > ( " AmbiguityPackInner " , Symbol ( " AmbiguityPackInner " , true ) ) ;
2013-08-06 01:49:45 -04:00
setPacked ( subParent , true ) ;
2013-10-02 03:15:20 -04:00
std : : vector < NodeTree < Symbol > * > tmp = parent - > getChildren ( ) ;
2013-08-09 04:39:43 -04:00
subParent - > addChildren ( & tmp ) ;
2013-08-06 01:49:45 -04:00
parent - > clearChildren ( ) ;
parent - > addChild ( subParent ) ;
}
2013-10-02 03:15:20 -04:00
NodeTree < Symbol > * t = new NodeTree < Symbol > ( " AmbiguityPackOuter " , Symbol ( " AmbiguityPackInner " , true ) ) ;
2013-08-06 01:49:45 -04:00
setPacked ( t , true ) ;
parent - > addChild ( t ) ;
t - > addChildren ( children ) ;
}
}
}
2013-10-02 03:15:20 -04:00
bool RNGLRParser : : belongsToFamily ( NodeTree < Symbol > * node , std : : vector < NodeTree < Symbol > * > * nodes ) {
2013-08-16 00:03:26 -04:00
//std::cout << "Checking " << node->getData()->toString() << "'s family" << std::endl;
2013-10-02 03:15:20 -04:00
std : : vector < NodeTree < Symbol > * > children = node - > getChildren ( ) ;
for ( std : : vector < NodeTree < Symbol > * > : : size_type i = 0 ; i < nodes - > size ( ) ; i + + ) {
2013-08-08 02:44:17 -04:00
bool containsOne = false ;
2013-10-02 03:15:20 -04:00
for ( std : : vector < NodeTree < Symbol > * > : : size_type j = 0 ; j < children . size ( ) ; j + + ) {
2013-08-09 04:39:43 -04:00
//Not sure where null comes from. For right now, just check to be sure we don't segfault
2013-09-26 15:16:58 -04:00
if ( ( * nodes ) [ i ] = = children [ j ] | | ( ( * nodes ) [ i ] ! = NULL & & children [ j ] ! = NULL & & ( * ( * nodes ) [ i ] ) = = * ( children [ j ] ) ) ) {
2013-08-08 02:44:17 -04:00
containsOne = true ;
break ;
}
}
if ( ! containsOne ) {
return false ;
}
}
return true ;
2013-08-06 01:49:45 -04:00
}
2013-10-02 03:15:20 -04:00
bool RNGLRParser : : arePacked ( std : : vector < NodeTree < Symbol > * > nodes ) {
2013-08-06 01:49:45 -04:00
bool packed = true ;
2013-10-02 03:15:20 -04:00
for ( std : : vector < NodeTree < Symbol > * > : : size_type i = 0 ; i < nodes . size ( ) ; i + + )
2013-08-09 04:39:43 -04:00
packed & = packedMap [ * ( nodes [ i ] ) ] ;
2013-08-06 01:49:45 -04:00
return packed ;
}
2013-10-02 03:15:20 -04:00
bool RNGLRParser : : isPacked ( NodeTree < Symbol > * node ) {
2013-08-09 04:39:43 -04:00
return packedMap [ * node ] ;
2013-08-06 01:49:45 -04:00
}
2013-10-02 03:15:20 -04:00
void RNGLRParser : : setPacked ( NodeTree < Symbol > * node , bool isPacked ) {
2013-08-09 04:39:43 -04:00
packedMap [ * node ] = isPacked ;
2013-08-06 01:49:45 -04:00
}
2013-08-02 02:47:01 -04:00
//Have to use own add states function in order to construct RN table instead of LALR table
2013-08-22 15:41:30 -04:00
void RNGLRParser : : addStates ( std : : vector < State * > * stateSets , State * state , std : : queue < State * > * toDo ) {
2013-08-02 02:47:01 -04:00
std : : vector < State * > newStates ;
//For each rule in the state we already have
std : : vector < ParseRule * > * currStateTotal = state - > getTotal ( ) ;
for ( std : : vector < ParseRule * > : : size_type i = 0 ; i < currStateTotal - > size ( ) ; i + + ) {
//Clone the current rule
ParseRule * advancedRule = ( * currStateTotal ) [ i ] - > clone ( ) ;
//Try to advance the pointer, if sucessful see if it is the correct next symbol
2014-06-30 01:57:50 -07:00
if ( advancedRule - > advancePointer ( ) ) {
2013-08-02 02:47:01 -04:00
//Technically, it should be the set of rules sharing this symbol advanced past in the basis for new state
//So search our new states to see if any of them use this advanced symbol as a base.
//If so, add this rule to them.
//If not, create it.
bool symbolAlreadyInState = false ;
for ( std : : vector < State * > : : size_type j = 0 ; j < newStates . size ( ) ; j + + ) {
2013-10-02 03:15:20 -04:00
if ( newStates [ j ] - > basis [ 0 ] - > getAtIndex ( ) = = advancedRule - > getAtIndex ( ) ) {
2013-08-02 02:47:01 -04:00
symbolAlreadyInState = true ;
2013-08-16 00:03:26 -04:00
//Add rule to state, combining with idenical rule except lookahead if exists
newStates [ j ] - > addRuleCombineLookahead ( advancedRule ) ;
2013-08-02 02:47:01 -04:00
//We found a state with the same symbol, so stop searching
break ;
}
}
if ( ! symbolAlreadyInState ) {
State * newState = new State ( stateSets - > size ( ) + newStates . size ( ) , advancedRule , state ) ;
newStates . push_back ( newState ) ;
}
}
}
//Put all our new states in the set of states only if they're not already there.
bool stateAlreadyInAllStates = false ;
2013-10-02 03:15:20 -04:00
Symbol currStateSymbol ;
2013-08-02 02:47:01 -04:00
for ( std : : vector < State * > : : size_type i = 0 ; i < newStates . size ( ) ; i + + ) {
stateAlreadyInAllStates = false ;
currStateSymbol = ( * ( newStates [ i ] - > getBasis ( ) ) ) [ 0 ] - > getAtIndex ( ) ;
for ( std : : vector < State * > : : size_type j = 0 ; j < stateSets - > size ( ) ; j + + ) {
2013-08-16 00:03:26 -04:00
if ( newStates [ i ] - > basisEqualsExceptLookahead ( * ( ( * stateSets ) [ j ] ) ) ) {
2013-08-26 15:37:49 -04:00
//if (newStates[i]->basisEquals(*((*stateSets)[j]))) {
2013-08-02 02:47:01 -04:00
stateAlreadyInAllStates = true ;
//If it does exist, we should add it as the shift/goto in the action table
2013-12-18 18:05:21 -06:00
//std::cout << "newStates[" << i << "] == stateSets[" << j << "]" << std::endl;
2014-06-30 01:57:50 -07:00
2013-08-23 01:51:58 -04:00
if ( ! ( ( * stateSets ) [ j ] - > basisEquals ( * ( newStates [ i ] ) ) ) )
2013-08-22 15:41:30 -04:00
toDo - > push ( ( * stateSets ) [ j ] ) ;
2014-06-30 01:57:50 -07:00
2013-08-16 00:03:26 -04:00
( * stateSets ) [ j ] - > combineStates ( * ( newStates [ i ] ) ) ;
2013-12-18 18:05:21 -06:00
//std::cout << j << "\t Hay, doing an inside loop state reductions!" << std::endl;
2013-08-16 00:03:26 -04:00
addStateReductionsToTable ( ( * stateSets ) [ j ] ) ;
2013-08-02 02:47:01 -04:00
table . add ( stateNum ( state ) , currStateSymbol , new ParseAction ( ParseAction : : SHIFT , j ) ) ;
2013-08-26 15:37:49 -04:00
2013-08-02 02:47:01 -04:00
break ;
}
}
if ( ! stateAlreadyInAllStates ) {
//If the state does not already exist, add it and add it as the shift/goto in the action table
stateSets - > push_back ( newStates [ i ] ) ;
2013-08-22 15:41:30 -04:00
toDo - > push ( newStates [ i ] ) ;
2013-08-02 02:47:01 -04:00
table . add ( stateNum ( state ) , currStateSymbol , new ParseAction ( ParseAction : : SHIFT , stateSets - > size ( ) - 1 ) ) ;
}
}
2013-08-16 00:03:26 -04:00
addStateReductionsToTable ( state ) ;
}
2013-08-26 15:37:49 -04:00
2013-08-16 00:03:26 -04:00
void RNGLRParser : : addStateReductionsToTable ( State * state ) {
std : : vector < ParseRule * > * currStateTotal = state - > getTotal ( ) ;
2014-01-19 18:20:52 -05:00
//std::cout << currStateTotal->size() << "::" << state->getNumber() << std::endl;
2013-08-16 00:03:26 -04:00
for ( std : : vector < ParseRule * > : : size_type i = 0 ; i < currStateTotal - > size ( ) ; i + + ) {
//See if reduce
//Also, this really only needs to be done for the state's basis, but we're already iterating through, so...
2013-10-02 03:15:20 -04:00
std : : vector < Symbol > * lookahead = ( * currStateTotal ) [ i ] - > getLookahead ( ) ;
2013-08-16 00:03:26 -04:00
if ( ( * currStateTotal ) [ i ] - > isAtEnd ( ) ) {
2013-12-18 18:05:21 -06:00
for ( std : : vector < Symbol > : : size_type j = 0 ; j < lookahead - > size ( ) ; j + + ) {
2013-08-16 00:03:26 -04:00
table . add ( stateNum ( state ) , ( * lookahead ) [ j ] , new ParseAction ( ParseAction : : REDUCE , ( * currStateTotal ) [ i ] ) ) ;
2013-12-18 18:05:21 -06:00
}
2013-08-16 00:03:26 -04:00
//If this has an appropriate ruduction to null, get the reduce trees out
} else if ( reducesToNull ( ( * currStateTotal ) [ i ] ) ) {
//std::cout << (*currStateTotal)[i]->toString() << " REDUCES TO NULL" << std::endl;
2013-08-26 15:37:49 -04:00
//It used to be that if is a rule that produces only NULL, add in the approprite reduction, but use a new rule with a right side that is equal to
2013-08-16 00:03:26 -04:00
//the part that we've already gone through in the rule. (so we don't pop extra off stack)
//Now we use the same rule and make sure that the index location is used
2013-10-02 03:15:20 -04:00
for ( std : : vector < Symbol > : : size_type j = 0 ; j < lookahead - > size ( ) ; j + + )
2013-08-16 00:03:26 -04:00
table . add ( stateNum ( state ) , ( * lookahead ) [ j ] , new ParseAction ( ParseAction : : REDUCE , ( * currStateTotal ) [ i ] ) ) ;
}
}
2013-08-02 15:21:42 -04:00
}
2013-08-13 14:01:53 -04:00
bool RNGLRParser : : fullyReducesToNull ( ParseRule * rule ) {
return rule - > getIndex ( ) = = 0 & & reducesToNull ( rule ) ;
}
2013-08-02 15:21:42 -04:00
bool RNGLRParser : : reducesToNull ( ParseRule * rule ) {
2013-10-02 03:15:20 -04:00
std : : vector < Symbol > avoidList ;
2013-08-02 15:21:42 -04:00
return reducesToNull ( rule , avoidList ) ;
}
2013-10-02 03:15:20 -04:00
bool RNGLRParser : : reducesToNull ( ParseRule * rule , std : : vector < Symbol > avoidList ) {
2013-08-12 00:02:50 -04:00
//If the rule is completed and not null, it doesn't reduce to null, it's just completed.
if ( rule - > isAtEnd ( ) & & rule - > getRightSize ( ) ! = 0 )
return false ;
2013-10-02 03:15:20 -04:00
for ( std : : vector < Symbol > : : size_type i = 0 ; i < avoidList . size ( ) ; i + + )
if ( rule - > getLeftSide ( ) = = avoidList [ i ] )
2013-08-02 15:21:42 -04:00
return false ;
avoidList . push_back ( rule - > getLeftSide ( ) ) ;
2013-10-02 03:15:20 -04:00
std : : vector < Symbol > rightSide = rule - > getRightSide ( ) ;
2013-08-02 15:21:42 -04:00
bool reduces = true ;
2013-10-02 03:15:20 -04:00
for ( std : : vector < Symbol > : : size_type i = rule - > getIndex ( ) ; i < rightSide . size ( ) ; i + + ) {
if ( rightSide [ i ] = = nullSymbol )
2013-08-02 15:21:42 -04:00
continue ;
2013-10-02 03:15:20 -04:00
if ( rightSide [ i ] . isTerminal ( ) ) {
2013-08-02 15:21:42 -04:00
reduces = false ;
break ;
}
bool subSymbolReduces = false ;
for ( std : : vector < ParseRule * > : : size_type j = 0 ; j < loadedGrammer . size ( ) ; j + + ) {
2013-10-02 03:15:20 -04:00
if ( loadedGrammer [ j ] - > getLeftSide ( ) = = rightSide [ i ] ) {
2013-08-02 15:21:42 -04:00
if ( reducesToNull ( loadedGrammer [ j ] , avoidList ) ) {
subSymbolReduces = true ;
break ;
}
}
}
if ( ! subSymbolReduces ) {
reduces = false ;
break ;
}
}
return reduces ;
}
2013-10-02 03:15:20 -04:00
NodeTree < Symbol > * RNGLRParser : : getNullableParts ( ParseRule * rule ) {
return getNullableParts ( rule , std : : vector < NodeTree < Symbol > * > ( ) ) ;
2013-08-13 14:01:53 -04:00
}
2013-10-02 03:15:20 -04:00
NodeTree < Symbol > * RNGLRParser : : getNullableParts ( ParseRule * rule , std : : vector < NodeTree < Symbol > * > avoidList ) {
2013-08-12 00:02:50 -04:00
if ( reducesToNull ( rule ) ) {
2013-08-16 00:03:26 -04:00
//std::cout << "Reduces to null so adding parts " << rule->toString() << std::endl;
2013-10-02 03:15:20 -04:00
Symbol symbol = rule - > getLeftSide ( ) ;
NodeTree < Symbol > * symbolNode = new NodeTree < Symbol > ( symbol . getName ( ) , symbol ) ;
if ( rule - > getAtNextIndex ( ) = = nullSymbol ) {
symbolNode - > addChild ( new NodeTree < Symbol > ( nullSymbol . getName ( ) , nullSymbol ) ) ;
2013-08-12 00:02:50 -04:00
} else {
2013-08-13 14:01:53 -04:00
//Find recursively
2013-08-12 00:02:50 -04:00
ParseRule * iterate = rule - > clone ( ) ;
while ( ! iterate - > isAtEnd ( ) ) {
2013-08-13 14:01:53 -04:00
//Check to see if we've done this symbol already, if so use it
2013-10-02 03:15:20 -04:00
for ( std : : vector < NodeTree < Symbol > * > : : size_type i = 0 ; i < avoidList . size ( ) ; i + + ) {
if ( iterate - > getAtNextIndex ( ) = = avoidList [ i ] - > getData ( ) ) {
2013-08-13 14:01:53 -04:00
symbolNode - > addChild ( avoidList [ i ] ) ;
break ;
}
}
//We haven't so do it recursively
for ( std : : vector < ParseRule * > : : size_type i = 0 ; i < loadedGrammer . size ( ) ; i + + ) {
2013-10-02 03:15:20 -04:00
if ( fullyReducesToNull ( loadedGrammer [ i ] ) & & iterate - > getAtNextIndex ( ) = = loadedGrammer [ i ] - > getLeftSide ( ) ) {
NodeTree < Symbol > * symbolTree = getNullableParts ( loadedGrammer [ i ] , avoidList ) ;
2013-08-13 14:01:53 -04:00
avoidList . push_back ( symbolTree ) ;
symbolNode - > addChild ( symbolTree ) ;
}
}
iterate - > advancePointer ( ) ;
2013-08-12 00:02:50 -04:00
}
}
return symbolNode ;
}
return NULL ;
2013-08-08 02:44:17 -04:00
}
2013-10-02 03:15:20 -04:00
NodeTree < Symbol > * RNGLRParser : : getNullableParts ( Symbol symbol ) {
return new NodeTree < Symbol > ( " CRAZY_SYMBOL " , nullSymbol ) ;
2013-08-08 02:44:17 -04:00
}
2013-10-02 03:15:20 -04:00
std : : vector < NodeTree < Symbol > * > RNGLRParser : : getPathEdges ( std : : vector < NodeTree < int > * > path ) {
std : : vector < NodeTree < Symbol > * > pathEdges ;
2013-08-09 04:39:43 -04:00
for ( std : : vector < NodeTree < int > * > : : size_type i = 0 ; i < path . size ( ) - 1 ; i + + )
2013-08-08 02:44:17 -04:00
pathEdges . push_back ( gss . getEdge ( path [ i ] , path [ i + 1 ] ) ) ;
return pathEdges ;
}
2014-02-20 18:24:04 -05:00
int RNGLRParser : : findLine ( int tokenNum ) {
int lineNo = 0 ;
for ( int i = 0 ; i < tokenNum ; i + + ) {
std : : string tokenString = input [ i ] . getValue ( ) ;
for ( int j = 0 ; j < tokenString . size ( ) ; j + + )
if ( tokenString [ j ] = = ' \n ' )
lineNo + + ;
}
return lineNo ;
}