public inbox for archer-commits@sourceware.org
help / color / mirror / Atom feed
* [SCM] archer-cpparser-branch: * cparser.c: Add comments for some functions. Add keywords, handling for "[]", a bunch of minor cleanups. (cp_lexer_consume_token): Return the consumed token instead of the next one. (free_expression_chain): Turn into a cleanup function. (cp_expression_chain): Do not reallocate expout when appending to an existing chain. (cp_required_token_error): New function. (cp_requre_token): New function. (cp_parse_identifier): New function. (cp_parse_global_scope_opt): New function. (cp_parse_unqualified_id): New function. (cp_parse_id_expression): New function. (cp_parse_primary_expression): Handle TTYPE_NAME. (cp_parse_postfix_open_square_expression): New function. (cp_parse_postfix_expression): Add handling for "[" and mention "(", "++", "--", ".", and ".*". (build_binary_opt): Do not free RHS. (cp_parse_binary_expression): Add cleanups for LHS and RHS. Save cleanups onto the expression stack, too. (cp_lex_one_token): Add TTYPE_NAME handling. (free_cp_parser): Make into a cleanup function. (new_parser): Set lexing language. (c_parse): Add cleanup for parser. Free EXPOUT when finished with parsing. (_initialize_cparser): Define global_namespace. [Needed?]
@ 2010-09-02 19:53 kseitz
0 siblings, 0 replies; only message in thread
From: kseitz @ 2010-09-02 19:53 UTC (permalink / raw)
To: archer-commits
The branch, archer-cpparser-branch has been updated
via 7576e402a1a865264bbb355561d916dff595e637 (commit)
from 20221dcf00df6aef51260edb368992039268dbc1 (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email.
- Log -----------------------------------------------------------------
commit 7576e402a1a865264bbb355561d916dff595e637
Author: keiths <keiths@redhat.com>
Date: Thu Sep 2 12:38:27 2010 -0700
* cparser.c: Add comments for some functions.
Add keywords, handling for "[]", a bunch of minor cleanups.
(cp_lexer_consume_token): Return the consumed token instead
of the next one.
(free_expression_chain): Turn into a cleanup function.
(cp_expression_chain): Do not reallocate expout when
appending to an existing chain.
(cp_required_token_error): New function.
(cp_requre_token): New function.
(cp_parse_identifier): New function.
(cp_parse_global_scope_opt): New function.
(cp_parse_unqualified_id): New function.
(cp_parse_id_expression): New function.
(cp_parse_primary_expression): Handle TTYPE_NAME.
(cp_parse_postfix_open_square_expression): New function.
(cp_parse_postfix_expression): Add handling for "[" and
mention "(", "++", "--", ".", and ".*".
(build_binary_opt): Do not free RHS.
(cp_parse_binary_expression): Add cleanups for LHS and RHS.
Save cleanups onto the expression stack, too.
(cp_lex_one_token): Add TTYPE_NAME handling.
(free_cp_parser): Make into a cleanup function.
(new_parser): Set lexing language.
(c_parse): Add cleanup for parser.
Free EXPOUT when finished with parsing.
(_initialize_cparser): Define global_namespace. [Needed?]
-----------------------------------------------------------------------
Summary of changes:
gdb/cparser.c | 451 +++++++++++++++++++++++++++++++++++++++++++++++++++-----
1 files changed, 410 insertions(+), 41 deletions(-)
First 500 lines of diff:
diff --git a/gdb/cparser.c b/gdb/cparser.c
index d4eae48..d272b69 100644
--- a/gdb/cparser.c
+++ b/gdb/cparser.c
@@ -25,6 +25,7 @@
#include "gdb_string.h"
#include "gdbtypes.h"
#include "language.h"
+#include "objfiles.h"
#include "parser-defs.h"
#include "vec.h"
@@ -33,8 +34,6 @@
/* Lexer token table:
OP(name, string description): operator tokens
TK(name, string description): parser tokens
-
- Hmm... Still need reserved keywords...
*/
#define TOKEN_TABLE \
OP(EQ, "=") \
@@ -114,10 +113,52 @@ static const char *token_table_strings[(int) N_TOKEN_TYPES] =
#undef OP
#undef TK
+typedef enum cp_keyword
+ {
+ KEYWORD_UNSIGNED,
+ KEYWORD_TEMPLATE,
+ KEYWORD_VOLATILE,
+ KEYWORD_STRUCT,
+ KEYWORD_SIGNED,
+ KEYWORD_SIZEOF,
+ KEYWORD_DOUBLE,
+ KEYWORD_FALSE,
+ KEYWORD_CLASS,
+ KEYWORD_UNION,
+ KEYWORD_SHORT,
+ KEYWORD_CONST,
+ KEYWORD_ENUM,
+ KEYWORD_LONG,
+ KEYWORD_TRUE,
+ KEYWORD_INT,
+ KEYWORD_NEW,
+ KEYWORD_DELETE,
+ KEYWORD_OPERATOR, /* ?? */
+
+ KEYWORD_AND,
+ KEYWORD_AND_EQ,
+ KEYWORD_BITAND,
+ KEYWORD_BITOR,
+ KEYWORD_COMPL,
+ KEYWORD_NOT,
+ KEYWORD_NOT_EQ,
+ KEYWORD_OR,
+ KEYWORD_OR_EQ,
+ KEYWORD_XOR,
+ KEYWORD_XOR_EQ,
+
+ KEYWORD_CONST_CAST,
+ KEYWORD_DYNAMIC_CAST,
+ KEYWORD_STATIC_CAST,
+ KEYWORD_REINTERPRET_CAST,
+ KEYWORD_MAX /* a marker */
+ } cp_keyword;
+
typedef unsigned char token_value;
typedef struct cp_token
{
token_type type;
+ cp_keyword keyword;
token_value *value; /* Must be free'd (necesary?) */
} cp_token;
@@ -148,12 +189,34 @@ typedef struct
/* The token stream */
cp_token_list *tokens;
cp_token_list *head;
+
+ /* Parsing language */
+ unsigned char language;
} cp_lexer;
+/* An expression "chain" which wraps the parser globals
+ expout, expout_size, and expout_ptr. */
+typedef struct cp_expression
+{
+ /* The actual expression */
+ struct expression *exp;
+
+ /* The allocated number of elements in the expression. */
+ int size;
+
+ /* A pointer to the next free slot in the expression. */
+ int ptr;
+} cp_expression;
+
/* A parser instance */
typedef struct
{
+ /* The lexer */
cp_lexer *lexer;
+
+ cp_expression *scope;
+ cp_expression *qualifying_scope;
+ cp_expression *object_scope;
} cp_parser;
/* Operator precedence levels */
@@ -207,19 +270,8 @@ enum expr_code
BIT_NOT_EXPR
};
-/* An expression "chain" which wraps the parser globals
- expout, expout_size, and expout_ptr. */
-typedef struct _cp_expression
-{
- /* The actual expression */
- struct expression *exp;
-
- /* The allocated number of elements in the expression. */
- int size;
-
- /* A pointer to the next free slot in the expression. */
- int ptr;
-} cp_expression;
+/* An expression representing the global namespace. */
+static cp_expression *global_namespace;
/* A stack is used to deal with operator precedence. This
structure describes a stack entry for this. */
@@ -233,6 +285,9 @@ typedef struct cp_expression_stack_entry
/* The precedence level of this sub-expression. */
enum cp_precedence prec;
+
+ /* A cleanup for the expression being suspended. */
+ struct cleanup *cleanup;
} cp_expression_stack_entry;
/* Type definition for the operator precedence stack. */
@@ -312,6 +367,57 @@ typedef struct
};
} cp_typed_number;
+struct reserved_keywords
+{
+ const char *name;
+ cp_keyword keyword;
+ unsigned char valid_languages;
+};
+
+#define CP_LANGUAGE_C 0x1
+#define CP_LANGUAGE_CPLUS 0x2
+#define CP_LANGUAGE_ALL_C (CP_LANGUAGE_C | CP_LANGUAGE_CPLUS)
+
+static const struct reserved_keywords reserved_keywords[] =
+{
+ {"unsigned", KEYWORD_UNSIGNED, CP_LANGUAGE_ALL_C},
+ {"template", KEYWORD_TEMPLATE, CP_LANGUAGE_CPLUS},
+ {"volatile", KEYWORD_VOLATILE, CP_LANGUAGE_ALL_C},
+ {"struct", KEYWORD_STRUCT, CP_LANGUAGE_ALL_C},
+ {"signed", KEYWORD_SIGNED, CP_LANGUAGE_ALL_C},
+ {"sizeof", KEYWORD_SIZEOF, CP_LANGUAGE_ALL_C},
+ {"double", KEYWORD_DOUBLE, CP_LANGUAGE_ALL_C},
+ {"false", KEYWORD_FALSE, CP_LANGUAGE_CPLUS},
+ {"class", KEYWORD_CLASS, CP_LANGUAGE_CPLUS},
+ {"union", KEYWORD_UNION, CP_LANGUAGE_ALL_C},
+ {"short", KEYWORD_SHORT, CP_LANGUAGE_ALL_C},
+ {"const", KEYWORD_CONST, CP_LANGUAGE_ALL_C},
+ {"enum", KEYWORD_ENUM, CP_LANGUAGE_ALL_C},
+ {"long", KEYWORD_LONG, CP_LANGUAGE_ALL_C},
+ {"true", KEYWORD_TRUE, CP_LANGUAGE_CPLUS},
+ {"int", KEYWORD_INT, CP_LANGUAGE_ALL_C},
+ {"new", KEYWORD_NEW, CP_LANGUAGE_CPLUS},
+ {"delete", KEYWORD_DELETE, CP_LANGUAGE_CPLUS},
+ {"operator", KEYWORD_OPERATOR, CP_LANGUAGE_CPLUS},
+
+ {"and", KEYWORD_AND, CP_LANGUAGE_CPLUS},
+ {"and_eq", KEYWORD_AND_EQ, CP_LANGUAGE_CPLUS},
+ {"bitand", KEYWORD_BITAND, CP_LANGUAGE_CPLUS},
+ {"bitor", KEYWORD_BITOR, CP_LANGUAGE_CPLUS},
+ {"compl", KEYWORD_COMPL, CP_LANGUAGE_CPLUS},
+ {"not", KEYWORD_NOT, CP_LANGUAGE_CPLUS},
+ {"not_eq", KEYWORD_NOT_EQ, CP_LANGUAGE_CPLUS},
+ {"or", KEYWORD_OR, CP_LANGUAGE_CPLUS},
+ {"or_eq", KEYWORD_OR_EQ, CP_LANGUAGE_CPLUS},
+ {"xor", KEYWORD_XOR, CP_LANGUAGE_CPLUS},
+ {"xor_eq", KEYWORD_XOR_EQ, CP_LANGUAGE_CPLUS},
+
+ {"const_cast", KEYWORD_CONST_CAST, CP_LANGUAGE_CPLUS},
+ {"dynamic_cast", KEYWORD_DYNAMIC_CAST, CP_LANGUAGE_CPLUS},
+ {"static_cast", KEYWORD_STATIC_CAST, CP_LANGUAGE_CPLUS},
+ {"reinterpret_cast", KEYWORD_REINTERPRET_CAST, CP_LANGUAGE_CPLUS}
+};
+
/* Returns the current expression chain (from expout). If the argument
is non-NULL, then the current chain is appended to it.
@@ -322,12 +428,16 @@ static cp_expression *cp_cast_expression (cp_parser *);
\f
+/* Allocate a new CP_TOKEN. */
+
static cp_token *
new_token (void)
{
return (cp_token *) xcalloc (1, sizeof (cp_token));
}
+/* Push TOKEN onto LEXER's token stream. */
+
static void
cp_lexer_push_token (cp_lexer *lexer, cp_token *token)
{
@@ -349,6 +459,9 @@ cp_lexer_push_token (cp_lexer *lexer, cp_token *token)
}
}
+/* Returns the next token in the token stream. It is not removed from
+ the stream until cp_lexer_consume_token is called. */
+
static cp_token *
cp_lexer_peek_token (const cp_lexer *lexer)
{
@@ -357,29 +470,36 @@ cp_lexer_peek_token (const cp_lexer *lexer)
return lexer->tokens->token;
}
+/* Advance the token stream past the current token. */
+
static cp_token *
cp_lexer_consume_token (cp_lexer *lexer)
{
- cp_token_list *next = lexer->tokens->next;
- gdb_assert (lexer->tokens != NULL);
- lexer->tokens = next;
- return next->token;
+ cp_token_list *head = lexer->tokens;
+ lexer->tokens = head->next;
+ return head->token;
}
+/* Returns true if the next token in LEXER has the given TYPE. */
+
static int
cp_lexer_next_token_is (cp_lexer *lexer, token_type type)
{
return (cp_lexer_peek_token (lexer)->type == type);
}
+/* Returns true if the next token is the EOF marker token. */
+
static int
cp_is_eof_token (cp_token *token)
{
- return (token->type == TTYPE_EOF);
+ return (token == EOF_token);
}
\f
+/* Append the SRC expression chain to DEST. */
+
static void
cp_expression_append_chain (cp_expression *dest, cp_expression *src)
{
@@ -402,49 +522,63 @@ cp_expression_append_chain (cp_expression *dest, cp_expression *src)
}
/* Frees all memory allocated in the given chain. */
+
static void
-free_expression_chain (cp_expression *chain)
+free_expression_chain (void *chain)
{
- xfree (chain->exp);
- xfree (chain);
+ cp_expression *expr = (cp_expression *) chain;
+ xfree (expr->exp);
+ xfree (expr);
}
+/* Returns an expression chain containing the current contents of EXPOUT.
+ If CHAIN is non-NULL, the EXPOUT is copied into it instead. */
+
static cp_expression *
cp_expression_chain (cp_expression *chain)
{
if (chain == NULL)
{
- /* new chain */
+ /* Create a new chain for the expression in EXPOUT. */
chain = (cp_expression *) xmalloc (sizeof (cp_expression));
chain->size = expout_size;
chain->ptr = expout_ptr;
chain->exp = expout;
chain->exp->nelts = expout_ptr;
+
+ /* Reset globals for next expression */
+ expout_size = 10;
+ expout_ptr = 0;
+ expout = (struct expression *)
+ xmalloc (sizeof (struct expression) + EXP_ELEM_TO_BYTES (expout_size));
+ expout->language_defn = current_language;
+ expout->gdbarch = get_current_arch ();
}
else
{
- /* append chain */
+ /* Append the expression in EXPOUT to CHAIN. */
cp_expression tmp;
tmp.size = expout_size;
tmp.ptr = expout_ptr;
tmp.exp = expout;
tmp.exp->nelts = expout_ptr;
cp_expression_append_chain (chain, &tmp);
- }
- /* Reset globals for next expression */
- expout_size = 10;
- expout_ptr = 0;
- expout = (struct expression *)
- xmalloc (sizeof (struct expression) + EXP_ELEM_TO_BYTES (expout_size));
- expout->language_defn = current_language;
- expout->gdbarch = get_current_arch ();
+ /* Reset globals for next expression. When appending a chain to
+ another chain, the contents of expout are copied into the
+ destination chain, so there is no need to allocate new memory
+ for expout. Simply reset the pointer to zero. */
+ expout_ptr = 0;
+ }
return chain;
}
+/* A helper function to parse numbers from token values. */
+
static void
-parse_number (const cp_parser *parser, token_value *value, cp_typed_number *result)
+parse_number (const cp_parser *parser, token_value *value,
+ cp_typed_number *result)
{
/* FIXME: Shouldn't these be unsigned? We don't deal with negative values
here, and we do kind of silly things like cast to unsigned. */
@@ -729,6 +863,123 @@ parse_number (const cp_parser *parser, token_value *value, cp_typed_number *resu
error (_("Invalid number \"%s\"."), value);
}
+/* Print out an appropriate error message for an expected missing
+ token of type TYPE. */
+
+static void
+cp_required_token_error (cp_parser *parser, token_type type)
+{
+ /* keiths-FIXME: This is not really sufficiently user-friendly. */
+ error (_("syntax error: expected %s"), token_table_strings[(int) type]);
+}
+
+/* If the next token in PARSER is not of type TYPE, throw an error.
+ Otherwise, consume the token and return the next token. */
+
+static cp_token *
+cp_require_token (cp_parser *parser, token_type type)
+{
+ if (cp_lexer_next_token_is (parser->lexer, type))
+ return cp_lexer_consume_token (parser->lexer);
+
+ cp_required_token_error (parser, type);
+ return NULL;
+}
+
+static cp_expression *
+cp_parse_identifier (cp_parser *parser)
+{
+ cp_token *token = cp_require_token (parser, TTYPE_NAME);
+ if (token != NULL)
+ {
+ /* FIXME: Can we use parser->scope? */
+ struct symbol *sym = lookup_symbol (token->value,
+ expression_context_block, VAR_DOMAIN,
+ NULL);
+ if (sym != NULL)
+ {
+ write_exp_elt_opcode (OP_VAR_VALUE);
+ write_exp_elt_block (expression_context_block);
+ write_exp_elt_sym (sym);
+ write_exp_elt_opcode (OP_VAR_VALUE);
+ return cp_expression_chain (NULL);
+ }
+ else
+ {
+ struct minimal_symbol *msym;
+ msym = lookup_minimal_symbol (token->value, NULL, NULL);
+ if (msym != NULL)
+ {
+ write_exp_msymbol (msym);
+ return cp_expression_chain (NULL);
+ }
+ else if (!have_full_symbols () && !have_partial_symbols ())
+ error (_("No symbol table is loaded. Use the \"file\" command."));
+ else
+ error (_("No symbol \"%s\" in current context."), token->value);
+ }
+ }
+
+ return NULL;
+}
+
+static cp_expression *
+cp_parse_global_scope_opt (cp_parser *parser, int current_scope_valid_p)
+{
+ cp_token *token = cp_lexer_peek_token (parser->lexer);
+ if (token->type == TTYPE_SCOPE)
+ {
+ cp_lexer_consume_token (parser->lexer);
+ parser->scope = global_namespace;
+ parser->qualifying_scope = global_namespace;
+ parser->object_scope = NULL;
+
+ return parser->scope;
+ }
+ else if (!current_scope_valid_p)
+ {
+ parser->scope = NULL;
+ parser->qualifying_scope = NULL;
+ parser->object_scope = NULL;
+ }
+
+ return NULL;
+}
+
+static cp_expression *
+cp_parse_unqualified_id (cp_parser *parser, int optional_p)
+{
+ cp_token *token = cp_lexer_peek_token (parser->lexer);
+
+ switch (token->type)
+ {
+ case TTYPE_NAME:
+ return cp_parse_identifier (parser);
+
+ default:
+ if (optional_p)
+ return NULL;
+ error (_("expected unqualified-id"));
+ }
+}
+
+static cp_expression *
+cp_parse_id_expression (cp_parser *parser, int optional_p)
+{
+ int global_scope_p
+ = (cp_parse_global_scope_opt (parser, /*current_scope_valid_p=*/ 0)
+ != NULL);
+
+ if (global_scope_p)
+ {
+ cp_token *token = cp_lexer_peek_token (parser->lexer);
+ if (token->type == TTYPE_NAME)
+ return cp_parse_identifier (parser);
+ }
+
+ return cp_parse_unqualified_id (parser, optional_p);
+}
+
static cp_expression *
cp_parse_primary_expression (cp_parser *parser)
{
@@ -767,11 +1018,14 @@ cp_parse_primary_expression (cp_parser *parser)
}
/* expout now contains the number's expression chain. So
- we need to save this and reset expout. */
+ we need to save this and reset expout. */
return cp_expression_chain (NULL);
}
break;
+ case TTYPE_NAME:
+ return cp_parse_id_expression (parser, /*optional_p=*/ 0);
+
default:
error (_("expected primary expression"));
}
@@ -781,17 +1035,57 @@ cp_parse_primary_expression (cp_parser *parser)
}
static cp_expression *
+cp_parse_postfix_open_square_expression (cp_parser *parser, cp_expression *expr)
+{
+ cp_lexer_consume_token (parser->lexer);
+ cp_expression_append_chain (expr, cp_parse_expression (parser));
+ cp_require_token (parser, TTYPE_CLOSE_SQUARE);
+ write_exp_elt_opcode (BINOP_SUBSCRIPT);
+ return cp_expression_chain (expr);
+}
+
+static cp_expression *
hooks/post-receive
--
Repository for Project Archer.
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2010-09-02 19:53 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-09-02 19:53 [SCM] archer-cpparser-branch: * cparser.c: Add comments for some functions. Add keywords, handling for "[]", a bunch of minor cleanups. (cp_lexer_consume_token): Return the consumed token instead of the next one. (free_expression_chain): Turn into a cleanup function. (cp_expression_chain): Do not reallocate expout when appending to an existing chain. (cp_required_token_error): New function. (cp_requre_token): New function. (cp_parse_identifier): New function. (cp_parse_global_scope_opt): New function. (cp_parse_unqualified_id): New function. (cp_parse_id_expression): New function. (cp_parse_primary_expression): Handle TTYPE_NAME. (cp_parse_postfix_open_square_expression): New function. (cp_parse_postfix_expression): Add handling for "[" and mention "(", "++", "--", ".", and ".*". (build_binary_opt): Do not free RHS. (cp_parse_binary_expression): Add cleanups for LHS and RHS. Save cleanups onto the expression stack, too. (cp_lex_one_token): Add TTYPE_NAME handling. (free_cp_parser): Make into a cleanup function. (new_parser): Set lexing language. (c_parse): Add cleanup for parser. Free EXPOUT when finished with parsing. (_initialize_cparser): Define global_namespace. [Needed?] kseitz
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).