https://github.com/j123b567/scpi-parser

Dependents:   scpi_sx127x scpi_sx127x_firstTest MLX90418_I2C_master

Committer:
dudmuck
Date:
Fri Aug 07 21:54:11 2015 +0000
Revision:
1:b497f235115a
update from github commit 6e5e3e0e3fc450eaf53feee059824ad85c4f270d

Who changed what in which revision?

UserRevisionLine numberNew contents of line
dudmuck 1:b497f235115a 1 /*-
dudmuck 1:b497f235115a 2 * Copyright (c) 2012-2013 Jan Breuer,
dudmuck 1:b497f235115a 3 *
dudmuck 1:b497f235115a 4 * All Rights Reserved
dudmuck 1:b497f235115a 5 *
dudmuck 1:b497f235115a 6 * Redistribution and use in source and binary forms, with or without
dudmuck 1:b497f235115a 7 * modification, are permitted provided that the following conditions are
dudmuck 1:b497f235115a 8 * met:
dudmuck 1:b497f235115a 9 * 1. Redistributions of source code must retain the above copyright notice,
dudmuck 1:b497f235115a 10 * this list of conditions and the following disclaimer.
dudmuck 1:b497f235115a 11 * 2. Redistributions in binary form must reproduce the above copyright
dudmuck 1:b497f235115a 12 * notice, this list of conditions and the following disclaimer in the
dudmuck 1:b497f235115a 13 * documentation and/or other materials provided with the distribution.
dudmuck 1:b497f235115a 14 *
dudmuck 1:b497f235115a 15 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
dudmuck 1:b497f235115a 16 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
dudmuck 1:b497f235115a 17 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
dudmuck 1:b497f235115a 18 * DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
dudmuck 1:b497f235115a 19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
dudmuck 1:b497f235115a 20 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
dudmuck 1:b497f235115a 21 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
dudmuck 1:b497f235115a 22 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
dudmuck 1:b497f235115a 23 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
dudmuck 1:b497f235115a 24 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
dudmuck 1:b497f235115a 25 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
dudmuck 1:b497f235115a 26 */
dudmuck 1:b497f235115a 27
dudmuck 1:b497f235115a 28 /**
dudmuck 1:b497f235115a 29 * @file lexer.c
dudmuck 1:b497f235115a 30 * @date Wed Mar 20 19:35:19 UTC 2013
dudmuck 1:b497f235115a 31 *
dudmuck 1:b497f235115a 32 * @brief SCPI Lexer
dudmuck 1:b497f235115a 33 *
dudmuck 1:b497f235115a 34 *
dudmuck 1:b497f235115a 35 */
dudmuck 1:b497f235115a 36
dudmuck 1:b497f235115a 37 #include <ctype.h>
dudmuck 1:b497f235115a 38 #include <stdio.h>
dudmuck 1:b497f235115a 39 #include <string.h>
dudmuck 1:b497f235115a 40
dudmuck 1:b497f235115a 41 #include "lexer_private.h"
dudmuck 1:b497f235115a 42 #include "scpi/error.h"
dudmuck 1:b497f235115a 43
dudmuck 1:b497f235115a 44 /**
dudmuck 1:b497f235115a 45 * Is white space
dudmuck 1:b497f235115a 46 * @param c
dudmuck 1:b497f235115a 47 * @return
dudmuck 1:b497f235115a 48 */
dudmuck 1:b497f235115a 49 static int isws(int c) {
dudmuck 1:b497f235115a 50 if ((c == ' ') || (c == '\t')) {
dudmuck 1:b497f235115a 51 return 1;
dudmuck 1:b497f235115a 52 }
dudmuck 1:b497f235115a 53 return 0;
dudmuck 1:b497f235115a 54 }
dudmuck 1:b497f235115a 55
dudmuck 1:b497f235115a 56 /**
dudmuck 1:b497f235115a 57 * Is binary digit
dudmuck 1:b497f235115a 58 * @param c
dudmuck 1:b497f235115a 59 * @return
dudmuck 1:b497f235115a 60 */
dudmuck 1:b497f235115a 61 static int isbdigit(int c) {
dudmuck 1:b497f235115a 62 if ((c == '0') || (c == '1')) {
dudmuck 1:b497f235115a 63 return 1;
dudmuck 1:b497f235115a 64 }
dudmuck 1:b497f235115a 65 return 0;
dudmuck 1:b497f235115a 66 }
dudmuck 1:b497f235115a 67
dudmuck 1:b497f235115a 68 /**
dudmuck 1:b497f235115a 69 * Is hexadecimal digit
dudmuck 1:b497f235115a 70 * @param c
dudmuck 1:b497f235115a 71 * @return
dudmuck 1:b497f235115a 72 */
dudmuck 1:b497f235115a 73 static int isqdigit(int c) {
dudmuck 1:b497f235115a 74 if ((c == '0') || (c == '1') || (c == '2') || (c == '3') || (c == '4') || (c == '5') || (c == '6') || (c == '7')) {
dudmuck 1:b497f235115a 75 return 1;
dudmuck 1:b497f235115a 76 }
dudmuck 1:b497f235115a 77 return 0;
dudmuck 1:b497f235115a 78 }
dudmuck 1:b497f235115a 79
dudmuck 1:b497f235115a 80 /**
dudmuck 1:b497f235115a 81 * Is end of string
dudmuck 1:b497f235115a 82 * @param state
dudmuck 1:b497f235115a 83 * @return
dudmuck 1:b497f235115a 84 */
dudmuck 1:b497f235115a 85 static int iseos(lex_state_t * state) {
dudmuck 1:b497f235115a 86 if ((state->buffer + state->len) <= (state->pos)) {
dudmuck 1:b497f235115a 87 return 1;
dudmuck 1:b497f235115a 88 } else {
dudmuck 1:b497f235115a 89 return 0;
dudmuck 1:b497f235115a 90 }
dudmuck 1:b497f235115a 91 }
dudmuck 1:b497f235115a 92
dudmuck 1:b497f235115a 93 /**
dudmuck 1:b497f235115a 94 * Private export of iseos
dudmuck 1:b497f235115a 95 * @param state
dudmuck 1:b497f235115a 96 * @return
dudmuck 1:b497f235115a 97 */
dudmuck 1:b497f235115a 98 int scpiLex_IsEos(lex_state_t * state) {
dudmuck 1:b497f235115a 99 return iseos(state);
dudmuck 1:b497f235115a 100 }
dudmuck 1:b497f235115a 101
dudmuck 1:b497f235115a 102 /**
dudmuck 1:b497f235115a 103 * Test current character
dudmuck 1:b497f235115a 104 * @param state
dudmuck 1:b497f235115a 105 * @param chr
dudmuck 1:b497f235115a 106 * @return
dudmuck 1:b497f235115a 107 */
dudmuck 1:b497f235115a 108 static int ischr(lex_state_t * state, char chr) {
dudmuck 1:b497f235115a 109 return (state->pos[0] == chr);
dudmuck 1:b497f235115a 110 }
dudmuck 1:b497f235115a 111
dudmuck 1:b497f235115a 112 /**
dudmuck 1:b497f235115a 113 * Is plus or minus
dudmuck 1:b497f235115a 114 * @param c
dudmuck 1:b497f235115a 115 * @return
dudmuck 1:b497f235115a 116 */
dudmuck 1:b497f235115a 117 static int isplusmn(int c) {
dudmuck 1:b497f235115a 118 return c == '+' || c == '-';
dudmuck 1:b497f235115a 119 }
dudmuck 1:b497f235115a 120
dudmuck 1:b497f235115a 121 /**
dudmuck 1:b497f235115a 122 * Is letter H
dudmuck 1:b497f235115a 123 * @param c
dudmuck 1:b497f235115a 124 * @return
dudmuck 1:b497f235115a 125 */
dudmuck 1:b497f235115a 126 static int isH(int c) {
dudmuck 1:b497f235115a 127 return c == 'h' || c == 'H';
dudmuck 1:b497f235115a 128 }
dudmuck 1:b497f235115a 129
dudmuck 1:b497f235115a 130 /**
dudmuck 1:b497f235115a 131 * Is letter B
dudmuck 1:b497f235115a 132 * @param c
dudmuck 1:b497f235115a 133 * @return
dudmuck 1:b497f235115a 134 */
dudmuck 1:b497f235115a 135 static int isB(int c) {
dudmuck 1:b497f235115a 136 return c == 'b' || c == 'B';
dudmuck 1:b497f235115a 137 }
dudmuck 1:b497f235115a 138
dudmuck 1:b497f235115a 139 /**
dudmuck 1:b497f235115a 140 * Is letter Q
dudmuck 1:b497f235115a 141 * @param c
dudmuck 1:b497f235115a 142 * @return
dudmuck 1:b497f235115a 143 */
dudmuck 1:b497f235115a 144 static int isQ(int c) {
dudmuck 1:b497f235115a 145 return c == 'q' || c == 'Q';
dudmuck 1:b497f235115a 146 }
dudmuck 1:b497f235115a 147
dudmuck 1:b497f235115a 148 /**
dudmuck 1:b497f235115a 149 * Is letter E
dudmuck 1:b497f235115a 150 * @param c
dudmuck 1:b497f235115a 151 * @return
dudmuck 1:b497f235115a 152 */
dudmuck 1:b497f235115a 153 static int isE(int c) {
dudmuck 1:b497f235115a 154 return c == 'e' || c == 'E';
dudmuck 1:b497f235115a 155 }
dudmuck 1:b497f235115a 156
dudmuck 1:b497f235115a 157 #define SKIP_NONE 0
dudmuck 1:b497f235115a 158 #define SKIP_OK 1
dudmuck 1:b497f235115a 159 #define SKIP_INCOMPLETE -1
dudmuck 1:b497f235115a 160
dudmuck 1:b497f235115a 161 /* skip characters */
dudmuck 1:b497f235115a 162 /* 7.4.1 <PROGRAM MESSAGE UNIT SEPARATOR>*/
dudmuck 1:b497f235115a 163 // TODO: static int skipProgramMessageUnitSeparator(lex_state_t * state)
dudmuck 1:b497f235115a 164
dudmuck 1:b497f235115a 165 /**
dudmuck 1:b497f235115a 166 * Skip all whitespaces
dudmuck 1:b497f235115a 167 * @param state
dudmuck 1:b497f235115a 168 * @return
dudmuck 1:b497f235115a 169 */
dudmuck 1:b497f235115a 170 static int skipWs(lex_state_t * state) {
dudmuck 1:b497f235115a 171 int someSpace = 0;
dudmuck 1:b497f235115a 172 while (!iseos(state) && isws(state->pos[0])) {
dudmuck 1:b497f235115a 173 state->pos++;
dudmuck 1:b497f235115a 174 someSpace++;
dudmuck 1:b497f235115a 175 }
dudmuck 1:b497f235115a 176
dudmuck 1:b497f235115a 177 return someSpace;
dudmuck 1:b497f235115a 178 }
dudmuck 1:b497f235115a 179
dudmuck 1:b497f235115a 180 /* 7.4.2 <PROGRAM DATA SEPARATOR> */
dudmuck 1:b497f235115a 181 // static int skipProgramDataSeparator(lex_state_t * state)
dudmuck 1:b497f235115a 182
dudmuck 1:b497f235115a 183 /* 7.5.2 <PROGRAM MESSAGE TERMINATOR> */
dudmuck 1:b497f235115a 184 // static int skipProgramMessageTerminator(lex_state_t * state)
dudmuck 1:b497f235115a 185
dudmuck 1:b497f235115a 186 /**
dudmuck 1:b497f235115a 187 * Skip decimal digit
dudmuck 1:b497f235115a 188 * @param state
dudmuck 1:b497f235115a 189 * @return
dudmuck 1:b497f235115a 190 */
dudmuck 1:b497f235115a 191 static int skipDigit(lex_state_t * state) {
dudmuck 1:b497f235115a 192 if (!iseos(state) && isdigit(state->pos[0])) {
dudmuck 1:b497f235115a 193 state->pos++;
dudmuck 1:b497f235115a 194 return SKIP_OK;
dudmuck 1:b497f235115a 195 } else {
dudmuck 1:b497f235115a 196 return SKIP_NONE;
dudmuck 1:b497f235115a 197 }
dudmuck 1:b497f235115a 198 }
dudmuck 1:b497f235115a 199
dudmuck 1:b497f235115a 200 /**
dudmuck 1:b497f235115a 201 * Skip multiple decimal digits
dudmuck 1:b497f235115a 202 * @param state
dudmuck 1:b497f235115a 203 * @return
dudmuck 1:b497f235115a 204 */
dudmuck 1:b497f235115a 205 static int skipNumbers(lex_state_t * state) {
dudmuck 1:b497f235115a 206 int someNumbers = 0;
dudmuck 1:b497f235115a 207 while (!iseos(state) && isdigit(state->pos[0])) {
dudmuck 1:b497f235115a 208 state->pos++;
dudmuck 1:b497f235115a 209 someNumbers++;
dudmuck 1:b497f235115a 210 }
dudmuck 1:b497f235115a 211 return someNumbers;
dudmuck 1:b497f235115a 212 }
dudmuck 1:b497f235115a 213
dudmuck 1:b497f235115a 214 /**
dudmuck 1:b497f235115a 215 * Skip plus or minus
dudmuck 1:b497f235115a 216 * @param state
dudmuck 1:b497f235115a 217 * @return
dudmuck 1:b497f235115a 218 */
dudmuck 1:b497f235115a 219 static int skipPlusmn(lex_state_t * state) {
dudmuck 1:b497f235115a 220 if (!iseos(state) && isplusmn(state->pos[0])) {
dudmuck 1:b497f235115a 221 state->pos++;
dudmuck 1:b497f235115a 222 return SKIP_OK;
dudmuck 1:b497f235115a 223 } else {
dudmuck 1:b497f235115a 224 return SKIP_NONE;
dudmuck 1:b497f235115a 225 }
dudmuck 1:b497f235115a 226 }
dudmuck 1:b497f235115a 227
dudmuck 1:b497f235115a 228 /**
dudmuck 1:b497f235115a 229 * Skip any character from 'a'-'Z'
dudmuck 1:b497f235115a 230 * @param state
dudmuck 1:b497f235115a 231 * @return
dudmuck 1:b497f235115a 232 */
dudmuck 1:b497f235115a 233 static int skipAlpha(lex_state_t * state) {
dudmuck 1:b497f235115a 234 int someLetters = 0;
dudmuck 1:b497f235115a 235 while (!iseos(state) && isalpha(state->pos[0])) {
dudmuck 1:b497f235115a 236 state->pos++;
dudmuck 1:b497f235115a 237 someLetters++;
dudmuck 1:b497f235115a 238 }
dudmuck 1:b497f235115a 239 return someLetters;
dudmuck 1:b497f235115a 240 }
dudmuck 1:b497f235115a 241
dudmuck 1:b497f235115a 242 /**
dudmuck 1:b497f235115a 243 * Skip exact character chr or nothing
dudmuck 1:b497f235115a 244 * @param state
dudmuck 1:b497f235115a 245 * @param chr
dudmuck 1:b497f235115a 246 * @return
dudmuck 1:b497f235115a 247 */
dudmuck 1:b497f235115a 248 static int skipChr(lex_state_t * state, char chr) {
dudmuck 1:b497f235115a 249 if (!iseos(state) && ischr(state, chr)) {
dudmuck 1:b497f235115a 250 state->pos++;
dudmuck 1:b497f235115a 251 return SKIP_OK;
dudmuck 1:b497f235115a 252 } else {
dudmuck 1:b497f235115a 253 return SKIP_NONE;
dudmuck 1:b497f235115a 254 }
dudmuck 1:b497f235115a 255 }
dudmuck 1:b497f235115a 256
dudmuck 1:b497f235115a 257 /**
dudmuck 1:b497f235115a 258 * Skip slash or dot
dudmuck 1:b497f235115a 259 * @param state
dudmuck 1:b497f235115a 260 * @return
dudmuck 1:b497f235115a 261 */
dudmuck 1:b497f235115a 262 static int skipSlashDot(lex_state_t * state) {
dudmuck 1:b497f235115a 263 if (!iseos(state) && (ischr(state, '/') | ischr(state, '.'))) {
dudmuck 1:b497f235115a 264 state->pos++;
dudmuck 1:b497f235115a 265 return SKIP_OK;
dudmuck 1:b497f235115a 266 } else {
dudmuck 1:b497f235115a 267 return SKIP_NONE;
dudmuck 1:b497f235115a 268 }
dudmuck 1:b497f235115a 269 }
dudmuck 1:b497f235115a 270
dudmuck 1:b497f235115a 271 /**
dudmuck 1:b497f235115a 272 * Skip star
dudmuck 1:b497f235115a 273 * @param state
dudmuck 1:b497f235115a 274 * @return
dudmuck 1:b497f235115a 275 */
dudmuck 1:b497f235115a 276 static int skipStar(lex_state_t * state) {
dudmuck 1:b497f235115a 277 if (!iseos(state) && ischr(state, '*')) {
dudmuck 1:b497f235115a 278 state->pos++;
dudmuck 1:b497f235115a 279 return SKIP_OK;
dudmuck 1:b497f235115a 280 } else {
dudmuck 1:b497f235115a 281 return SKIP_NONE;
dudmuck 1:b497f235115a 282 }
dudmuck 1:b497f235115a 283 }
dudmuck 1:b497f235115a 284
dudmuck 1:b497f235115a 285 /**
dudmuck 1:b497f235115a 286 * Skip colon
dudmuck 1:b497f235115a 287 * @param state
dudmuck 1:b497f235115a 288 * @return
dudmuck 1:b497f235115a 289 */
dudmuck 1:b497f235115a 290 static int skipColon(lex_state_t * state) {
dudmuck 1:b497f235115a 291 if (!iseos(state) && ischr(state, ':')) {
dudmuck 1:b497f235115a 292 state->pos++;
dudmuck 1:b497f235115a 293 return SKIP_OK;
dudmuck 1:b497f235115a 294 } else {
dudmuck 1:b497f235115a 295 return SKIP_NONE;
dudmuck 1:b497f235115a 296 }
dudmuck 1:b497f235115a 297 }
dudmuck 1:b497f235115a 298
dudmuck 1:b497f235115a 299 /* 7.6.1.2 <COMMAND PROGRAM HEADER> */
dudmuck 1:b497f235115a 300
dudmuck 1:b497f235115a 301 /**
dudmuck 1:b497f235115a 302 * Skip program mnemonic [a-z][a-z0-9_]*
dudmuck 1:b497f235115a 303 * @param state
dudmuck 1:b497f235115a 304 * @return
dudmuck 1:b497f235115a 305 */
dudmuck 1:b497f235115a 306 static int skipProgramMnemonic(lex_state_t * state) {
dudmuck 1:b497f235115a 307 const char * startPos = state->pos;
dudmuck 1:b497f235115a 308 if (!iseos(state) && isalpha(state->pos[0])) {
dudmuck 1:b497f235115a 309 state->pos++;
dudmuck 1:b497f235115a 310 while (!iseos(state) && (isalnum(state->pos[0]) || ischr(state, '_'))) {
dudmuck 1:b497f235115a 311 state->pos++;
dudmuck 1:b497f235115a 312 }
dudmuck 1:b497f235115a 313 }
dudmuck 1:b497f235115a 314
dudmuck 1:b497f235115a 315 if (iseos(state)) {
dudmuck 1:b497f235115a 316 return (state->pos - startPos) * SKIP_INCOMPLETE;
dudmuck 1:b497f235115a 317 } else {
dudmuck 1:b497f235115a 318 return (state->pos - startPos) * SKIP_OK;
dudmuck 1:b497f235115a 319 }
dudmuck 1:b497f235115a 320 }
dudmuck 1:b497f235115a 321
dudmuck 1:b497f235115a 322 /* tokens */
dudmuck 1:b497f235115a 323
dudmuck 1:b497f235115a 324 /**
dudmuck 1:b497f235115a 325 * Detect token white space
dudmuck 1:b497f235115a 326 * @param state
dudmuck 1:b497f235115a 327 * @param token
dudmuck 1:b497f235115a 328 * @return
dudmuck 1:b497f235115a 329 */
dudmuck 1:b497f235115a 330 int scpiLex_WhiteSpace(lex_state_t * state, scpi_token_t * token) {
dudmuck 1:b497f235115a 331 token->ptr = state->pos;
dudmuck 1:b497f235115a 332
dudmuck 1:b497f235115a 333 skipWs(state);
dudmuck 1:b497f235115a 334
dudmuck 1:b497f235115a 335 token->len = state->pos - token->ptr;
dudmuck 1:b497f235115a 336
dudmuck 1:b497f235115a 337 if (token->len > 0) {
dudmuck 1:b497f235115a 338 token->type = SCPI_TOKEN_WS;
dudmuck 1:b497f235115a 339 } else {
dudmuck 1:b497f235115a 340 token->type = SCPI_TOKEN_UNKNOWN;
dudmuck 1:b497f235115a 341 }
dudmuck 1:b497f235115a 342
dudmuck 1:b497f235115a 343 return token->len;
dudmuck 1:b497f235115a 344 }
dudmuck 1:b497f235115a 345
dudmuck 1:b497f235115a 346 /* 7.6.1 <COMMAND PROGRAM HEADER> */
dudmuck 1:b497f235115a 347
dudmuck 1:b497f235115a 348 /**
dudmuck 1:b497f235115a 349 * Skip command program header \*<PROGRAM MNEMONIC>
dudmuck 1:b497f235115a 350 * @param state
dudmuck 1:b497f235115a 351 * @return
dudmuck 1:b497f235115a 352 */
dudmuck 1:b497f235115a 353 static int skipCommonProgramHeader(lex_state_t * state) {
dudmuck 1:b497f235115a 354 int res;
dudmuck 1:b497f235115a 355 if (skipStar(state)) {
dudmuck 1:b497f235115a 356 res = skipProgramMnemonic(state);
dudmuck 1:b497f235115a 357 if (res == SKIP_NONE && iseos(state)) {
dudmuck 1:b497f235115a 358 return SKIP_INCOMPLETE;
dudmuck 1:b497f235115a 359 } else if (res <= SKIP_INCOMPLETE) {
dudmuck 1:b497f235115a 360 return SKIP_OK;
dudmuck 1:b497f235115a 361 } else if (res >= SKIP_OK) {
dudmuck 1:b497f235115a 362 return SKIP_OK;
dudmuck 1:b497f235115a 363 } else {
dudmuck 1:b497f235115a 364 return SKIP_INCOMPLETE;
dudmuck 1:b497f235115a 365 }
dudmuck 1:b497f235115a 366 }
dudmuck 1:b497f235115a 367 return SKIP_NONE;
dudmuck 1:b497f235115a 368 }
dudmuck 1:b497f235115a 369
dudmuck 1:b497f235115a 370 /**
dudmuck 1:b497f235115a 371 * Skip compound program header :<PROGRAM MNEMONIC>:<PROGRAM MNEMONIC>...
dudmuck 1:b497f235115a 372 * @param state
dudmuck 1:b497f235115a 373 * @return
dudmuck 1:b497f235115a 374 */
dudmuck 1:b497f235115a 375 static int skipCompoundProgramHeader(lex_state_t * state) {
dudmuck 1:b497f235115a 376 int res;
dudmuck 1:b497f235115a 377 int firstColon = skipColon(state);
dudmuck 1:b497f235115a 378
dudmuck 1:b497f235115a 379 res = skipProgramMnemonic(state);
dudmuck 1:b497f235115a 380 if (res >= SKIP_OK) {
dudmuck 1:b497f235115a 381 while (skipColon(state)) {
dudmuck 1:b497f235115a 382 res = skipProgramMnemonic(state);
dudmuck 1:b497f235115a 383 if (res <= SKIP_INCOMPLETE) {
dudmuck 1:b497f235115a 384 return SKIP_OK;
dudmuck 1:b497f235115a 385 } else if (res == SKIP_NONE) {
dudmuck 1:b497f235115a 386 return SKIP_INCOMPLETE;
dudmuck 1:b497f235115a 387 }
dudmuck 1:b497f235115a 388 }
dudmuck 1:b497f235115a 389 return SKIP_OK;
dudmuck 1:b497f235115a 390 } else if (res <= SKIP_INCOMPLETE) {
dudmuck 1:b497f235115a 391 return SKIP_OK;
dudmuck 1:b497f235115a 392 } else if (firstColon) {
dudmuck 1:b497f235115a 393 return SKIP_INCOMPLETE;
dudmuck 1:b497f235115a 394 } else {
dudmuck 1:b497f235115a 395 return SKIP_NONE;
dudmuck 1:b497f235115a 396 }
dudmuck 1:b497f235115a 397 }
dudmuck 1:b497f235115a 398
dudmuck 1:b497f235115a 399 /**
dudmuck 1:b497f235115a 400 * Detect token command or compound program header
dudmuck 1:b497f235115a 401 * @param state
dudmuck 1:b497f235115a 402 * @param token
dudmuck 1:b497f235115a 403 * @return
dudmuck 1:b497f235115a 404 */
dudmuck 1:b497f235115a 405 int scpiLex_ProgramHeader(lex_state_t * state, scpi_token_t * token) {
dudmuck 1:b497f235115a 406 int res;
dudmuck 1:b497f235115a 407 token->ptr = state->pos;
dudmuck 1:b497f235115a 408 token->type = SCPI_TOKEN_UNKNOWN;
dudmuck 1:b497f235115a 409
dudmuck 1:b497f235115a 410 res = skipCommonProgramHeader(state);
dudmuck 1:b497f235115a 411 if (res >= SKIP_OK) {
dudmuck 1:b497f235115a 412 if (skipChr(state, '?') >= SKIP_OK) {
dudmuck 1:b497f235115a 413 token->type = SCPI_TOKEN_COMMON_QUERY_PROGRAM_HEADER;
dudmuck 1:b497f235115a 414 } else {
dudmuck 1:b497f235115a 415 token->type = SCPI_TOKEN_COMMON_PROGRAM_HEADER;
dudmuck 1:b497f235115a 416 }
dudmuck 1:b497f235115a 417 } else if (res <= SKIP_INCOMPLETE) {
dudmuck 1:b497f235115a 418 token->type = SCPI_TOKEN_INCOMPLETE_COMMON_PROGRAM_HEADER;
dudmuck 1:b497f235115a 419 } else if (res == SKIP_NONE) {
dudmuck 1:b497f235115a 420 res = skipCompoundProgramHeader(state);
dudmuck 1:b497f235115a 421
dudmuck 1:b497f235115a 422 if (res >= SKIP_OK) {
dudmuck 1:b497f235115a 423 if (skipChr(state, '?') >= SKIP_OK) {
dudmuck 1:b497f235115a 424 token->type = SCPI_TOKEN_COMPOUND_QUERY_PROGRAM_HEADER;
dudmuck 1:b497f235115a 425 } else {
dudmuck 1:b497f235115a 426 token->type = SCPI_TOKEN_COMPOUND_PROGRAM_HEADER;
dudmuck 1:b497f235115a 427 }
dudmuck 1:b497f235115a 428 } else if (res <= SKIP_INCOMPLETE) {
dudmuck 1:b497f235115a 429 token->type = SCPI_TOKEN_INCOMPLETE_COMPOUND_PROGRAM_HEADER;
dudmuck 1:b497f235115a 430 }
dudmuck 1:b497f235115a 431 }
dudmuck 1:b497f235115a 432
dudmuck 1:b497f235115a 433 if (token->type != SCPI_TOKEN_UNKNOWN) {
dudmuck 1:b497f235115a 434 token->len = state->pos - token->ptr;
dudmuck 1:b497f235115a 435 } else {
dudmuck 1:b497f235115a 436 token->len = 0;
dudmuck 1:b497f235115a 437 state->pos = token->ptr;
dudmuck 1:b497f235115a 438 }
dudmuck 1:b497f235115a 439
dudmuck 1:b497f235115a 440 return token->len;
dudmuck 1:b497f235115a 441 }
dudmuck 1:b497f235115a 442
dudmuck 1:b497f235115a 443 /* 7.7.1 <CHARACTER PROGRAM DATA> */
dudmuck 1:b497f235115a 444
dudmuck 1:b497f235115a 445 /**
dudmuck 1:b497f235115a 446 * Detect token "Character program data"
dudmuck 1:b497f235115a 447 * @param state
dudmuck 1:b497f235115a 448 * @param token
dudmuck 1:b497f235115a 449 * @return
dudmuck 1:b497f235115a 450 */
dudmuck 1:b497f235115a 451 int scpiLex_CharacterProgramData(lex_state_t * state, scpi_token_t * token) {
dudmuck 1:b497f235115a 452 token->ptr = state->pos;
dudmuck 1:b497f235115a 453
dudmuck 1:b497f235115a 454 if (!iseos(state) && isalpha(state->pos[0])) {
dudmuck 1:b497f235115a 455 state->pos++;
dudmuck 1:b497f235115a 456 while (!iseos(state) && (isalnum(state->pos[0]) || ischr(state, '_'))) {
dudmuck 1:b497f235115a 457 state->pos++;
dudmuck 1:b497f235115a 458 }
dudmuck 1:b497f235115a 459 }
dudmuck 1:b497f235115a 460
dudmuck 1:b497f235115a 461 token->len = state->pos - token->ptr;
dudmuck 1:b497f235115a 462 if (token->len > 0) {
dudmuck 1:b497f235115a 463 token->type = SCPI_TOKEN_PROGRAM_MNEMONIC;
dudmuck 1:b497f235115a 464 } else {
dudmuck 1:b497f235115a 465 token->type = SCPI_TOKEN_UNKNOWN;
dudmuck 1:b497f235115a 466 }
dudmuck 1:b497f235115a 467
dudmuck 1:b497f235115a 468 return token->len;
dudmuck 1:b497f235115a 469 }
dudmuck 1:b497f235115a 470
dudmuck 1:b497f235115a 471 /* 7.7.2 <DECIMAL NUMERIC PROGRAM DATA> */
dudmuck 1:b497f235115a 472 static int skipMantisa(lex_state_t * state) {
dudmuck 1:b497f235115a 473 int someNumbers = 0;
dudmuck 1:b497f235115a 474
dudmuck 1:b497f235115a 475 skipPlusmn(state);
dudmuck 1:b497f235115a 476
dudmuck 1:b497f235115a 477 someNumbers += skipNumbers(state);
dudmuck 1:b497f235115a 478
dudmuck 1:b497f235115a 479 if (skipChr(state, '.')) {
dudmuck 1:b497f235115a 480 someNumbers += skipNumbers(state);
dudmuck 1:b497f235115a 481 }
dudmuck 1:b497f235115a 482
dudmuck 1:b497f235115a 483 return someNumbers;
dudmuck 1:b497f235115a 484 }
dudmuck 1:b497f235115a 485
dudmuck 1:b497f235115a 486 static int skipExponent(lex_state_t * state) {
dudmuck 1:b497f235115a 487 int someNumbers = 0;
dudmuck 1:b497f235115a 488
dudmuck 1:b497f235115a 489 if (!iseos(state) && isE(state->pos[0])) {
dudmuck 1:b497f235115a 490 state->pos++;
dudmuck 1:b497f235115a 491
dudmuck 1:b497f235115a 492 skipWs(state);
dudmuck 1:b497f235115a 493
dudmuck 1:b497f235115a 494 skipPlusmn(state);
dudmuck 1:b497f235115a 495
dudmuck 1:b497f235115a 496 someNumbers = skipNumbers(state);
dudmuck 1:b497f235115a 497 }
dudmuck 1:b497f235115a 498
dudmuck 1:b497f235115a 499 return someNumbers;
dudmuck 1:b497f235115a 500 }
dudmuck 1:b497f235115a 501
dudmuck 1:b497f235115a 502 /**
dudmuck 1:b497f235115a 503 * Detect token Decimal number
dudmuck 1:b497f235115a 504 * @param state
dudmuck 1:b497f235115a 505 * @param token
dudmuck 1:b497f235115a 506 * @return
dudmuck 1:b497f235115a 507 */
dudmuck 1:b497f235115a 508 int scpiLex_DecimalNumericProgramData(lex_state_t * state, scpi_token_t * token) {
dudmuck 1:b497f235115a 509 char * rollback;
dudmuck 1:b497f235115a 510 token->ptr = state->pos;
dudmuck 1:b497f235115a 511
dudmuck 1:b497f235115a 512 if (skipMantisa(state)) {
dudmuck 1:b497f235115a 513 rollback = state->pos;
dudmuck 1:b497f235115a 514 skipWs(state);
dudmuck 1:b497f235115a 515 if (!skipExponent(state)) {
dudmuck 1:b497f235115a 516 state->pos = rollback;
dudmuck 1:b497f235115a 517 }
dudmuck 1:b497f235115a 518 } else {
dudmuck 1:b497f235115a 519 state->pos = token->ptr;
dudmuck 1:b497f235115a 520 }
dudmuck 1:b497f235115a 521
dudmuck 1:b497f235115a 522 token->len = state->pos - token->ptr;
dudmuck 1:b497f235115a 523 if (token->len > 0) {
dudmuck 1:b497f235115a 524 token->type = SCPI_TOKEN_DECIMAL_NUMERIC_PROGRAM_DATA;
dudmuck 1:b497f235115a 525 } else {
dudmuck 1:b497f235115a 526 token->type = SCPI_TOKEN_UNKNOWN;
dudmuck 1:b497f235115a 527 }
dudmuck 1:b497f235115a 528
dudmuck 1:b497f235115a 529 return token->len;
dudmuck 1:b497f235115a 530 }
dudmuck 1:b497f235115a 531
dudmuck 1:b497f235115a 532 /* 7.7.3 <SUFFIX PROGRAM DATA> */
dudmuck 1:b497f235115a 533 int scpiLex_SuffixProgramData(lex_state_t * state, scpi_token_t * token) {
dudmuck 1:b497f235115a 534 token->ptr = state->pos;
dudmuck 1:b497f235115a 535
dudmuck 1:b497f235115a 536 skipChr(state, '/');
dudmuck 1:b497f235115a 537
dudmuck 1:b497f235115a 538 // TODO: strict parsing : SLASH? (ALPHA+ (MINUS? DIGIT)?) ((SLASH | DOT) (ALPHA+ (MINUS? DIGIT)?))*
dudmuck 1:b497f235115a 539 if (skipAlpha(state)) {
dudmuck 1:b497f235115a 540 skipChr(state, '-');
dudmuck 1:b497f235115a 541 skipDigit(state);
dudmuck 1:b497f235115a 542
dudmuck 1:b497f235115a 543 while (skipSlashDot(state)) {
dudmuck 1:b497f235115a 544 skipAlpha(state);
dudmuck 1:b497f235115a 545 skipChr(state, '-');
dudmuck 1:b497f235115a 546 skipDigit(state);
dudmuck 1:b497f235115a 547 }
dudmuck 1:b497f235115a 548 }
dudmuck 1:b497f235115a 549
dudmuck 1:b497f235115a 550 token->len = state->pos - token->ptr;
dudmuck 1:b497f235115a 551 if ((token->len > 0)) {
dudmuck 1:b497f235115a 552 token->type = SCPI_TOKEN_SUFFIX_PROGRAM_DATA;
dudmuck 1:b497f235115a 553 } else {
dudmuck 1:b497f235115a 554 token->type = SCPI_TOKEN_UNKNOWN;
dudmuck 1:b497f235115a 555 state->pos = token->ptr;
dudmuck 1:b497f235115a 556 token->len = 0;
dudmuck 1:b497f235115a 557 }
dudmuck 1:b497f235115a 558
dudmuck 1:b497f235115a 559 return token->len;
dudmuck 1:b497f235115a 560 }
dudmuck 1:b497f235115a 561
dudmuck 1:b497f235115a 562 /* 7.7.4 <NONDECIMAL NUMERIC PROGRAM DATA> */
dudmuck 1:b497f235115a 563 static int skipHexNum(lex_state_t * state) {
dudmuck 1:b497f235115a 564 int someNumbers = 0;
dudmuck 1:b497f235115a 565 while (!iseos(state) && isxdigit(state->pos[0])) {
dudmuck 1:b497f235115a 566 state->pos++;
dudmuck 1:b497f235115a 567 someNumbers++;
dudmuck 1:b497f235115a 568 }
dudmuck 1:b497f235115a 569 return someNumbers;
dudmuck 1:b497f235115a 570 }
dudmuck 1:b497f235115a 571
dudmuck 1:b497f235115a 572 static int skipOctNum(lex_state_t * state) {
dudmuck 1:b497f235115a 573 int someNumbers = 0;
dudmuck 1:b497f235115a 574 while (!iseos(state) && isqdigit(state->pos[0])) {
dudmuck 1:b497f235115a 575 state->pos++;
dudmuck 1:b497f235115a 576 someNumbers++;
dudmuck 1:b497f235115a 577 }
dudmuck 1:b497f235115a 578 return someNumbers;
dudmuck 1:b497f235115a 579 }
dudmuck 1:b497f235115a 580
dudmuck 1:b497f235115a 581 static int skipBinNum(lex_state_t * state) {
dudmuck 1:b497f235115a 582 int someNumbers = 0;
dudmuck 1:b497f235115a 583 while (!iseos(state) && isbdigit(state->pos[0])) {
dudmuck 1:b497f235115a 584 state->pos++;
dudmuck 1:b497f235115a 585 someNumbers++;
dudmuck 1:b497f235115a 586 }
dudmuck 1:b497f235115a 587 return someNumbers;
dudmuck 1:b497f235115a 588 }
dudmuck 1:b497f235115a 589
dudmuck 1:b497f235115a 590 /**
dudmuck 1:b497f235115a 591 * Detect token nondecimal number
dudmuck 1:b497f235115a 592 * @param state
dudmuck 1:b497f235115a 593 * @param token
dudmuck 1:b497f235115a 594 * @return
dudmuck 1:b497f235115a 595 */
dudmuck 1:b497f235115a 596 int scpiLex_NondecimalNumericData(lex_state_t * state, scpi_token_t * token) {
dudmuck 1:b497f235115a 597 int someNumbers = 0;
dudmuck 1:b497f235115a 598 token->ptr = state->pos;
dudmuck 1:b497f235115a 599 if (skipChr(state, '#')) {
dudmuck 1:b497f235115a 600 if (!iseos(state)) {
dudmuck 1:b497f235115a 601 if (isH(state->pos[0])) {
dudmuck 1:b497f235115a 602 state->pos++;
dudmuck 1:b497f235115a 603 someNumbers = skipHexNum(state);
dudmuck 1:b497f235115a 604 token->type = SCPI_TOKEN_HEXNUM;
dudmuck 1:b497f235115a 605 } else if (isQ(state->pos[0])) {
dudmuck 1:b497f235115a 606 state->pos++;
dudmuck 1:b497f235115a 607 someNumbers = skipOctNum(state);
dudmuck 1:b497f235115a 608 token->type = SCPI_TOKEN_OCTNUM;
dudmuck 1:b497f235115a 609 } else if (isB(state->pos[0])) {
dudmuck 1:b497f235115a 610 state->pos++;
dudmuck 1:b497f235115a 611 someNumbers = skipBinNum(state);
dudmuck 1:b497f235115a 612 token->type = SCPI_TOKEN_BINNUM;
dudmuck 1:b497f235115a 613 }
dudmuck 1:b497f235115a 614 }
dudmuck 1:b497f235115a 615 }
dudmuck 1:b497f235115a 616
dudmuck 1:b497f235115a 617 if (someNumbers) {
dudmuck 1:b497f235115a 618 token->ptr += 2; // ignore number prefix
dudmuck 1:b497f235115a 619 token->len = state->pos - token->ptr;
dudmuck 1:b497f235115a 620 } else {
dudmuck 1:b497f235115a 621 token->type = SCPI_TOKEN_UNKNOWN;
dudmuck 1:b497f235115a 622 state->pos = token->ptr;
dudmuck 1:b497f235115a 623 token->len = 0;
dudmuck 1:b497f235115a 624 }
dudmuck 1:b497f235115a 625 return token->len > 0 ? token->len + 2 : 0;
dudmuck 1:b497f235115a 626 }
dudmuck 1:b497f235115a 627
dudmuck 1:b497f235115a 628 /* 7.7.5 <STRING PROGRAM DATA> */
dudmuck 1:b497f235115a 629 static int isascii7bit(int c) {
dudmuck 1:b497f235115a 630 return (c >= 0) && (c <= 0x7f);
dudmuck 1:b497f235115a 631 }
dudmuck 1:b497f235115a 632
dudmuck 1:b497f235115a 633 static void skipQuoteProgramData(lex_state_t * state, char quote) {
dudmuck 1:b497f235115a 634 while (!iseos(state)) {
dudmuck 1:b497f235115a 635 if (isascii7bit(state->pos[0]) && !ischr(state, quote)) {
dudmuck 1:b497f235115a 636 state->pos++;
dudmuck 1:b497f235115a 637 } else if (ischr(state, quote)) {
dudmuck 1:b497f235115a 638 state->pos++;
dudmuck 1:b497f235115a 639 if (!iseos(state) && ischr(state, quote)) {
dudmuck 1:b497f235115a 640 state->pos++;
dudmuck 1:b497f235115a 641 } else {
dudmuck 1:b497f235115a 642 state->pos--;
dudmuck 1:b497f235115a 643 break;
dudmuck 1:b497f235115a 644 }
dudmuck 1:b497f235115a 645 }
dudmuck 1:b497f235115a 646 }
dudmuck 1:b497f235115a 647 }
dudmuck 1:b497f235115a 648
dudmuck 1:b497f235115a 649 static void skipDoubleQuoteProgramData(lex_state_t * state) {
dudmuck 1:b497f235115a 650 skipQuoteProgramData(state, '"');
dudmuck 1:b497f235115a 651 }
dudmuck 1:b497f235115a 652
dudmuck 1:b497f235115a 653 static void skipSingleQuoteProgramData(lex_state_t * state) {
dudmuck 1:b497f235115a 654 skipQuoteProgramData(state, '\'');
dudmuck 1:b497f235115a 655 }
dudmuck 1:b497f235115a 656
dudmuck 1:b497f235115a 657 /**
dudmuck 1:b497f235115a 658 * Detect token String data
dudmuck 1:b497f235115a 659 * @param state
dudmuck 1:b497f235115a 660 * @param token
dudmuck 1:b497f235115a 661 * @return
dudmuck 1:b497f235115a 662 */
dudmuck 1:b497f235115a 663 int scpiLex_StringProgramData(lex_state_t * state, scpi_token_t * token) {
dudmuck 1:b497f235115a 664 token->ptr = state->pos;
dudmuck 1:b497f235115a 665
dudmuck 1:b497f235115a 666 if (!iseos(state)) {
dudmuck 1:b497f235115a 667 if (ischr(state, '"')) {
dudmuck 1:b497f235115a 668 state->pos++;
dudmuck 1:b497f235115a 669 token->type = SCPI_TOKEN_DOUBLE_QUOTE_PROGRAM_DATA;
dudmuck 1:b497f235115a 670 skipDoubleQuoteProgramData(state);
dudmuck 1:b497f235115a 671 if (!iseos(state) && ischr(state, '"')) {
dudmuck 1:b497f235115a 672 state->pos++;
dudmuck 1:b497f235115a 673 token->len = state->pos - token->ptr;
dudmuck 1:b497f235115a 674 } else {
dudmuck 1:b497f235115a 675 state->pos = token->ptr;
dudmuck 1:b497f235115a 676 }
dudmuck 1:b497f235115a 677 } else if (ischr(state, '\'')) {
dudmuck 1:b497f235115a 678 state->pos++;
dudmuck 1:b497f235115a 679 token->type = SCPI_TOKEN_SINGLE_QUOTE_PROGRAM_DATA;
dudmuck 1:b497f235115a 680 skipSingleQuoteProgramData(state);
dudmuck 1:b497f235115a 681 if (!iseos(state) && ischr(state, '\'')) {
dudmuck 1:b497f235115a 682 state->pos++;
dudmuck 1:b497f235115a 683 token->len = state->pos - token->ptr;
dudmuck 1:b497f235115a 684 } else {
dudmuck 1:b497f235115a 685 state->pos = token->ptr;
dudmuck 1:b497f235115a 686 }
dudmuck 1:b497f235115a 687 }
dudmuck 1:b497f235115a 688 }
dudmuck 1:b497f235115a 689
dudmuck 1:b497f235115a 690 token->len = state->pos - token->ptr;
dudmuck 1:b497f235115a 691
dudmuck 1:b497f235115a 692 if ((token->len > 0)) {
dudmuck 1:b497f235115a 693 token->ptr++;
dudmuck 1:b497f235115a 694 token->len -= 2;
dudmuck 1:b497f235115a 695 } else {
dudmuck 1:b497f235115a 696 token->type = SCPI_TOKEN_UNKNOWN;
dudmuck 1:b497f235115a 697 state->pos = token->ptr;
dudmuck 1:b497f235115a 698 token->len = 0;
dudmuck 1:b497f235115a 699 }
dudmuck 1:b497f235115a 700
dudmuck 1:b497f235115a 701 return token->len > 0 ? token->len + 2 : 0;
dudmuck 1:b497f235115a 702 }
dudmuck 1:b497f235115a 703
dudmuck 1:b497f235115a 704 /* 7.7.6 <ARBITRARY BLOCK PROGRAM DATA> */
dudmuck 1:b497f235115a 705 static int isNonzeroDigit(int c) {
dudmuck 1:b497f235115a 706 return isdigit(c) && (c != '0');
dudmuck 1:b497f235115a 707 }
dudmuck 1:b497f235115a 708
dudmuck 1:b497f235115a 709 /**
dudmuck 1:b497f235115a 710 * Detect token Block Data
dudmuck 1:b497f235115a 711 * @param state
dudmuck 1:b497f235115a 712 * @param token
dudmuck 1:b497f235115a 713 * @return
dudmuck 1:b497f235115a 714 */
dudmuck 1:b497f235115a 715 int scpiLex_ArbitraryBlockProgramData(lex_state_t * state, scpi_token_t * token) {
dudmuck 1:b497f235115a 716 int i;
dudmuck 1:b497f235115a 717 int arbitraryBlockLength = 0;
dudmuck 1:b497f235115a 718 const char * ptr = state->pos;
dudmuck 1:b497f235115a 719 int validData = -1;
dudmuck 1:b497f235115a 720 token->ptr = state->pos;
dudmuck 1:b497f235115a 721
dudmuck 1:b497f235115a 722 if (skipChr(state, '#')) {
dudmuck 1:b497f235115a 723 if (!iseos(state) && isNonzeroDigit(state->pos[0])) {
dudmuck 1:b497f235115a 724 /* Get number of digits */
dudmuck 1:b497f235115a 725 i = state->pos[0] - '0';
dudmuck 1:b497f235115a 726 state->pos++;
dudmuck 1:b497f235115a 727
dudmuck 1:b497f235115a 728 for (; i > 0; i--) {
dudmuck 1:b497f235115a 729 if (!iseos(state) && isdigit(state->pos[0])) {
dudmuck 1:b497f235115a 730 arbitraryBlockLength *= 10;
dudmuck 1:b497f235115a 731 arbitraryBlockLength += (state->pos[0] - '0');
dudmuck 1:b497f235115a 732 state->pos++;
dudmuck 1:b497f235115a 733 } else {
dudmuck 1:b497f235115a 734 break;
dudmuck 1:b497f235115a 735 }
dudmuck 1:b497f235115a 736 }
dudmuck 1:b497f235115a 737
dudmuck 1:b497f235115a 738 if (i == 0) {
dudmuck 1:b497f235115a 739 state->pos += arbitraryBlockLength;
dudmuck 1:b497f235115a 740 if ((state->buffer + state->len) >= (state->pos)) {
dudmuck 1:b497f235115a 741 token->ptr = state->pos - arbitraryBlockLength;
dudmuck 1:b497f235115a 742 token->len = arbitraryBlockLength;
dudmuck 1:b497f235115a 743 validData = 1;
dudmuck 1:b497f235115a 744 }
dudmuck 1:b497f235115a 745 } else if (iseos(state)) {
dudmuck 1:b497f235115a 746 validData = 0;
dudmuck 1:b497f235115a 747 }
dudmuck 1:b497f235115a 748 } else if (iseos(state)) {
dudmuck 1:b497f235115a 749 validData = 0;
dudmuck 1:b497f235115a 750 }
dudmuck 1:b497f235115a 751 }
dudmuck 1:b497f235115a 752
dudmuck 1:b497f235115a 753 if (validData == 1) {
dudmuck 1:b497f235115a 754 // valid
dudmuck 1:b497f235115a 755 token->type = SCPI_TOKEN_ARBITRARY_BLOCK_PROGRAM_DATA;
dudmuck 1:b497f235115a 756 } else if (validData == 0) {
dudmuck 1:b497f235115a 757 // incomplete
dudmuck 1:b497f235115a 758 token->type = SCPI_TOKEN_UNKNOWN;
dudmuck 1:b497f235115a 759 token->len = 0;
dudmuck 1:b497f235115a 760 state->pos = state->buffer + state->len;
dudmuck 1:b497f235115a 761 } else {
dudmuck 1:b497f235115a 762 // invalid
dudmuck 1:b497f235115a 763 token->type = SCPI_TOKEN_UNKNOWN;
dudmuck 1:b497f235115a 764 state->pos = token->ptr;
dudmuck 1:b497f235115a 765 token->len = 0;
dudmuck 1:b497f235115a 766 }
dudmuck 1:b497f235115a 767
dudmuck 1:b497f235115a 768 return token->len + (token->ptr - ptr);
dudmuck 1:b497f235115a 769 }
dudmuck 1:b497f235115a 770
dudmuck 1:b497f235115a 771 /* 7.7.7 <EXPRESSION PROGRAM DATA> */
dudmuck 1:b497f235115a 772 static int isProgramExpression(int c) {
dudmuck 1:b497f235115a 773 if ((c >= 0x20) && (c <= 0x7e)) {
dudmuck 1:b497f235115a 774 if ((c != 0x22)
dudmuck 1:b497f235115a 775 && (c != 0x23)
dudmuck 1:b497f235115a 776 && (c != 0x27)
dudmuck 1:b497f235115a 777 && (c != 0x28)
dudmuck 1:b497f235115a 778 && (c != 0x29)
dudmuck 1:b497f235115a 779 && (c != 0x3B)) {
dudmuck 1:b497f235115a 780 return 1;
dudmuck 1:b497f235115a 781 }
dudmuck 1:b497f235115a 782 }
dudmuck 1:b497f235115a 783
dudmuck 1:b497f235115a 784 return 0;
dudmuck 1:b497f235115a 785 }
dudmuck 1:b497f235115a 786
dudmuck 1:b497f235115a 787 static void skipProgramExpression(lex_state_t * state) {
dudmuck 1:b497f235115a 788 while (!iseos(state) && isProgramExpression(state->pos[0])) {
dudmuck 1:b497f235115a 789 state->pos++;
dudmuck 1:b497f235115a 790 }
dudmuck 1:b497f235115a 791 }
dudmuck 1:b497f235115a 792
dudmuck 1:b497f235115a 793 // TODO: 7.7.7.2-2 recursive - any program data
dudmuck 1:b497f235115a 794
dudmuck 1:b497f235115a 795 /**
dudmuck 1:b497f235115a 796 * Detect token Expression
dudmuck 1:b497f235115a 797 * @param state
dudmuck 1:b497f235115a 798 * @param token
dudmuck 1:b497f235115a 799 * @return
dudmuck 1:b497f235115a 800 */
dudmuck 1:b497f235115a 801 int scpiLex_ProgramExpression(lex_state_t * state, scpi_token_t * token) {
dudmuck 1:b497f235115a 802 token->ptr = state->pos;
dudmuck 1:b497f235115a 803
dudmuck 1:b497f235115a 804 if (!iseos(state) && ischr(state, '(')) {
dudmuck 1:b497f235115a 805 state->pos++;
dudmuck 1:b497f235115a 806 skipProgramExpression(state);
dudmuck 1:b497f235115a 807
dudmuck 1:b497f235115a 808 if (!iseos(state) && ischr(state, ')')) {
dudmuck 1:b497f235115a 809 state->pos++;
dudmuck 1:b497f235115a 810 token->len = state->pos - token->ptr;
dudmuck 1:b497f235115a 811 } else {
dudmuck 1:b497f235115a 812 token->len = 0;
dudmuck 1:b497f235115a 813 }
dudmuck 1:b497f235115a 814 }
dudmuck 1:b497f235115a 815
dudmuck 1:b497f235115a 816 if ((token->len > 0)) {
dudmuck 1:b497f235115a 817 token->type = SCPI_TOKEN_PROGRAM_EXPRESSION;
dudmuck 1:b497f235115a 818 } else {
dudmuck 1:b497f235115a 819 token->type = SCPI_TOKEN_UNKNOWN;
dudmuck 1:b497f235115a 820 state->pos = token->ptr;
dudmuck 1:b497f235115a 821 token->len = 0;
dudmuck 1:b497f235115a 822 }
dudmuck 1:b497f235115a 823
dudmuck 1:b497f235115a 824 return token->len;
dudmuck 1:b497f235115a 825 }
dudmuck 1:b497f235115a 826
dudmuck 1:b497f235115a 827 /**
dudmuck 1:b497f235115a 828 * Detect token comma
dudmuck 1:b497f235115a 829 * @param state
dudmuck 1:b497f235115a 830 * @param token
dudmuck 1:b497f235115a 831 * @return
dudmuck 1:b497f235115a 832 */
dudmuck 1:b497f235115a 833 int scpiLex_Comma(lex_state_t * state, scpi_token_t * token) {
dudmuck 1:b497f235115a 834 token->ptr = state->pos;
dudmuck 1:b497f235115a 835
dudmuck 1:b497f235115a 836 if (skipChr(state, ',')) {
dudmuck 1:b497f235115a 837 token->len = 1;
dudmuck 1:b497f235115a 838 token->type = SCPI_TOKEN_COMMA;
dudmuck 1:b497f235115a 839 } else {
dudmuck 1:b497f235115a 840 token->len = 0;
dudmuck 1:b497f235115a 841 token->type = SCPI_TOKEN_UNKNOWN;
dudmuck 1:b497f235115a 842 }
dudmuck 1:b497f235115a 843
dudmuck 1:b497f235115a 844 return token->len;
dudmuck 1:b497f235115a 845 }
dudmuck 1:b497f235115a 846
dudmuck 1:b497f235115a 847 /**
dudmuck 1:b497f235115a 848 * Detect token semicolon
dudmuck 1:b497f235115a 849 * @param state
dudmuck 1:b497f235115a 850 * @param token
dudmuck 1:b497f235115a 851 * @return
dudmuck 1:b497f235115a 852 */
dudmuck 1:b497f235115a 853 int scpiLex_Semicolon(lex_state_t * state, scpi_token_t * token) {
dudmuck 1:b497f235115a 854 token->ptr = state->pos;
dudmuck 1:b497f235115a 855
dudmuck 1:b497f235115a 856 if (skipChr(state, ';')) {
dudmuck 1:b497f235115a 857 token->len = 1;
dudmuck 1:b497f235115a 858 token->type = SCPI_TOKEN_SEMICOLON;
dudmuck 1:b497f235115a 859 } else {
dudmuck 1:b497f235115a 860 token->len = 0;
dudmuck 1:b497f235115a 861 token->type = SCPI_TOKEN_UNKNOWN;
dudmuck 1:b497f235115a 862 }
dudmuck 1:b497f235115a 863
dudmuck 1:b497f235115a 864 return token->len;
dudmuck 1:b497f235115a 865 }
dudmuck 1:b497f235115a 866
dudmuck 1:b497f235115a 867 /**
dudmuck 1:b497f235115a 868 * Detect token New line
dudmuck 1:b497f235115a 869 * @param state
dudmuck 1:b497f235115a 870 * @param token
dudmuck 1:b497f235115a 871 * @return
dudmuck 1:b497f235115a 872 */
dudmuck 1:b497f235115a 873 int scpiLex_NewLine(lex_state_t * state, scpi_token_t * token) {
dudmuck 1:b497f235115a 874 token->ptr = state->pos;
dudmuck 1:b497f235115a 875
dudmuck 1:b497f235115a 876 skipChr(state, '\r');
dudmuck 1:b497f235115a 877 skipChr(state, '\n');
dudmuck 1:b497f235115a 878
dudmuck 1:b497f235115a 879 token->len = state->pos - token->ptr;
dudmuck 1:b497f235115a 880
dudmuck 1:b497f235115a 881 if ((token->len > 0)) {
dudmuck 1:b497f235115a 882 token->type = SCPI_TOKEN_NL;
dudmuck 1:b497f235115a 883 } else {
dudmuck 1:b497f235115a 884 token->type = SCPI_TOKEN_UNKNOWN;
dudmuck 1:b497f235115a 885 state->pos = token->ptr;
dudmuck 1:b497f235115a 886 token->len = 0;
dudmuck 1:b497f235115a 887 }
dudmuck 1:b497f235115a 888
dudmuck 1:b497f235115a 889 return token->len;
dudmuck 1:b497f235115a 890 }