aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoger Sayle <roger@eyesopen.com>2007-09-02 17:44:37 +0000
committerRoger Sayle <sayle@gcc.gnu.org>2007-09-02 17:44:37 +0000
commitf2449db41c586a49bce8e512cdeb9f4e1330d998 (patch)
tree55128b82c7e60dce137d947dba21f608c81bbff0
parentb35c5f019f9dcbee023c54f25be644d90a5a76ac (diff)
downloadgcc-f2449db41c586a49bce8e512cdeb9f4e1330d998.zip
gcc-f2449db41c586a49bce8e512cdeb9f4e1330d998.tar.gz
gcc-f2449db41c586a49bce8e512cdeb9f4e1330d998.tar.bz2
decl.c (match_string_p): New helper function to explicitly match a string of characters.
* decl.c (match_string_p): New helper function to explicitly match a string of characters. (match_attr_spec): Remove no longer needed DECL_COLON from decl_types. Delete decls array and peek_char. Rewrite decl attribute parser to avoid calling gfc_match_strings. * match.c (gfc_match_strings): Delete unused function. * match.h (gfc_match_strings): Delete prototype. From-SVN: r128028
-rw-r--r--gcc/fortran/ChangeLog10
-rw-r--r--gcc/fortran/decl.c214
-rw-r--r--gcc/fortran/match.c84
-rw-r--r--gcc/fortran/match.h1
4 files changed, 180 insertions, 129 deletions
diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog
index d6c5e09..b0cb8c9 100644
--- a/gcc/fortran/ChangeLog
+++ b/gcc/fortran/ChangeLog
@@ -1,3 +1,13 @@
+2007-09-02 Roger Sayle <roger@eyesopen.com>
+
+ * decl.c (match_string_p): New helper function to explicitly match
+ a string of characters.
+ (match_attr_spec): Remove no longer needed DECL_COLON from decl_types.
+ Delete decls array and peek_char. Rewrite decl attribute parser to
+ avoid calling gfc_match_strings.
+ * match.c (gfc_match_strings): Delete unused function.
+ * match.h (gfc_match_strings): Delete prototype.
+
2007-09-02 Tobias Schlüuter <tobi@gcc.gnu.org>
* dump-parse-tree.c (show_char_const): New function.
diff --git a/gcc/fortran/decl.c b/gcc/fortran/decl.c
index 8b35662..b1f4f35 100644
--- a/gcc/fortran/decl.c
+++ b/gcc/fortran/decl.c
@@ -2468,6 +2468,21 @@ syntax:
}
+/* A minimal implementation of gfc_match without whitespace, escape
+ characters or variable arguments. Returns true if the next
+ characters match the TARGET template exactly. */
+
+static bool
+match_string_p (const char *target)
+{
+ const char *p;
+
+ for (p = target; *p; p++)
+ if (gfc_next_char () != *p)
+ return false;
+ return true;
+}
+
/* Matches an attribute specification including array specs. If
successful, leaves the variables current_attr and current_as
holding the specification. Also sets the colon_seen variable for
@@ -2488,7 +2503,7 @@ match_attr_spec (void)
DECL_IN, DECL_OUT, DECL_INOUT, DECL_INTRINSIC, DECL_OPTIONAL,
DECL_PARAMETER, DECL_POINTER, DECL_PROTECTED, DECL_PRIVATE,
DECL_PUBLIC, DECL_SAVE, DECL_TARGET, DECL_VALUE, DECL_VOLATILE,
- DECL_IS_BIND_C, DECL_COLON, DECL_NONE,
+ DECL_IS_BIND_C, DECL_NONE,
GFC_DECL_END /* Sentinel */
}
decl_types;
@@ -2496,35 +2511,12 @@ match_attr_spec (void)
/* GFC_DECL_END is the sentinel, index starts at 0. */
#define NUM_DECL GFC_DECL_END
- static mstring decls[] = {
- minit (", allocatable", DECL_ALLOCATABLE),
- minit (", dimension", DECL_DIMENSION),
- minit (", external", DECL_EXTERNAL),
- minit (", intent ( in )", DECL_IN),
- minit (", intent ( out )", DECL_OUT),
- minit (", intent ( in out )", DECL_INOUT),
- minit (", intrinsic", DECL_INTRINSIC),
- minit (", optional", DECL_OPTIONAL),
- minit (", parameter", DECL_PARAMETER),
- minit (", pointer", DECL_POINTER),
- minit (", protected", DECL_PROTECTED),
- minit (", private", DECL_PRIVATE),
- minit (", public", DECL_PUBLIC),
- minit (", save", DECL_SAVE),
- minit (", target", DECL_TARGET),
- minit (", value", DECL_VALUE),
- minit (", volatile", DECL_VOLATILE),
- minit ("::", DECL_COLON),
- minit (NULL, DECL_NONE)
- };
-
locus start, seen_at[NUM_DECL];
int seen[NUM_DECL];
decl_types d;
const char *attr;
match m;
try t;
- char peek_char;
gfc_clear_attr (&current_attr);
start = gfc_current_locus;
@@ -2538,29 +2530,171 @@ match_attr_spec (void)
for (;;)
{
- d = (decl_types) gfc_match_strings (decls);
+ int ch;
- if (d == DECL_NONE)
+ d = DECL_NONE;
+ gfc_gobble_whitespace ();
+
+ ch = gfc_next_char ();
+ if (ch == ':')
+ {
+ /* This is the successful exit condition for the loop. */
+ if (gfc_next_char () == ':')
+ break;
+ }
+ else if (ch == ',')
{
- /* See if we can find the bind(c) since all else failed.
- We need to skip over any whitespace and stop on the ','. */
gfc_gobble_whitespace ();
- peek_char = gfc_peek_char ();
- if (peek_char == ',')
+ switch (gfc_peek_char ())
{
- /* Chomp the comma. */
- peek_char = gfc_next_char ();
+ case 'a':
+ if (match_string_p ("allocatable"))
+ d = DECL_ALLOCATABLE;
+ break;
+
+ case 'b':
/* Try and match the bind(c). */
m = gfc_match_bind_c (NULL);
if (m == MATCH_YES)
d = DECL_IS_BIND_C;
else if (m == MATCH_ERROR)
goto cleanup;
+ break;
+
+ case 'd':
+ if (match_string_p ("dimension"))
+ d = DECL_DIMENSION;
+ break;
+
+ case 'e':
+ if (match_string_p ("external"))
+ d = DECL_EXTERNAL;
+ break;
+
+ case 'i':
+ if (match_string_p ("int"))
+ {
+ ch = gfc_next_char ();
+ if (ch == 'e')
+ {
+ if (match_string_p ("nt"))
+ {
+ /* Matched "intent". */
+ /* TODO: Call match_intent_spec from here. */
+ if (gfc_match (" ( in out )") == MATCH_YES)
+ d = DECL_INOUT;
+ else if (gfc_match (" ( in )") == MATCH_YES)
+ d = DECL_IN;
+ else if (gfc_match (" ( out )") == MATCH_YES)
+ d = DECL_OUT;
+ }
+ }
+ else if (ch == 'r')
+ {
+ if (match_string_p ("insic"))
+ {
+ /* Matched "intrinsic". */
+ d = DECL_INTRINSIC;
+ }
+ }
+ }
+ break;
+
+ case 'o':
+ if (match_string_p ("optional"))
+ d = DECL_OPTIONAL;
+ break;
+
+ case 'p':
+ gfc_next_char ();
+ switch (gfc_next_char ())
+ {
+ case 'a':
+ if (match_string_p ("rameter"))
+ {
+ /* Matched "parameter". */
+ d = DECL_PARAMETER;
+ }
+ break;
+
+ case 'o':
+ if (match_string_p ("inter"))
+ {
+ /* Matched "pointer". */
+ d = DECL_POINTER;
+ }
+ break;
+
+ case 'r':
+ ch = gfc_next_char ();
+ if (ch == 'i')
+ {
+ if (match_string_p ("vate"))
+ {
+ /* Matched "private". */
+ d = DECL_PRIVATE;
+ }
+ }
+ else if (ch == 'o')
+ {
+ if (match_string_p ("tected"))
+ {
+ /* Matched "protected". */
+ d = DECL_PROTECTED;
+ }
+ }
+ break;
+
+ case 'u':
+ if (match_string_p ("blic"))
+ {
+ /* Matched "public". */
+ d = DECL_PUBLIC;
+ }
+ break;
+ }
+ break;
+
+ case 's':
+ if (match_string_p ("save"))
+ d = DECL_SAVE;
+ break;
+
+ case 't':
+ if (match_string_p ("target"))
+ d = DECL_TARGET;
+ break;
+
+ case 'v':
+ gfc_next_char ();
+ ch = gfc_next_char ();
+ if (ch == 'a')
+ {
+ if (match_string_p ("lue"))
+ {
+ /* Matched "value". */
+ d = DECL_VALUE;
+ }
+ }
+ else if (ch == 'o')
+ {
+ if (match_string_p ("latile"))
+ {
+ /* Matched "volatile". */
+ d = DECL_VOLATILE;
+ }
+ }
+ break;
}
}
- if (d == DECL_NONE || d == DECL_COLON)
- break;
+ /* No double colon and no recognizable decl_type, so assume that
+ we've been looking at something else the whole time. */
+ if (d == DECL_NONE)
+ {
+ m = MATCH_NO;
+ goto cleanup;
+ }
seen[d]++;
seen_at[d] = gfc_current_locus;
@@ -2580,14 +2714,6 @@ match_attr_spec (void)
}
}
- /* No double colon, so assume that we've been looking at something
- else the whole time. */
- if (d == DECL_NONE)
- {
- m = MATCH_NO;
- goto cleanup;
- }
-
/* Since we've seen a double colon, we have to be looking at an
attr-spec. This means that we can now issue errors. */
for (d = GFC_DECL_BEGIN; d != GFC_DECL_END; d++)
@@ -2667,8 +2793,8 @@ match_attr_spec (void)
if (gfc_current_state () == COMP_DERIVED
&& d != DECL_DIMENSION && d != DECL_POINTER
- && d != DECL_COLON && d != DECL_PRIVATE
- && d != DECL_PUBLIC && d != DECL_NONE)
+ && d != DECL_PRIVATE && d != DECL_PUBLIC
+ && d != DECL_NONE)
{
if (d == DECL_ALLOCATABLE)
{
diff --git a/gcc/fortran/match.c b/gcc/fortran/match.c
index dcf6ad1..83b8873 100644
--- a/gcc/fortran/match.c
+++ b/gcc/fortran/match.c
@@ -417,90 +417,6 @@ gfc_match_label (void)
}
-/* Try and match the input against an array of possibilities. If one
- potential matching string is a substring of another, the longest
- match takes precedence. Spaces in the target strings are optional
- spaces that do not necessarily have to be found in the input
- stream. In fixed mode, spaces never appear. If whitespace is
- matched, it matches unlimited whitespace in the input. For this
- reason, the 'mp' member of the mstring structure is used to track
- the progress of each potential match.
-
- If there is no match we return the tag associated with the
- terminating NULL mstring structure and leave the locus pointer
- where it started. If there is a match we return the tag member of
- the matched mstring and leave the locus pointer after the matched
- character.
-
- A '%' character is a mandatory space. */
-
-int
-gfc_match_strings (mstring *a)
-{
- mstring *p, *best_match;
- int no_match, c, possibles;
- locus match_loc;
-
- possibles = 0;
-
- for (p = a; p->string != NULL; p++)
- {
- p->mp = p->string;
- possibles++;
- }
-
- no_match = p->tag;
-
- best_match = NULL;
- match_loc = gfc_current_locus;
-
- gfc_gobble_whitespace ();
-
- while (possibles > 0)
- {
- c = gfc_next_char ();
-
- /* Apply the next character to the current possibilities. */
- for (p = a; p->string != NULL; p++)
- {
- if (p->mp == NULL)
- continue;
-
- if (*p->mp == ' ')
- {
- /* Space matches 1+ whitespace(s). */
- if ((gfc_current_form == FORM_FREE) && gfc_is_whitespace (c))
- continue;
-
- p->mp++;
- }
-
- if (*p->mp != c)
- {
- /* Match failed. */
- p->mp = NULL;
- possibles--;
- continue;
- }
-
- p->mp++;
- if (*p->mp == '\0')
- {
- /* Found a match. */
- match_loc = gfc_current_locus;
- best_match = p;
- possibles--;
- p->mp = NULL;
- }
- }
- }
-
- gfc_current_locus = match_loc;
-
- return (best_match == NULL) ? no_match : best_match->tag;
-}
-
-
/* See if the current input looks like a name of some sort. Modifies
the passed buffer which must be GFC_MAX_SYMBOL_LEN+1 bytes long.
Note that options.c restricts max_identifier_length to not more
diff --git a/gcc/fortran/match.h b/gcc/fortran/match.h
index abd6ab1..0909617 100644
--- a/gcc/fortran/match.h
+++ b/gcc/fortran/match.h
@@ -46,7 +46,6 @@ match gfc_match_st_label (gfc_st_label **);
match gfc_match_label (void);
match gfc_match_small_int (int *);
match gfc_match_small_int_expr (int *, gfc_expr **);
-int gfc_match_strings (mstring *);
match gfc_match_name (char *);
match gfc_match_name_C (char *buffer);
match gfc_match_symbol (gfc_symbol **, int);