• entries
570
2427
• views
217354

# Untitled

101 views

ARRGH I HATE WRITING PARSERS!

Maybe its lack of experience, maybe I just suck. BUT I HATE THEMSSS PRECIIOUUSSS!! GRAHHH!

So, I've broken the bloody fudgy parser into two parts - one that expands a function in string form, ie:

INPUT: f(x) = 8*x+sinx^2/2
OUTPUT: f(x) = ((8*x)+((sin(x^2))/2))

And one that actually parses it. That doesn't look too bad, does it? And it worked for a while. Until I realized buggers happen when...

INPUT: f(x) = sinx
OUTPUT: f(x) = sinx)

What's happening? The expander searches for the operator token "sin" and finds it at position 0. And it borks.

So I made some changes and some changes and the whole thing is a complete mess right now. It's to the point where I fix the problem and another one arises because of the changes.

It may be time to scrap the expander and start writing it again from scratch.

I HATE WRITING PARSERS :( :(

UPDATE! Okay, I rewrote the whole damn thing. And it appears to be working. Its such an ugly function... UGH. But you know, I wasn't even going to attempt something nice. Once again, I SUCK AT WRITING PARSERS :( :( :(

Just so you can see how shit this code is...

string pawn::equ::expand( string equ, string token ) {	// regexes LOL!	static string bops = "+-*/^=";	static string uops = "log|sin|cos|tan|asin|acos|atan";		string::size_type iBegin = equ.find( token );	string::size_type iEnd = iBegin + token.size();	// loop through the whole equation and find all	// instances of the token.	while ( iBegin != string::npos ) {		// tasks:		//    - add a '(' before the expression		//    - add a ')' after the expression		// if the thingy was found at the beginning of the		// string, then we need to go ahead and add a "("		// in for it since the search pattern will bork		if ( iBegin == 0 ) {			equ.insert( 0, "(" );		} else {			// need to find an operator that's not in an expression			int pCount = 0;			// work backwards			for ( string::size_type i = iBegin-1; i >= 0 && i < equ.size(); --i ) {				char currChar = equ;				if ( currChar == ')' ) {					pCount++;				} else if ( currChar == '(' ) {					pCount--;				} else if ( bops.find( currChar ) != string::npos ) {					// its a binary operator.					if ( pCount <= 0 ) {						// insert in front of i						equ.insert( i+1, "(" );						break; // exit the loop.					}								} else if ( uops.find( currChar ) != string::npos && i >= 2 ) {					// it might be a unary operator, but not if its closer than 2										// build a lookforward check thing.					string lookahead;					for ( int currPos = 2; currPos >= 0; --currPos )						lookahead += equ[i-currPos];					// see if it exists in the regex					if ( uops.find( currChar ) != string::npos ) {						if ( pCount <= 0 ) {							// insert at end of operator (i)							equ.insert( i+1, "(" );							break;						}					}					// don't have to check for the 4-letter regexes					// since, reading backwards, they're equivalent.				}				// finally, if we're still looking at the end				// add one in.				if ( i == 0 ) {					equ.insert( i, "(" );					break;				}			}		}		// now we've got to place the ")" on the other side of the bugger.				// if its at the end of the expression (which shouldn't be possible)		// we need a special case		if ( iEnd == equ.size() ) {			equ.insert( equ.size(), ")" );		} else {			int pCount = 0;			// work forwards			for ( string::size_type i = iEnd+1; i <= equ.size(); ++i ) {				char currChar = equ; // get the character we're at				// figure out what it means				if ( currChar == '(' ) {					pCount++;				} else if ( currChar == ')' ) {					pCount--;				} else if ( bops.find( currChar ) != string::npos ) {					// binary operator					if ( pCount <= 0 ) {						equ.insert( i, ")" );						break;					}				} else if ( uops.find( currChar ) != string::npos && i <= equ.size()-2 ) {					string lookahead;					for ( int currPos = 0; currPos <= 2; ++currPos ) 						lookahead = lookahead + equ[currPos+i];					// check if its in the regex					if ( uops.find( lookahead ) != string::npos ) {						if ( pCount <= 0 ) {							equ.insert( i, ")" );							break;						}					}					// figure out the 4-char regex, if there is one.					if ( i <= equ.size()-3 ) {						// only if there is enough room!						lookahead += equ[i+3];					}					// check the regex again					if ( uops.find( lookahead ) != string::npos ) {						if ( pCount <= 0 ) {							equ.insert( i, ")" );							break;						}					}				}				// finally, if we're still looking at the end				// add one in.				if ( i == equ.size() ) {					equ.insert( i, ")" );					break;				}			}		}		// find the next instance of the token -		// starting from the end of this token		// +1 (the parenthesis we added)		iBegin = equ.find( token, iEnd+1 );		iEnd = iBegin + token.size();	}	return equ;}

BURN YOUR EYES OUT OMG >:( >:( >:(

So....why not use Antlr?

## Create an account

Register a new account