parseDemicalNumber.txt 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308
  1. OLD VERSION
  2. /*
  3. struct // private context for @parseDemicalNumber_2 function
  4. {
  5. bool dotAllowed; // dot-character indicator: shows if the character is
  6. // ... allowed in current state;
  7. bool signAllowed; // sign-character indicator: shows if the character is
  8. // ... allowed in current state;
  9. bool digitAllowed; // digit-character indicator: shows if the character is
  10. // ... allowed in current state;
  11. bool mantissaExpected; // mantissa indicator: shows if the mantissa
  12. // ... part of the number is expected in current state;
  13. bool exponentExpected; // exponent indicator: shows if the exponent
  14. // ... part of the number is expected in current state;
  15. bool exponentDetected; // exponent sign indicator: shows if the exponent sign
  16. // ... has been faced or not;
  17. bool whiteAllowed; // white-character indicator: shows if the character is
  18. // ... allowed in current state;
  19. bool manitssaOk; // mantissa indicator: shows if mantissa received or not.
  20. bool exponentOk; // exponent indicator: shows if exponent received or not.
  21. } parseDemicalNumber_2;*/
  22. // =================================================================================================================
  23. /*
  24. // @parseDemicalNumber_2
  25. // "Parser-function", parses a SCPI Demical Numeric Program Data ()
  26. // References:
  27. // "7.7.2 <DECIMAL NUMERIC PROGRAM DATA>", [1]
  28. // "7.7.2.2 Encoding Syntax", [1]
  29. // Parameters:
  30. // @xObj - parser context, must be prepared by @prepareParserContext
  31. // ... before each call. If it is needed to continue the processing, the
  32. // ... @bKeepContext parameter duing the call @prepareParserContext must
  33. // ... be set to 'true', and otherwise, to restart parsing the parameter
  34. // ... must be set to 'false'.
  35. // Returns:
  36. // eParserStatus_failed - error, can not parse data as a string;
  37. // eParserStatus_success - success, the string has been successfully parsed;
  38. // eParserStatus_need_data - warning, the string can not be parsed due to
  39. // there no enough data to process.
  40. eParserStatus_t parseDemicalNumber_2( xParseEntry_t * xObj )
  41. {
  42. sParseEntry_t * pObj = (sParseEntry_t*)xObj;
  43. eParserStatus_t status = eParserStatus_invalid;
  44. if( NULL != pObj && NULL != pObj->str && 0 != ((ptrdiff_t)pObj->tail - (ptrdiff_t)pObj->head)
  45. && pObj->str != pObj->tail )
  46. {
  47. status = eParserStatus_failed; // forward status set: the default 'eParserStatus_invalid' shall
  48. // ... not be returned due to the context will be changed.
  49. // if the context has been cleaned up
  50. if( ! pObj->bContextKept )
  51. {
  52. // "7.7.2.2 Encoding Syntax", [1]:
  53. pObj->parseDemicalNumber_2.signAllowed = true; // Mantissa can begin with a sign;
  54. pObj->parseDemicalNumber_2.dotAllowed = true; // Mantissa can begin with a dot;
  55. pObj->parseDemicalNumber_2.mantissaExpected = true; // Mantissa is expected in the beginning;
  56. pObj->parseDemicalNumber_2.exponentExpected = false; // Exponent is not expected in the beginning;
  57. pObj->parseDemicalNumber_2.exponentDetected = false; // Exponent sign is not detected by default;
  58. pObj->parseDemicalNumber_2.whiteAllowed = false; // White-character is not allowed by default;
  59. pObj->parseDemicalNumber_2.manitssaOk = false; // reset mantissa indicator
  60. pObj->parseDemicalNumber_2.exponentOk = false; // reset exponent indicator
  61. pObj->parseDemicalNumber_2.digitAllowed = true; // allow digits: the number can start from digit
  62. }
  63. // walk til the end of the buffer
  64. while( pObj->str != pObj->tail )
  65. {
  66. char character = *(pObj->str++);
  67. // Check if the mantissa is expected to be received:
  68. if( pObj->parseDemicalNumber_2.mantissaExpected )
  69. {
  70. // Check if the sign-character has not been faced yet:
  71. if( pObj->parseDemicalNumber_2.signAllowed )
  72. {
  73. // Check if the character is a sign-character:
  74. if( '-' == character || '+' == character )
  75. {
  76. // Yes, since this moment no sign character is allowed.
  77. pObj->parseDemicalNumber_2.signAllowed = false;
  78. // skip character
  79. continue;
  80. }
  81. // Current character is not a sign-character, and
  82. // ... since this moment the sign character is not
  83. // ... allowed anymore.
  84. pObj->parseDemicalNumber_2.signAllowed = false;
  85. }
  86. // Check if the dot-character has not been faced yet:
  87. if( pObj->parseDemicalNumber_2.dotAllowed )
  88. {
  89. // Check if the character is a dot-character:
  90. if( '.' == character )
  91. {
  92. // Yes, since this moment no dot character is allowed.
  93. pObj->parseDemicalNumber_2.dotAllowed = false;
  94. // since this moment the exponent part is allowed
  95. pObj->parseDemicalNumber_2.exponentExpected = true;
  96. // skip character
  97. continue;
  98. }
  99. // Current character is not a dot-character, but
  100. // ... the digit character is allowed to be followed
  101. // ... by the dot character.
  102. (void)pObj->parseDemicalNumber_2.dotAllowed;
  103. }
  104. // Check if the current character is a digit-character:
  105. // Check if digit character is allowed
  106. if( (pObj->parseDemicalNumber_2.digitAllowed) && scpi_isdigit( character ) )
  107. {
  108. // yes, the character is allowed digit character
  109. // since this moment the exponent part is allowed
  110. pObj->parseDemicalNumber_2.exponentExpected = true;
  111. // since the exponent part is allowed, a white character is allowed:
  112. pObj->parseDemicalNumber_2.whiteAllowed = true;
  113. // set mantissa indicator: it is enough to parse at least a mantissa
  114. pObj->parseDemicalNumber_2.manitssaOk = true;
  115. // skip character
  116. continue;
  117. }
  118. }
  119. // Check if the exponent is expected to be received:
  120. if( pObj->parseDemicalNumber_2.exponentExpected )
  121. {
  122. // check if white character is allowed:
  123. if( pObj->parseDemicalNumber_2.whiteAllowed )
  124. {
  125. // check for white character:
  126. if( scpi_iswhite( character ) )
  127. {
  128. // since white character detected only exponent
  129. // ... character is allowed.
  130. pObj->parseDemicalNumber_2.digitAllowed = false; // disallow digits
  131. // skip character
  132. continue;
  133. }
  134. }
  135. // if the exponent sign has not been faced yet:
  136. if( ! pObj->parseDemicalNumber_2.exponentDetected )
  137. {
  138. if( 'e' == character || 'E' == character )
  139. {
  140. // set exponent-sign indicator:
  141. pObj->parseDemicalNumber_2.exponentDetected = true;
  142. // allow the sign character for exponent:
  143. pObj->parseDemicalNumber_2.signAllowed = true;
  144. // allow white character:
  145. pObj->parseDemicalNumber_2.whiteAllowed = true;
  146. // disable the mantissa processing
  147. pObj->parseDemicalNumber_2.mantissaExpected = false;
  148. // skip character
  149. continue;
  150. }
  151. }
  152. // if the exponent sign has been detected:
  153. if( pObj->parseDemicalNumber_2.exponentDetected )
  154. {
  155. // check if the sign is allowed:
  156. if( pObj->parseDemicalNumber_2.signAllowed )
  157. {
  158. // Check if the character is a sign-character:
  159. if( '-' == character || '+' == character )
  160. {
  161. // Yes, since this moment no sign character is allowed.
  162. pObj->parseDemicalNumber_2.signAllowed = false;
  163. // disallow white character after the exponent sign
  164. pObj->parseDemicalNumber_2.whiteAllowed = false;
  165. // skip character
  166. continue;
  167. }
  168. }
  169. // Check if the current character is a digit-character:
  170. if( scpi_isdigit( character ) )
  171. {
  172. // since this moment no sign character is allowed.
  173. pObj->parseDemicalNumber_2.signAllowed = false;
  174. // since this moment no white character is allowed.
  175. pObj->parseDemicalNumber_2.whiteAllowed = false;
  176. // since at least one digit received the exponent is correct:
  177. pObj->parseDemicalNumber_2.exponentOk = true;
  178. // skip character
  179. continue;
  180. }
  181. // check if the exponent part is already valid
  182. if( pObj->parseDemicalNumber_2.exponentOk )
  183. {
  184. // if the white character is faced
  185. if( scpi_iswhite( character ) )
  186. {
  187. // set length:
  188. // LENGTH = @str - 1, minus one due to
  189. // ... @str has been already incremented
  190. pObj->tail = pObj->str - 1;
  191. status = eParserStatus_success; // successfully found
  192. break;
  193. }
  194. pObj->str--; // decrement interator due to current character is invalid
  195. }
  196. }
  197. }
  198. break;
  199. }
  200. if( status != eParserStatus_success )
  201. {
  202. // Check if the whole buffer processed?
  203. if( pObj->str >= pObj->tail )
  204. {
  205. // yes the whole buffer processed
  206. // Not enough data to continue.
  207. // Check for end-of-message indicator:
  208. if( ! pObj->bEndMessage )
  209. {
  210. // end-of-message is not set
  211. // set warning status: there no enough data
  212. status = eParserStatus_need_data;
  213. }
  214. else
  215. {
  216. // end-of-message is set.
  217. // Check if the white character is allowed:
  218. if( pObj->parseDemicalNumber_2.whiteAllowed )
  219. {
  220. // yes, white character is expected: it seems as
  221. // ... end condition since the white character allowed
  222. // ... only in the place where the entity can be finished.
  223. // So, it is end of the entity:
  224. // set the length:
  225. // LENGTH = @str - @head
  226. pObj->tail = pObj->str; // set the tail pointer to indicate the length
  227. status = eParserStatus_success; // successfully found
  228. }
  229. else
  230. {
  231. // yes, white character is not expected.
  232. // It seems as incompleted entity.
  233. status = eParserStatus_failed; // incomplete
  234. }
  235. }
  236. }
  237. else
  238. {
  239. // not the whole buffer processed
  240. // check if enough data has been processed - check for mantissa:
  241. if( pObj->parseDemicalNumber_2.manitssaOk )
  242. {
  243. // Check if the exponent sign has been detected and no exponent completely recevied?
  244. if( pObj->parseDemicalNumber_2.exponentDetected && !pObj->parseDemicalNumber_2.exponentOk )
  245. {
  246. // set failed status: trailing exponent sign detected.
  247. status = eParserStatus_failed;
  248. }
  249. else
  250. {
  251. // set the length:
  252. // LENGTH = @str - @head
  253. pObj->tail = pObj->str; // set the tail pointer to indicate the length
  254. status = eParserStatus_success; // successfully found
  255. }
  256. }
  257. else
  258. {
  259. // set failed status: no mantissa found
  260. status = eParserStatus_failed;
  261. }
  262. }
  263. }
  264. }
  265. return status;
  266. }
  267. */