![]() In the next post I’ll show how to modify this code to build an abstract syntax tree. Which is exactly what we expected: it validates correct expressions and throws an exception when the exception is incorrect. "*1 / 2.5" Unexpected token '*' at position 1 "1 ** 2.5" Unexpected token '*' at position 4 "1 * 2.5.6" Unexpected token '.' at position 7 "1 + 2&5" Unexpected token '&' at position 5 "M1 + 2.5" Unexpected token 'M' at position 0 " 1*2.5e2" Unexpected token 'e' at position 8 " 1*2,5" Unexpected token ',' at position 6 ParserException(const std::string& message, int pos):Īs you can see, the code for the grammar production is quite simple and straight forward. The exception class is defined like this:Ĭlass ParserException : public std::exception Sstr << "Expected token '" << expected << "' at position " << m_Index Sstr << "Unexpected token '" << m_crtToken.Symbol << "' at position " << m_Index With these defined, we can build the parser for the specified grammar. Memcpy(buffer, &m_Text, m_Index - index) Throw ParserException("Number expected but not found!", m_Index) GetNumber() extracts a number from the input text from the current position the purpose of this tutorial is didactical, so this function is quite simple: it reads integers and doubles with ‘.’ As the decimal point it doesn’t read numbers in a format like 123.3E+2.Throw ParserException(sstr.str(), m_Index) Sstr << "Unexpected token '" << m_Text << "' at position " << m_Index check if the current character is an operator or parenthesesĬase '-': m_crtToken.Type = Minus break Ĭase '(': m_crtToken.Type = OpenParenthesis break Ĭase ')': m_crtToken.Type = ClosedParenthesis break if the current character is a digit read a number GetNextToken(), extracts the next token from the text if an illegal token appears it throws an exception.SkipWhitespaces(), skips all whitespaces between two tokens:.To be able to do the parsing, we’ll need some helper functions: Here is how I defined the token type and the token: ![]() The possible tokens will be the arithmetical operators (‘+’, ‘-‘, ‘/’, ‘*’), the parentheses (‘(‘ and ‘)’), numbers and the end of the text. A token is basically a symbol extracted (one at a time) from the input text. However, I want to make it a little bit more organized, so the first thing to do will be defining a Token structure that will indicate the type of last extracted token and if the case its value (for numbers). And after that, you need to be very careful to follow the order of operations to evaluate each operation that’s in your expression. Having the grammar defined, we’ll make one function for each non-terminal symbol (EXP, EXP1, TERM, TERM1, FACTOR). The first thing that we’ll do when we’re trying to evaluate algebraic expressions is to substitute given values for the variables. As I was mentioning, the first step towards this goal is to parse the expression, make sure it is correct syntactically. ![]() In my previous post I have provided some background theory for evaluating expressions with abstract syntax trees.
0 Comments
Leave a Reply. |
AuthorWrite something about yourself. No need to be fancy, just an overview. ArchivesCategories |