1/*2 * Copyright © 2016-2018 Sören Tempel3 *4 * This program is free software: you can redistribute it and/or5 * modify it under the terms of the GNU Affero General Public6 * License as published by the Free Software Foundation, either7 * version 3 of the License, or (at your option) any later version.8 *9 * This program is distributed in the hope that it will be useful,10 * but WITHOUT ANY WARRANTY; without even the implied warranty of11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU12 * Affero General Public License for more details.13 *14 * You should have received a copy of the GNU Affero General Public15 * License along with this program. If not, see16 * <http://www.gnu.org/licenses/>.17 */1819#ifndef TMSIM_SCANNER_H20#define TMSIM_SCANNER_H2122#include <pthread.h>2324#include <sys/types.h>2526#include "queue.h"27#include "token.h"2829/**30 * Can be used in conjunction with emit if the character in the input31 * string at the start position of this token should be used as the32 * value field of the enqueued token.33 *34 * @param SCANNER Scanner for which a value should be emitted.35 */36#define TOKAUTO(SCANNER) (SCANNER->input[scr->start])3738/**39 * Macro which must be used to return from a ::scanfn function. This40 * macro sets the state field of given scanner and returns afterwards.41 *42 * @param SCANNER Scanner for which state field should be modified.43 * @param FUNCTION Function pointer which should be used as the next44 * state.45 */46#define LEXRET(SCANNER, FUNCTION) \47 do { \48 SCANNER->state = FUNCTION; \49 return; \50 } while (0)5152enum {53 /**54 * Passed to emit (as value) if the token doesn't have a55 * meaningful character value.56 */57 TOKNOP = 0,5859 /**60 * Amount of bytes needed for a string representation of the61 * ::tmname type plus one byte for null termination. This value62 * is somewhat heuristic.63 */64 STATELEN = 64,65};6667/**68 * Multithreaded lexer for the tmsim input files.69 */70typedef struct _scanner scanner;7172/**73 * Function pointer representing the current state of a ::scanner.74 */75typedef void (*scanfn)(scanner *scr);7677struct _scanner {78 /**79 * Current state of the scanner. This field points to the80 * function which should be invoked next for parsing the81 * upcoming characters.82 */83 scanfn state;8485 /**86 * Thread used to perform lexical scanning of the input string.87 */88 pthread_t thread;8990 /**91 * Queue to which recognized tokens should be added.92 */93 queue *tqueue;9495 char *input; /**< Input string passed to ::scanstr. */96 size_t inlen; /**< Length of the input string. */9798 size_t pos; /**< Current position in the input string. */99 size_t start; /**< Start position of current token in input string. */100101 unsigned int line; /**< Line being analyzed currently. */102 unsigned int column; /**< Column being analyzed currently. */103};104105scanner *scanstr(char *, size_t);106token *nexttoken(scanner *);107void freescanner(scanner *);108109#endif