Parser.h 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. #ifndef _PARSER_H_
  2. #define _PARSER_H_
  3. #include "Common.h"
  4. #include "Scanner.h"
  5. /**
  6. * @brief It contains some functions and macros that include code commonly used in parsing
  7. */
  8. namespace Parser {
  9. //=====================================================================================================================================
  10. // Parser macros =
  11. //=====================================================================================================================================
  12. #define PARSE_ERR(x) ERROR( "Parse Error (" << scanner.getScriptName() << ':' << scanner.getLineNumber() << "): " << x )
  13. #define PARSE_WARN(x) WARNING( "Parse Warning (" << scanner.getScriptName() << ':' << scanner.getLineNumber() << "): " << x )
  14. // common parser errors
  15. #define PARSE_ERR_EXPECTED(x) PARSE_ERR( "Expected " << x << " and not " << Scanner::getTokenInfo(scanner.getCrntToken()) );
  16. #define PARSE_ERR_UNEXPECTED() PARSE_ERR( "Unexpected token " << Scanner::getTokenInfo(scanner.getCrntToken()) );
  17. //=====================================================================================================================================
  18. // parseArrOfNumbers =
  19. //=====================================================================================================================================
  20. /**
  21. * @brief This template func is used for a common operation of parsing arrays of numbers
  22. *
  23. * It parses expressions like this one: { 10 -0.2 123.e-10 -0x0FF } and stores the result in the arr array. The acceptable types
  24. * (typename Type) are integer or floating point types
  25. *
  26. * @param scanner The scanner that we will use
  27. * @param bracket If true the array starts and ends with brackets eg { 10 0 -1 }
  28. * @param signs If true the array has numbers that may contain sign
  29. * @param size The count of numbers of the array wa want to parse
  30. * @param arr The array that the func returns the numbers
  31. * @return True if the parsing was successful
  32. */
  33. template <typename Type> bool parseArrOfNumbers( Scanner& scanner, bool bracket, bool signs, uint size, Type* arr )
  34. {
  35. const Scanner::Token* token;
  36. // first of all the left bracket
  37. if( bracket )
  38. {
  39. token = &scanner.getNextToken();
  40. if( token->getCode() != Scanner::TC_LBRACKET )
  41. {
  42. PARSE_ERR_EXPECTED( "{" );
  43. return false;
  44. }
  45. }
  46. // loop to parse numbers
  47. for( uint i=0; i<size; i++ )
  48. {
  49. token = &scanner.getNextToken();
  50. // check if there is a sign in front of a number
  51. bool sign = 0; // sign of the number. 0 for positive and 1 for negative
  52. if( signs )
  53. {
  54. if( token->getCode() == Scanner::TC_MINUS )
  55. {
  56. sign = 1;
  57. token = &scanner.getNextToken();
  58. }
  59. else if( token->getCode() == Scanner::TC_PLUS )
  60. {
  61. sign = 0;
  62. token = &scanner.getNextToken();
  63. }
  64. // check if not number
  65. if( token->getCode() != Scanner::TC_NUMBER )
  66. {
  67. PARSE_ERR_EXPECTED( "number" );
  68. return false;
  69. }
  70. } // end if signs
  71. // put the number in the arr and do typecasting from int to float
  72. Type nmbr;
  73. if( token->getDataType() == Scanner::DT_FLOAT )
  74. nmbr = static_cast<Type>( token->getValue().getFloat() );
  75. else
  76. nmbr = static_cast<Type>( token->getValue().getInt() );
  77. arr[i] = (sign==0) ? nmbr : -nmbr;
  78. }
  79. // the last thing is the right bracket
  80. if( bracket )
  81. {
  82. token = &scanner.getNextToken();
  83. if( token->getCode() != Scanner::TC_RBRACKET )
  84. {
  85. PARSE_ERR_EXPECTED( "}" );
  86. return false;
  87. }
  88. }
  89. return true;
  90. }
  91. } // end namespace Parser
  92. #endif