https://github.com/j123b567/scpi-parser
Dependents: scpi_sx127x scpi_sx127x_firstTest MLX90418_I2C_master
lexer.c
00001 /*- 00002 * Copyright (c) 2012-2013 Jan Breuer, 00003 * 00004 * All Rights Reserved 00005 * 00006 * Redistribution and use in source and binary forms, with or without 00007 * modification, are permitted provided that the following conditions are 00008 * met: 00009 * 1. Redistributions of source code must retain the above copyright notice, 00010 * this list of conditions and the following disclaimer. 00011 * 2. Redistributions in binary form must reproduce the above copyright 00012 * notice, this list of conditions and the following disclaimer in the 00013 * documentation and/or other materials provided with the distribution. 00014 * 00015 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR 00016 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 00017 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 00018 * DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE 00019 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 00020 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 00021 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 00022 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 00023 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 00024 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN 00025 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00026 */ 00027 00028 /** 00029 * @file lexer.c 00030 * @date Wed Mar 20 19:35:19 UTC 2013 00031 * 00032 * @brief SCPI Lexer 00033 * 00034 * 00035 */ 00036 00037 #include <ctype.h> 00038 #include <stdio.h> 00039 #include <string.h> 00040 00041 #include "lexer_private.h" 00042 #include "scpi/error.h" 00043 00044 /** 00045 * Is white space 00046 * @param c 00047 * @return 00048 */ 00049 static int isws(int c) { 00050 if ((c == ' ') || (c == '\t')) { 00051 return 1; 00052 } 00053 return 0; 00054 } 00055 00056 /** 00057 * Is binary digit 00058 * @param c 00059 * @return 00060 */ 00061 static int isbdigit(int c) { 00062 if ((c == '0') || (c == '1')) { 00063 return 1; 00064 } 00065 return 0; 00066 } 00067 00068 /** 00069 * Is hexadecimal digit 00070 * @param c 00071 * @return 00072 */ 00073 static int isqdigit(int c) { 00074 if ((c == '0') || (c == '1') || (c == '2') || (c == '3') || (c == '4') || (c == '5') || (c == '6') || (c == '7')) { 00075 return 1; 00076 } 00077 return 0; 00078 } 00079 00080 /** 00081 * Is end of string 00082 * @param state 00083 * @return 00084 */ 00085 static int iseos(lex_state_t * state) { 00086 if ((state->buffer + state->len) <= (state->pos)) { 00087 return 1; 00088 } else { 00089 return 0; 00090 } 00091 } 00092 00093 /** 00094 * Private export of iseos 00095 * @param state 00096 * @return 00097 */ 00098 int scpiLex_IsEos(lex_state_t * state) { 00099 return iseos(state); 00100 } 00101 00102 /** 00103 * Test current character 00104 * @param state 00105 * @param chr 00106 * @return 00107 */ 00108 static int ischr(lex_state_t * state, char chr) { 00109 return (state->pos[0] == chr); 00110 } 00111 00112 /** 00113 * Is plus or minus 00114 * @param c 00115 * @return 00116 */ 00117 static int isplusmn(int c) { 00118 return c == '+' || c == '-'; 00119 } 00120 00121 /** 00122 * Is letter H 00123 * @param c 00124 * @return 00125 */ 00126 static int isH(int c) { 00127 return c == 'h' || c == 'H'; 00128 } 00129 00130 /** 00131 * Is letter B 00132 * @param c 00133 * @return 00134 */ 00135 static int isB(int c) { 00136 return c == 'b' || c == 'B'; 00137 } 00138 00139 /** 00140 * Is letter Q 00141 * @param c 00142 * @return 00143 */ 00144 static int isQ(int c) { 00145 return c == 'q' || c == 'Q'; 00146 } 00147 00148 /** 00149 * Is letter E 00150 * @param c 00151 * @return 00152 */ 00153 static int isE(int c) { 00154 return c == 'e' || c == 'E'; 00155 } 00156 00157 #define SKIP_NONE 0 00158 #define SKIP_OK 1 00159 #define SKIP_INCOMPLETE -1 00160 00161 /* skip characters */ 00162 /* 7.4.1 <PROGRAM MESSAGE UNIT SEPARATOR>*/ 00163 // TODO: static int skipProgramMessageUnitSeparator(lex_state_t * state) 00164 00165 /** 00166 * Skip all whitespaces 00167 * @param state 00168 * @return 00169 */ 00170 static int skipWs(lex_state_t * state) { 00171 int someSpace = 0; 00172 while (!iseos(state) && isws(state->pos[0])) { 00173 state->pos++; 00174 someSpace++; 00175 } 00176 00177 return someSpace; 00178 } 00179 00180 /* 7.4.2 <PROGRAM DATA SEPARATOR> */ 00181 // static int skipProgramDataSeparator(lex_state_t * state) 00182 00183 /* 7.5.2 <PROGRAM MESSAGE TERMINATOR> */ 00184 // static int skipProgramMessageTerminator(lex_state_t * state) 00185 00186 /** 00187 * Skip decimal digit 00188 * @param state 00189 * @return 00190 */ 00191 static int skipDigit(lex_state_t * state) { 00192 if (!iseos(state) && isdigit(state->pos[0])) { 00193 state->pos++; 00194 return SKIP_OK; 00195 } else { 00196 return SKIP_NONE; 00197 } 00198 } 00199 00200 /** 00201 * Skip multiple decimal digits 00202 * @param state 00203 * @return 00204 */ 00205 static int skipNumbers(lex_state_t * state) { 00206 int someNumbers = 0; 00207 while (!iseos(state) && isdigit(state->pos[0])) { 00208 state->pos++; 00209 someNumbers++; 00210 } 00211 return someNumbers; 00212 } 00213 00214 /** 00215 * Skip plus or minus 00216 * @param state 00217 * @return 00218 */ 00219 static int skipPlusmn(lex_state_t * state) { 00220 if (!iseos(state) && isplusmn(state->pos[0])) { 00221 state->pos++; 00222 return SKIP_OK; 00223 } else { 00224 return SKIP_NONE; 00225 } 00226 } 00227 00228 /** 00229 * Skip any character from 'a'-'Z' 00230 * @param state 00231 * @return 00232 */ 00233 static int skipAlpha(lex_state_t * state) { 00234 int someLetters = 0; 00235 while (!iseos(state) && isalpha(state->pos[0])) { 00236 state->pos++; 00237 someLetters++; 00238 } 00239 return someLetters; 00240 } 00241 00242 /** 00243 * Skip exact character chr or nothing 00244 * @param state 00245 * @param chr 00246 * @return 00247 */ 00248 static int skipChr(lex_state_t * state, char chr) { 00249 if (!iseos(state) && ischr(state, chr)) { 00250 state->pos++; 00251 return SKIP_OK; 00252 } else { 00253 return SKIP_NONE; 00254 } 00255 } 00256 00257 /** 00258 * Skip slash or dot 00259 * @param state 00260 * @return 00261 */ 00262 static int skipSlashDot(lex_state_t * state) { 00263 if (!iseos(state) && (ischr(state, '/') | ischr(state, '.'))) { 00264 state->pos++; 00265 return SKIP_OK; 00266 } else { 00267 return SKIP_NONE; 00268 } 00269 } 00270 00271 /** 00272 * Skip star 00273 * @param state 00274 * @return 00275 */ 00276 static int skipStar(lex_state_t * state) { 00277 if (!iseos(state) && ischr(state, '*')) { 00278 state->pos++; 00279 return SKIP_OK; 00280 } else { 00281 return SKIP_NONE; 00282 } 00283 } 00284 00285 /** 00286 * Skip colon 00287 * @param state 00288 * @return 00289 */ 00290 static int skipColon(lex_state_t * state) { 00291 if (!iseos(state) && ischr(state, ':')) { 00292 state->pos++; 00293 return SKIP_OK; 00294 } else { 00295 return SKIP_NONE; 00296 } 00297 } 00298 00299 /* 7.6.1.2 <COMMAND PROGRAM HEADER> */ 00300 00301 /** 00302 * Skip program mnemonic [a-z][a-z0-9_]* 00303 * @param state 00304 * @return 00305 */ 00306 static int skipProgramMnemonic(lex_state_t * state) { 00307 const char * startPos = state->pos; 00308 if (!iseos(state) && isalpha(state->pos[0])) { 00309 state->pos++; 00310 while (!iseos(state) && (isalnum(state->pos[0]) || ischr(state, '_'))) { 00311 state->pos++; 00312 } 00313 } 00314 00315 if (iseos(state)) { 00316 return (state->pos - startPos) * SKIP_INCOMPLETE; 00317 } else { 00318 return (state->pos - startPos) * SKIP_OK; 00319 } 00320 } 00321 00322 /* tokens */ 00323 00324 /** 00325 * Detect token white space 00326 * @param state 00327 * @param token 00328 * @return 00329 */ 00330 int scpiLex_WhiteSpace(lex_state_t * state, scpi_token_t * token) { 00331 token->ptr = state->pos; 00332 00333 skipWs(state); 00334 00335 token->len = state->pos - token->ptr; 00336 00337 if (token->len > 0) { 00338 token->type = SCPI_TOKEN_WS; 00339 } else { 00340 token->type = SCPI_TOKEN_UNKNOWN; 00341 } 00342 00343 return token->len; 00344 } 00345 00346 /* 7.6.1 <COMMAND PROGRAM HEADER> */ 00347 00348 /** 00349 * Skip command program header \*<PROGRAM MNEMONIC> 00350 * @param state 00351 * @return 00352 */ 00353 static int skipCommonProgramHeader(lex_state_t * state) { 00354 int res; 00355 if (skipStar(state)) { 00356 res = skipProgramMnemonic(state); 00357 if (res == SKIP_NONE && iseos(state)) { 00358 return SKIP_INCOMPLETE; 00359 } else if (res <= SKIP_INCOMPLETE) { 00360 return SKIP_OK; 00361 } else if (res >= SKIP_OK) { 00362 return SKIP_OK; 00363 } else { 00364 return SKIP_INCOMPLETE; 00365 } 00366 } 00367 return SKIP_NONE; 00368 } 00369 00370 /** 00371 * Skip compound program header :<PROGRAM MNEMONIC>:<PROGRAM MNEMONIC>... 00372 * @param state 00373 * @return 00374 */ 00375 static int skipCompoundProgramHeader(lex_state_t * state) { 00376 int res; 00377 int firstColon = skipColon(state); 00378 00379 res = skipProgramMnemonic(state); 00380 if (res >= SKIP_OK) { 00381 while (skipColon(state)) { 00382 res = skipProgramMnemonic(state); 00383 if (res <= SKIP_INCOMPLETE) { 00384 return SKIP_OK; 00385 } else if (res == SKIP_NONE) { 00386 return SKIP_INCOMPLETE; 00387 } 00388 } 00389 return SKIP_OK; 00390 } else if (res <= SKIP_INCOMPLETE) { 00391 return SKIP_OK; 00392 } else if (firstColon) { 00393 return SKIP_INCOMPLETE; 00394 } else { 00395 return SKIP_NONE; 00396 } 00397 } 00398 00399 /** 00400 * Detect token command or compound program header 00401 * @param state 00402 * @param token 00403 * @return 00404 */ 00405 int scpiLex_ProgramHeader(lex_state_t * state, scpi_token_t * token) { 00406 int res; 00407 token->ptr = state->pos; 00408 token->type = SCPI_TOKEN_UNKNOWN; 00409 00410 res = skipCommonProgramHeader(state); 00411 if (res >= SKIP_OK) { 00412 if (skipChr(state, '?') >= SKIP_OK) { 00413 token->type = SCPI_TOKEN_COMMON_QUERY_PROGRAM_HEADER; 00414 } else { 00415 token->type = SCPI_TOKEN_COMMON_PROGRAM_HEADER; 00416 } 00417 } else if (res <= SKIP_INCOMPLETE) { 00418 token->type = SCPI_TOKEN_INCOMPLETE_COMMON_PROGRAM_HEADER; 00419 } else if (res == SKIP_NONE) { 00420 res = skipCompoundProgramHeader(state); 00421 00422 if (res >= SKIP_OK) { 00423 if (skipChr(state, '?') >= SKIP_OK) { 00424 token->type = SCPI_TOKEN_COMPOUND_QUERY_PROGRAM_HEADER; 00425 } else { 00426 token->type = SCPI_TOKEN_COMPOUND_PROGRAM_HEADER; 00427 } 00428 } else if (res <= SKIP_INCOMPLETE) { 00429 token->type = SCPI_TOKEN_INCOMPLETE_COMPOUND_PROGRAM_HEADER; 00430 } 00431 } 00432 00433 if (token->type != SCPI_TOKEN_UNKNOWN) { 00434 token->len = state->pos - token->ptr; 00435 } else { 00436 token->len = 0; 00437 state->pos = token->ptr; 00438 } 00439 00440 return token->len; 00441 } 00442 00443 /* 7.7.1 <CHARACTER PROGRAM DATA> */ 00444 00445 /** 00446 * Detect token "Character program data" 00447 * @param state 00448 * @param token 00449 * @return 00450 */ 00451 int scpiLex_CharacterProgramData(lex_state_t * state, scpi_token_t * token) { 00452 token->ptr = state->pos; 00453 00454 if (!iseos(state) && isalpha(state->pos[0])) { 00455 state->pos++; 00456 while (!iseos(state) && (isalnum(state->pos[0]) || ischr(state, '_'))) { 00457 state->pos++; 00458 } 00459 } 00460 00461 token->len = state->pos - token->ptr; 00462 if (token->len > 0) { 00463 token->type = SCPI_TOKEN_PROGRAM_MNEMONIC; 00464 } else { 00465 token->type = SCPI_TOKEN_UNKNOWN; 00466 } 00467 00468 return token->len; 00469 } 00470 00471 /* 7.7.2 <DECIMAL NUMERIC PROGRAM DATA> */ 00472 static int skipMantisa(lex_state_t * state) { 00473 int someNumbers = 0; 00474 00475 skipPlusmn(state); 00476 00477 someNumbers += skipNumbers(state); 00478 00479 if (skipChr(state, '.')) { 00480 someNumbers += skipNumbers(state); 00481 } 00482 00483 return someNumbers; 00484 } 00485 00486 static int skipExponent(lex_state_t * state) { 00487 int someNumbers = 0; 00488 00489 if (!iseos(state) && isE(state->pos[0])) { 00490 state->pos++; 00491 00492 skipWs(state); 00493 00494 skipPlusmn(state); 00495 00496 someNumbers = skipNumbers(state); 00497 } 00498 00499 return someNumbers; 00500 } 00501 00502 /** 00503 * Detect token Decimal number 00504 * @param state 00505 * @param token 00506 * @return 00507 */ 00508 int scpiLex_DecimalNumericProgramData(lex_state_t * state, scpi_token_t * token) { 00509 char * rollback; 00510 token->ptr = state->pos; 00511 00512 if (skipMantisa(state)) { 00513 rollback = state->pos; 00514 skipWs(state); 00515 if (!skipExponent(state)) { 00516 state->pos = rollback; 00517 } 00518 } else { 00519 state->pos = token->ptr; 00520 } 00521 00522 token->len = state->pos - token->ptr; 00523 if (token->len > 0) { 00524 token->type = SCPI_TOKEN_DECIMAL_NUMERIC_PROGRAM_DATA; 00525 } else { 00526 token->type = SCPI_TOKEN_UNKNOWN; 00527 } 00528 00529 return token->len; 00530 } 00531 00532 /* 7.7.3 <SUFFIX PROGRAM DATA> */ 00533 int scpiLex_SuffixProgramData(lex_state_t * state, scpi_token_t * token) { 00534 token->ptr = state->pos; 00535 00536 skipChr(state, '/'); 00537 00538 // TODO: strict parsing : SLASH? (ALPHA+ (MINUS? DIGIT)?) ((SLASH | DOT) (ALPHA+ (MINUS? DIGIT)?))* 00539 if (skipAlpha(state)) { 00540 skipChr(state, '-'); 00541 skipDigit(state); 00542 00543 while (skipSlashDot(state)) { 00544 skipAlpha(state); 00545 skipChr(state, '-'); 00546 skipDigit(state); 00547 } 00548 } 00549 00550 token->len = state->pos - token->ptr; 00551 if ((token->len > 0)) { 00552 token->type = SCPI_TOKEN_SUFFIX_PROGRAM_DATA; 00553 } else { 00554 token->type = SCPI_TOKEN_UNKNOWN; 00555 state->pos = token->ptr; 00556 token->len = 0; 00557 } 00558 00559 return token->len; 00560 } 00561 00562 /* 7.7.4 <NONDECIMAL NUMERIC PROGRAM DATA> */ 00563 static int skipHexNum(lex_state_t * state) { 00564 int someNumbers = 0; 00565 while (!iseos(state) && isxdigit(state->pos[0])) { 00566 state->pos++; 00567 someNumbers++; 00568 } 00569 return someNumbers; 00570 } 00571 00572 static int skipOctNum(lex_state_t * state) { 00573 int someNumbers = 0; 00574 while (!iseos(state) && isqdigit(state->pos[0])) { 00575 state->pos++; 00576 someNumbers++; 00577 } 00578 return someNumbers; 00579 } 00580 00581 static int skipBinNum(lex_state_t * state) { 00582 int someNumbers = 0; 00583 while (!iseos(state) && isbdigit(state->pos[0])) { 00584 state->pos++; 00585 someNumbers++; 00586 } 00587 return someNumbers; 00588 } 00589 00590 /** 00591 * Detect token nondecimal number 00592 * @param state 00593 * @param token 00594 * @return 00595 */ 00596 int scpiLex_NondecimalNumericData(lex_state_t * state, scpi_token_t * token) { 00597 int someNumbers = 0; 00598 token->ptr = state->pos; 00599 if (skipChr(state, '#')) { 00600 if (!iseos(state)) { 00601 if (isH(state->pos[0])) { 00602 state->pos++; 00603 someNumbers = skipHexNum(state); 00604 token->type = SCPI_TOKEN_HEXNUM; 00605 } else if (isQ(state->pos[0])) { 00606 state->pos++; 00607 someNumbers = skipOctNum(state); 00608 token->type = SCPI_TOKEN_OCTNUM; 00609 } else if (isB(state->pos[0])) { 00610 state->pos++; 00611 someNumbers = skipBinNum(state); 00612 token->type = SCPI_TOKEN_BINNUM; 00613 } 00614 } 00615 } 00616 00617 if (someNumbers) { 00618 token->ptr += 2; // ignore number prefix 00619 token->len = state->pos - token->ptr; 00620 } else { 00621 token->type = SCPI_TOKEN_UNKNOWN; 00622 state->pos = token->ptr; 00623 token->len = 0; 00624 } 00625 return token->len > 0 ? token->len + 2 : 0; 00626 } 00627 00628 /* 7.7.5 <STRING PROGRAM DATA> */ 00629 static int isascii7bit(int c) { 00630 return (c >= 0) && (c <= 0x7f); 00631 } 00632 00633 static void skipQuoteProgramData(lex_state_t * state, char quote) { 00634 while (!iseos(state)) { 00635 if (isascii7bit(state->pos[0]) && !ischr(state, quote)) { 00636 state->pos++; 00637 } else if (ischr(state, quote)) { 00638 state->pos++; 00639 if (!iseos(state) && ischr(state, quote)) { 00640 state->pos++; 00641 } else { 00642 state->pos--; 00643 break; 00644 } 00645 } 00646 } 00647 } 00648 00649 static void skipDoubleQuoteProgramData(lex_state_t * state) { 00650 skipQuoteProgramData(state, '"'); 00651 } 00652 00653 static void skipSingleQuoteProgramData(lex_state_t * state) { 00654 skipQuoteProgramData(state, '\''); 00655 } 00656 00657 /** 00658 * Detect token String data 00659 * @param state 00660 * @param token 00661 * @return 00662 */ 00663 int scpiLex_StringProgramData(lex_state_t * state, scpi_token_t * token) { 00664 token->ptr = state->pos; 00665 00666 if (!iseos(state)) { 00667 if (ischr(state, '"')) { 00668 state->pos++; 00669 token->type = SCPI_TOKEN_DOUBLE_QUOTE_PROGRAM_DATA; 00670 skipDoubleQuoteProgramData(state); 00671 if (!iseos(state) && ischr(state, '"')) { 00672 state->pos++; 00673 token->len = state->pos - token->ptr; 00674 } else { 00675 state->pos = token->ptr; 00676 } 00677 } else if (ischr(state, '\'')) { 00678 state->pos++; 00679 token->type = SCPI_TOKEN_SINGLE_QUOTE_PROGRAM_DATA; 00680 skipSingleQuoteProgramData(state); 00681 if (!iseos(state) && ischr(state, '\'')) { 00682 state->pos++; 00683 token->len = state->pos - token->ptr; 00684 } else { 00685 state->pos = token->ptr; 00686 } 00687 } 00688 } 00689 00690 token->len = state->pos - token->ptr; 00691 00692 if ((token->len > 0)) { 00693 token->ptr++; 00694 token->len -= 2; 00695 } else { 00696 token->type = SCPI_TOKEN_UNKNOWN; 00697 state->pos = token->ptr; 00698 token->len = 0; 00699 } 00700 00701 return token->len > 0 ? token->len + 2 : 0; 00702 } 00703 00704 /* 7.7.6 <ARBITRARY BLOCK PROGRAM DATA> */ 00705 static int isNonzeroDigit(int c) { 00706 return isdigit(c) && (c != '0'); 00707 } 00708 00709 /** 00710 * Detect token Block Data 00711 * @param state 00712 * @param token 00713 * @return 00714 */ 00715 int scpiLex_ArbitraryBlockProgramData(lex_state_t * state, scpi_token_t * token) { 00716 int i; 00717 int arbitraryBlockLength = 0; 00718 const char * ptr = state->pos; 00719 int validData = -1; 00720 token->ptr = state->pos; 00721 00722 if (skipChr(state, '#')) { 00723 if (!iseos(state) && isNonzeroDigit(state->pos[0])) { 00724 /* Get number of digits */ 00725 i = state->pos[0] - '0'; 00726 state->pos++; 00727 00728 for (; i > 0; i--) { 00729 if (!iseos(state) && isdigit(state->pos[0])) { 00730 arbitraryBlockLength *= 10; 00731 arbitraryBlockLength += (state->pos[0] - '0'); 00732 state->pos++; 00733 } else { 00734 break; 00735 } 00736 } 00737 00738 if (i == 0) { 00739 state->pos += arbitraryBlockLength; 00740 if ((state->buffer + state->len) >= (state->pos)) { 00741 token->ptr = state->pos - arbitraryBlockLength; 00742 token->len = arbitraryBlockLength; 00743 validData = 1; 00744 } 00745 } else if (iseos(state)) { 00746 validData = 0; 00747 } 00748 } else if (iseos(state)) { 00749 validData = 0; 00750 } 00751 } 00752 00753 if (validData == 1) { 00754 // valid 00755 token->type = SCPI_TOKEN_ARBITRARY_BLOCK_PROGRAM_DATA; 00756 } else if (validData == 0) { 00757 // incomplete 00758 token->type = SCPI_TOKEN_UNKNOWN; 00759 token->len = 0; 00760 state->pos = state->buffer + state->len; 00761 } else { 00762 // invalid 00763 token->type = SCPI_TOKEN_UNKNOWN; 00764 state->pos = token->ptr; 00765 token->len = 0; 00766 } 00767 00768 return token->len + (token->ptr - ptr); 00769 } 00770 00771 /* 7.7.7 <EXPRESSION PROGRAM DATA> */ 00772 static int isProgramExpression(int c) { 00773 if ((c >= 0x20) && (c <= 0x7e)) { 00774 if ((c != 0x22) 00775 && (c != 0x23) 00776 && (c != 0x27) 00777 && (c != 0x28) 00778 && (c != 0x29) 00779 && (c != 0x3B)) { 00780 return 1; 00781 } 00782 } 00783 00784 return 0; 00785 } 00786 00787 static void skipProgramExpression(lex_state_t * state) { 00788 while (!iseos(state) && isProgramExpression(state->pos[0])) { 00789 state->pos++; 00790 } 00791 } 00792 00793 // TODO: 7.7.7.2-2 recursive - any program data 00794 00795 /** 00796 * Detect token Expression 00797 * @param state 00798 * @param token 00799 * @return 00800 */ 00801 int scpiLex_ProgramExpression(lex_state_t * state, scpi_token_t * token) { 00802 token->ptr = state->pos; 00803 00804 if (!iseos(state) && ischr(state, '(')) { 00805 state->pos++; 00806 skipProgramExpression(state); 00807 00808 if (!iseos(state) && ischr(state, ')')) { 00809 state->pos++; 00810 token->len = state->pos - token->ptr; 00811 } else { 00812 token->len = 0; 00813 } 00814 } 00815 00816 if ((token->len > 0)) { 00817 token->type = SCPI_TOKEN_PROGRAM_EXPRESSION; 00818 } else { 00819 token->type = SCPI_TOKEN_UNKNOWN; 00820 state->pos = token->ptr; 00821 token->len = 0; 00822 } 00823 00824 return token->len; 00825 } 00826 00827 /** 00828 * Detect token comma 00829 * @param state 00830 * @param token 00831 * @return 00832 */ 00833 int scpiLex_Comma(lex_state_t * state, scpi_token_t * token) { 00834 token->ptr = state->pos; 00835 00836 if (skipChr(state, ',')) { 00837 token->len = 1; 00838 token->type = SCPI_TOKEN_COMMA; 00839 } else { 00840 token->len = 0; 00841 token->type = SCPI_TOKEN_UNKNOWN; 00842 } 00843 00844 return token->len; 00845 } 00846 00847 /** 00848 * Detect token semicolon 00849 * @param state 00850 * @param token 00851 * @return 00852 */ 00853 int scpiLex_Semicolon(lex_state_t * state, scpi_token_t * token) { 00854 token->ptr = state->pos; 00855 00856 if (skipChr(state, ';')) { 00857 token->len = 1; 00858 token->type = SCPI_TOKEN_SEMICOLON; 00859 } else { 00860 token->len = 0; 00861 token->type = SCPI_TOKEN_UNKNOWN; 00862 } 00863 00864 return token->len; 00865 } 00866 00867 /** 00868 * Detect token New line 00869 * @param state 00870 * @param token 00871 * @return 00872 */ 00873 int scpiLex_NewLine(lex_state_t * state, scpi_token_t * token) { 00874 token->ptr = state->pos; 00875 00876 skipChr(state, '\r'); 00877 skipChr(state, '\n'); 00878 00879 token->len = state->pos - token->ptr; 00880 00881 if ((token->len > 0)) { 00882 token->type = SCPI_TOKEN_NL; 00883 } else { 00884 token->type = SCPI_TOKEN_UNKNOWN; 00885 state->pos = token->ptr; 00886 token->len = 0; 00887 } 00888 00889 return token->len; 00890 }
Generated on Tue Jul 12 2022 19:30:15 by 1.7.2