return;
}
}
+
+/* Advances LEXER by N tokens. */
+void
+lex_get_n (struct lexer *lexer, size_t n)
+{
+ while (n-- > 0)
+ lex_get (lexer);
+}
\f
/* Issuing errors. */
ds_put_cstr (&s, ": ");
ds_put_vformat (&s, format, args);
}
- ds_put_byte (&s, '.');
+ if (ds_last (&s) != '.')
+ ds_put_byte (&s, '.');
msg (SE, "%s", ds_cstr (&s));
ds_destroy (&s);
}
bool
lex_force_int_range (struct lexer *lexer, const char *name, long min, long max)
{
+ bool is_number = lex_is_number (lexer);
bool is_integer = lex_is_integer (lexer);
- bool too_small = is_integer && lex_integer (lexer) < min;
- bool too_big = is_integer && lex_integer (lexer) > max;
+ bool too_small = (is_integer ? lex_integer (lexer) < min
+ : is_number ? lex_number (lexer) < min
+ : false);
+ bool too_big = (is_integer ? lex_integer (lexer) > max
+ : is_number ? lex_number (lexer) > max
+ : false);
if (is_integer && !too_small && !too_big)
return true;
else
lex_error (lexer, _("Expected positive integer."));
}
+ else
+ {
+ if (name)
+ lex_error (lexer, _("Expected integer %ld or greater for %s."),
+ min, name);
+ else
+ lex_error (lexer, _("Expected integer %ld or greater."), min);
+ }
}
else if (report_upper_bound)
{
}
}
-/* If LEXER is positioned at the sequence of tokens that may be parsed from S,
- skips it and returns true. Otherwise, returns false.
-
- S may consist of an arbitrary sequence of tokens, e.g. "KRUSKAL-WALLIS",
- "2SLS", or "END INPUT PROGRAM". Identifiers may be abbreviated to their
- first three letters. */
-bool
-lex_match_phrase (struct lexer *lexer, const char *s)
+static size_t
+lex_at_phrase__ (struct lexer *lexer, const char *s)
{
struct string_lexer slex;
struct token token;
- int i;
- i = 0;
+ size_t i = 0;
string_lexer_init (&slex, s, strlen (s), SEG_MODE_INTERACTIVE, true);
while (string_lexer_next (&slex, &token))
{
bool match = lex_tokens_match (lex_next (lexer, i++), &token);
token_uninit (&token);
if (!match)
- return false;
+ return 0;
}
+ return i;
+}
- while (i-- > 0)
- lex_get (lexer);
- return true;
+/* If LEXER is positioned at the sequence of tokens that may be parsed from S,
+ returns true. Otherwise, returns false.
+
+ S may consist of an arbitrary sequence of tokens, e.g. "KRUSKAL-WALLIS",
+ "2SLS", or "END INPUT PROGRAM". Identifiers may be abbreviated to their
+ first three letters. */
+bool
+lex_at_phrase (struct lexer *lexer, const char *s)
+{
+ return lex_at_phrase__ (lexer, s) > 0;
+}
+
+/* If LEXER is positioned at the sequence of tokens that may be parsed from S,
+ skips it and returns true. Otherwise, returns false.
+
+ S may consist of an arbitrary sequence of tokens, e.g. "KRUSKAL-WALLIS",
+ "2SLS", or "END INPUT PROGRAM". Identifiers may be abbreviated to their
+ first three letters. */
+bool
+lex_match_phrase (struct lexer *lexer, const char *s)
+{
+ size_t n = lex_at_phrase__ (lexer, s);
+ if (n > 0)
+ lex_get_n (lexer, n);
+ return n > 0;
}
static int
.macro_rep = macro ? first->macro_rep : NULL,
.ofs = macro ? first->ofs : 0,
.len = macro ? (last->ofs - first->ofs) + last->len : 0,
- .ref_cnt = first->ref_cnt,
+ .ref_cnt = macro ? first->ref_cnt : NULL,
};
if (t->ref_cnt)
++*t->ref_cnt;