X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Flanguage%2Flexer%2Fscan.c;h=6e9fc618e1568727ef04c6c41f4bf5ae951b9538;hb=b6a62580b53945471660ac9090dac4481e123983;hp=caf294a9d123b4aa28192775ba25aa5d53cb9e7e;hpb=fe8dc2171009e90d2335f159d05f7e6660e24780;p=pspp diff --git a/src/language/lexer/scan.c b/src/language/lexer/scan.c index caf294a9d1..6e9fc618e1 100644 --- a/src/language/lexer/scan.c +++ b/src/language/lexer/scan.c @@ -1,5 +1,5 @@ /* PSPP - a program for statistical analysis. - Copyright (C) 2010, 2011 Free Software Foundation, Inc. + Copyright (C) 2010, 2011, 2013 Free Software Foundation, Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -27,6 +27,7 @@ #include "libpspp/cast.h" #include "gl/c-ctype.h" +#include "gl/c-strtod.h" #include "gl/xmemdup0.h" enum @@ -379,7 +380,7 @@ scan_number__ (struct substring s) else p = xmemdup0 (s.string, s.length); - number = strtod (p, NULL); + number = c_strtod (p, NULL); if (p != buf) free (p); @@ -502,9 +503,6 @@ scan_start__ (struct scanner *scanner, enum segment_type type, case SEG_UNEXPECTED_CHAR: return scan_unexpected_char (&s, token); - - case SEG_N_TYPES: - NOT_REACHED (); } NOT_REACHED (); @@ -594,3 +592,58 @@ scanner_push (struct scanner *scanner, enum segment_type type, NOT_REACHED (); } + +/* Initializes SLEX for parsing INPUT in the specified MODE. + + SLEX has no internal state to free, but it retains a reference to INPUT, so + INPUT must not be modified or freed while SLEX is still in use. */ +void +string_lexer_init (struct string_lexer *slex, const char *input, + enum segmenter_mode mode) +{ + slex->input = input; + slex->length = strlen (input) + 1; + slex->offset = 0; + segmenter_init (&slex->segmenter, mode); +} + +/* */ +bool +string_lexer_next (struct string_lexer *slex, struct token *token) +{ + struct segmenter saved_segmenter; + size_t saved_offset = 0; + + struct scanner scanner; + + scanner_init (&scanner, token); + for (;;) + { + const char *s = slex->input + slex->offset; + size_t left = slex->length - slex->offset; + enum segment_type type; + int n; + + n = segmenter_push (&slex->segmenter, s, left, &type); + assert (n >= 0); + + slex->offset += n; + switch (scanner_push (&scanner, type, ss_buffer (s, n), token)) + { + case SCAN_BACK: + slex->segmenter = saved_segmenter; + slex->offset = saved_offset; + /* Fall through. */ + case SCAN_DONE: + return token->type != T_STOP; + + case SCAN_MORE: + break; + + case SCAN_SAVE: + saved_segmenter = slex->segmenter; + saved_offset = slex->offset; + break; + } + } +}