X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Flanguage%2Flexer%2Fscan.c;h=573a00df9d327f42445cda0c7ccb6492bc093f95;hb=b92e8417c7b44c8ce39829dca4eb8ab26f8b5494;hp=caf294a9d123b4aa28192775ba25aa5d53cb9e7e;hpb=fe8dc2171009e90d2335f159d05f7e6660e24780;p=pspp diff --git a/src/language/lexer/scan.c b/src/language/lexer/scan.c index caf294a9d1..573a00df9d 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); @@ -409,7 +410,7 @@ scan_type_to_string (enum scan_type type) #undef SCAN_TYPE default: - return token_type_to_name (type); + return token_type_to_name ((enum token_type) type); } } @@ -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,59 @@ scanner_push (struct scanner *scanner, enum segment_type type, NOT_REACHED (); } + +/* Initializes SLEX for parsing INPUT, which is LENGTH bytes long, 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, size_t length, + enum segmenter_mode mode) +{ + slex->input = input; + slex->length = length; + 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, true, &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; + } + } +}