简体   繁体   中英

Modifying the Shunting Yard Algorithm (c++)

I have a shunting yard algorithm in proper working order, but I noticed a special quirk:

1 + ( 3 * ( 4 + 5 ) )

parses correctly to

1 3 4 5 + * +,

but

1 + (3 * (4 + 5))
fails, and parses to

 1 * + 5)) +  

I want to get it to parse the second problem properly, so that the result is the same as the first. How can I accomplish this?

Notes: I derived my algorithm from wikipedia: http://en.wikipedia.org/wiki/Shunting-yard_algorithm#The_algorithm_in_detail

My algorithm code is:

string switchingYard(string input)

Edit: Ok, so I just got an idea. So when the parser encounters the '(3' token, it would otherwise treat the two characters as one, and discard the whole thing, but what if I called the function recursively , passing in the substring of the input string which starts at the '3' character? I would then only need to add the shunted string to the output vector, and call ignore on the stringstream! I'm talking about making these changes:

string switchingYard(string input, int depth)

becomes

 string switchingYard(string input, int depth) 
and
 if((token[0] == '(' || token[0] == ')') && (isdigit(token[1]) || token[1] == '.' || isOperator(token[1])) { string shunted_recur = out.push_back(switchingYard(input.substr(io.tellg()+1),depth+1)); } 
gets added to the end of the while loop. Thoughts?

Your problem is that the parser reads strings with:

io >> token;

The simple solution, in my opinion, would be to simply read a character at a time. Eg

char ch;

io >> ch;

I would actually write a function that reads a token - it would know things like "a sequence of digits is a number" and separate out operators, parenthesis, etc. It would return an object (class or structure type) that holds an "type of element" and "value (if relevant) - so it could be type "number" and value "4711", or type "operator", value "+".

You will need a "state" for your tokeniser, which will include a "lookahead" character (one char should be enough), so that you can stop when you have gone past the end of a number, and then pick up the character that "stopped being a number" next time around.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM