summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorJose Antonio Ortega Ruiz <jao@gnu.org>2003-05-27 22:50:50 +0000
committerJose Antonio Ortega Ruiz <jao@gnu.org>2003-05-27 22:50:50 +0000
commitde56533ebd3a6022e4ad0b15978f676d683f5eef (patch)
tree8fbf77a918180d8f45b4f10cdba7cbb9a8ba46e4
parent9f711b0c104b9aa427078327067a279465f7663c (diff)
downloadmdk-de56533ebd3a6022e4ad0b15978f676d683f5eef.tar.gz
mdk-de56533ebd3a6022e4ad0b15978f676d683f5eef.tar.bz2
new error message for missing ALF operand quotes (bug #3750 fixed)
-rw-r--r--mixlib/mix_parser.c87
-rw-r--r--mixlib/mix_parser.h19
-rw-r--r--mixlib/mix_scanner.l104
3 files changed, 110 insertions, 100 deletions
diff --git a/mixlib/mix_parser.c b/mixlib/mix_parser.c
index 2087f15..e2c7e3f 100644
--- a/mixlib/mix_parser.c
+++ b/mixlib/mix_parser.c
@@ -1,23 +1,23 @@
/* -*-c-*- -------------- mix_parser.c :
- * Implementation of the functions declared in mix_parser.h and
+ * Implementation of the functions declared in mix_parser.h and
* xmix_parser.h
* ------------------------------------------------------------------
- * Copyright (C) 2000, 2001 Free Software Foundation, Inc.
- *
+ * Copyright (C) 2000, 2001, 2003 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
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
- *
+ *
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
- *
+ *
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
+ *
*/
#include <string.h>
@@ -57,7 +57,8 @@ static const gchar * const ERR_MESSAGE_[] = {
N_("symbol is an instruction name"),
N_("failed write access to code file"),
N_("operand of ALF pseudo instruction has less than 5 chars"),
- N_("operand of ALF pseudo instruction has more than 5 chars")
+ N_("operand of ALF pseudo instruction has more than 5 chars"),
+ N_("operand of ALF pseudo instruction must be quoted")
};
static const guint NO_OF_MESSAGES_ = sizeof(ERR_MESSAGE_)/sizeof (gchar*);
@@ -68,13 +69,13 @@ mix_parser_err_string (mix_parser_err_t error)
return (error < NO_OF_MESSAGES_) ? _(ERR_MESSAGE_[error]) : NULL;
}
-guint
+guint
mix_parser_err_count (const mix_parser_t *parser)
{
return (parser) ? parser->err_count : 0;
}
-guint
+guint
mix_parser_warning_count (const mix_parser_t *parser)
{
return (parser) ? parser->warn_count : 0;
@@ -104,7 +105,7 @@ compare_shorts_ (gconstpointer s1, gconstpointer s2)
return mix_short_magnitude (a) - mix_short_magnitude (b);
else if ( mix_short_magnitude (a) == 0 && mix_short_magnitude (b) == 0 )
return 0;
- else if ( mix_short_is_positive (a) )
+ else if ( mix_short_is_positive (a) )
return 1;
return -1;
}
@@ -113,9 +114,9 @@ mix_parser_t *
mix_parser_new (const gchar *in_file)
{
mix_parser_t *result;
- mix_file_t *f = mix_file_new_with_def_ext (in_file, mix_io_READ,
+ mix_file_t *f = mix_file_new_with_def_ext (in_file, mix_io_READ,
MIX_SRC_DEFEXT);
-
+
if ( f == NULL ) return NULL;
result = g_new (mix_parser_t, 1);
result->symbol_table = mix_symbol_table_new ();
@@ -193,16 +194,16 @@ update_future_refs_value_ (mix_parser_t *parser, const gchar *name,
{
GSList *list = NULL;
gpointer key;
-
+
g_assert (parser != NULL && name != NULL);
- if ( g_hash_table_lookup_extended (parser->future_refs, name, &key,
+ if ( g_hash_table_lookup_extended (parser->future_refs, name, &key,
(gpointer *)&list) )
{
GSList *tmp = list;
ins_node_ *node;
while ( tmp != NULL )
{
- node =
+ node =
(ins_node_ *)g_tree_lookup (parser->ins_table,tmp->data);
g_assert (node);
if (mix_get_ins_address (node->ins) == 1) {
@@ -230,7 +231,7 @@ update_ls_ (gpointer symbol, gpointer value, gpointer parser)
mix_ins_t ins;
mix_word_t w = (mix_word_t) GPOINTER_TO_UINT (value);
mix_parser_t *par = (mix_parser_t *) parser;
-
+
mix_word_to_ins_uncheck (w, ins);
mix_parser_add_ins (par, &ins, 0);
update_future_refs_ (par, (const gchar *)symbol);
@@ -245,16 +246,16 @@ mix_parser_compile (mix_parser_t *parser)
g_return_val_if_fail (parser->symbol_table != NULL, MIX_PERR_INTERNAL);
g_return_val_if_fail (parser->future_refs != NULL, MIX_PERR_INTERNAL);
g_return_val_if_fail (parser->ins_table != NULL, MIX_PERR_INTERNAL);
-
+
parser->status = mix_flex_scan (parser);
if ( parser->status == MIX_PERR_OK )
{
- mix_symbol_table_foreach (parser->ls_table, update_ls_,
+ mix_symbol_table_foreach (parser->ls_table, update_ls_,
(gpointer)parser);
- g_hash_table_foreach_remove (parser->future_refs,
+ g_hash_table_foreach_remove (parser->future_refs,
undef_warning_, (gpointer)parser);
}
-
+
return parser->status;
}
@@ -275,7 +276,7 @@ write_code_ (gpointer address, gpointer ins_node, gpointer context)
desc.address = (mix_address_t)GPOINTER_TO_UINT (address);
if ( mix_code_file_write_ins (cntx->file, &desc) )
return FALSE;
- else
+ else
{
cntx->parser->status = MIX_PERR_NOWRITE;
return TRUE;
@@ -283,14 +284,14 @@ write_code_ (gpointer address, gpointer ins_node, gpointer context)
}
mix_parser_err_t
-mix_parser_write_code (mix_parser_t *parser, const gchar *code_file,
+mix_parser_write_code (mix_parser_t *parser, const gchar *code_file,
gboolean debug)
{
struct write_code_context_ context;
const gchar *cfname = (code_file) ?
code_file : mix_file_base_name (parser->in_file);
gchar *source_path;
-
+
g_return_val_if_fail (parser != NULL, MIX_PERR_INTERNAL);
if (parser->status != MIX_PERR_OK ) return parser->status;
context.parser = parser;
@@ -303,13 +304,13 @@ mix_parser_write_code (mix_parser_t *parser, const gchar *code_file,
}
else
source_path = g_strdup (mix_file_base_name (parser->in_file));
-
+
context.file = mix_code_file_new_write (cfname, parser->start, source_path,
debug, parser->symbol_table);
g_free (source_path);
if (context.file == NULL) return MIX_PERR_NOOUT;
- g_tree_traverse (parser->ins_table, write_code_,
+ g_tree_traverse (parser->ins_table, write_code_,
G_IN_ORDER, (gpointer)&context);
mix_code_file_delete (context.file);
return parser->status;
@@ -344,21 +345,21 @@ mix_parser_write_listing (mix_parser_t *parser, const gchar *list_file)
FILE *file;
mix_file_t *mfile;
const gchar *name;
-
+
g_return_val_if_fail (parser != NULL, MIX_PERR_INTERNAL);
if (parser->status != MIX_PERR_OK ) return parser->status;
name = (list_file) ? list_file : mix_file_base_name (parser->in_file);
mfile = mix_file_new_with_def_ext (name, mix_io_WRITE, MIX_LIST_DEFEXT);
if ( mfile == NULL ) return MIX_PERR_NOOUT;
file = mix_file_to_FILE (mfile);
- fprintf (file, _("*** %s%s: compilation summary ***\n\n"),
- mix_file_base_name (parser->in_file),
+ fprintf (file, _("*** %s%s: compilation summary ***\n\n"),
+ mix_file_base_name (parser->in_file),
mix_file_extension (parser->in_file));
fputs ( _("*** Address / Compiled word / Symbolic rep / Source file line\n"),
file);
- g_tree_traverse (parser->ins_table, write_listing_,
+ g_tree_traverse (parser->ins_table, write_listing_,
G_IN_ORDER, (gpointer)file);
- fprintf (file, _("\n*** Start address: %d\n"),
+ fprintf (file, _("\n*** Start address: %d\n"),
mix_short_magnitude (parser->start));
fprintf (file, _("\n*** Symbol table\n"));
mix_symbol_table_print (parser->symbol_table, MIX_SYM_ROWS, file, TRUE);
@@ -372,7 +373,7 @@ static gint
load_vm_ (gpointer address, gpointer ins, gpointer vm)
{
mix_vm_set_addr_contents ((mix_vm_t*)vm,
- (mix_address_t)GPOINTER_TO_UINT (address),
+ (mix_address_t)GPOINTER_TO_UINT (address),
((ins_node_ *)ins)->ins);
return FALSE;
}
@@ -410,12 +411,12 @@ mix_parser_err_t
mix_parser_define_symbol_value (mix_parser_t *parser, const gchar *name,
mix_word_t value)
{
- g_assert (parser != NULL && name != NULL);
-
+ g_assert (parser != NULL && name != NULL);
+
switch (mix_symbol_table_add (parser->symbol_table, name, value))
{
- case MIX_SYM_OK:
- if ( parser->status == MIX_PERR_NOCOMP )
+ case MIX_SYM_OK:
+ if ( parser->status == MIX_PERR_NOCOMP )
update_future_refs_value_ (parser, name, value);
return MIX_PERR_OK;
case MIX_SYM_LONG: return MIX_PERR_LONG_SYMBOL;
@@ -449,10 +450,10 @@ mix_parser_manage_local_symbol (mix_parser_t *parser, const gchar *name,
{
gchar ref[3];
ref[2] = 0;
-
+
g_assert (parser != NULL && name != NULL);
g_assert (strlen(name) == 2);
-
+
switch (name[1])
{
case 'f': case 'F':
@@ -461,10 +462,10 @@ mix_parser_manage_local_symbol (mix_parser_t *parser, const gchar *name,
case 'h': case 'H':
ref[0] = name[0];
ref[1] = 'F';
- if ( parser->status == MIX_PERR_NOCOMP )
+ if ( parser->status == MIX_PERR_NOCOMP )
update_future_refs_value_ (parser, ref, value);
ref[1] = 'B';
- mix_symbol_table_insert (parser->symbol_table, ref,
+ mix_symbol_table_insert (parser->symbol_table, ref,
mix_short_to_word_fast (value));
break;
default:
@@ -484,7 +485,7 @@ mix_parser_define_ls (mix_parser_t *parser, mix_word_t value)
/* Compilation */
void
-mix_parser_add_ins (mix_parser_t *parser, const mix_ins_t *new_ins,
+mix_parser_add_ins (mix_parser_t *parser, const mix_ins_t *new_ins,
guint lineno)
{
g_assert (parser != NULL && new_ins != NULL);
@@ -506,7 +507,7 @@ mix_parser_add_raw (mix_parser_t *parser, mix_word_t word, guint lineno)
}
/* Error handling */
-void
+void
mix_parser_log_error (mix_parser_t *parser, mix_parser_err_t error,
gint lineno, const gchar *comment, gboolean warn)
{
@@ -519,9 +520,9 @@ mix_parser_log_error (mix_parser_t *parser, mix_parser_err_t error,
parser->err_line = lineno;
parser->status = error;
}
-
+
fprintf (stderr, "%s%s:%d: %s: %s",
- mix_file_base_name (parser->in_file),
+ mix_file_base_name (parser->in_file),
mix_file_extension (parser->in_file),
lineno, warn ? _("warning"):_("error"), _(ERR_MESSAGE_[error]));
diff --git a/mixlib/mix_parser.h b/mixlib/mix_parser.h
index f371430..a18442c 100644
--- a/mixlib/mix_parser.h
+++ b/mixlib/mix_parser.h
@@ -2,22 +2,22 @@
* Declarations for mix_parser_t, which compiles a source file into
* a mix code file.
* ------------------------------------------------------------------
- * Copyright (C) 2000 Free Software Foundation, Inc.
- *
+ * Copyright (C) 2000, 2003 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
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
- *
+ *
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
- *
+ *
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
+ *
*/
@@ -46,7 +46,7 @@ mix_parser_src_file_extension(const mix_parser_t *parser);
/* Compile a mix source file */
/* compilation errors */
-typedef enum {
+typedef enum {
MIX_PERR_OK, /* no error */
MIX_PERR_NOCOMP, /* file not yet compiled */
MIX_PERR_INTERNAL, /* internal error */
@@ -70,7 +70,8 @@ typedef enum {
MIX_PERR_SYM_INS, /* symbol has the same name as instruction */
MIX_PERR_NOWRITE, /* failed code write */
MIX_PERR_SHORT_ALF, /* short ALF operand */
- MIX_PERR_LONG_ALF /* too long ALF operand */
+ MIX_PERR_LONG_ALF, /* too long ALF operand */
+ MIX_PERR_UNQUOTED_ALF /* unquoted ALF operand */
} mix_parser_err_t;
extern const gchar *
@@ -79,10 +80,10 @@ mix_parser_err_string(mix_parser_err_t error);
extern mix_parser_err_t
mix_parser_compile(mix_parser_t *parser);
-extern guint
+extern guint
mix_parser_warning_count(const mix_parser_t *parser);
-extern guint
+extern guint
mix_parser_err_count(const mix_parser_t *parser);
/* Write the compilation result to a code file with the given name.
diff --git a/mixlib/mix_scanner.l b/mixlib/mix_scanner.l
index 8c6a186..6e4cb71 100644
--- a/mixlib/mix_scanner.l
+++ b/mixlib/mix_scanner.l
@@ -1,25 +1,26 @@
/* -*-c-*- -------------- mix_scanner.l :
* Lexical scanner used by mix_parser_t
* ------------------------------------------------------------------
- * Copyright (C) 2000 Free Software Foundation, Inc.
- *
+ * Copyright (C) 2000, 2003 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
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
- *
+ *
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
- *
+ *
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
+ *
*/
%{
+#include <ctype.h>
#include <string.h>
#include "mix.h"
@@ -104,13 +105,25 @@
BEGIN (INITIAL); \
} while (FALSE)
-
+
static mix_word_t
- eval_binop_ (const gchar *op, mix_word_t x, mix_word_t y);
-
+eval_binop_ (const gchar *op, mix_word_t x, mix_word_t y);
+
+static void yyunput(int, char*);
+
static void
- unput_word_ (mix_word_t word);
-
+unput_word_ (mix_word_t word)
+ {
+ gchar *value;
+ gint k;
+ value = g_strdup_printf ("%s%ld",
+ mix_word_is_negative (word)? "-":"+",
+ mix_word_magnitude (word));
+ for (k = strlen (value) - 1; k >= 0; --k)
+ unput (value[k]);
+ g_free (value);
+ }
+
%}
%option nomain
@@ -148,7 +161,7 @@ atexpr {digit}+|{symbol}|\*
expr [+-]?{atexpr}({binop}{1}{atexpr})*
fpart \({expr}\)
wexpr {expr}({fpart})?(,{expr}({fpart})?)*
-
+
%%
@@ -161,14 +174,14 @@ wexpr {expr}({fpart})?(,{expr}({fpart})?)*
gchar *symbol = NULL, *lsymbol = NULL;
mix_address_t loc = MIX_SHORT_ZERO;
guint lineno = 1;
- mix_ins_fill_from_id (ins, mix_NOP);
- ins.address = 0;
- ins.index = 0;
+ mix_ins_fill_from_id (ins, mix_NOP);
+ ins.address = 0;
+ ins.index = 0;
parser->err_line = 0;
yyin = mix_file_to_FILE (parser->in_file);
-
+
%}
-
+
<*><<EOF>> {
mix_parser_log_error (parser, MIX_PERR_UNEX_EOF, lineno, NULL, FALSE);
@@ -182,11 +195,11 @@ wexpr {expr}({fpart})?(,{expr}({fpart})?)*
yyless (0);
BEGIN (LOC);
}
- \n {
+ \n {
++lineno;
- if ( end ) return parser->status;
+ if ( end ) return parser->status;
}
-}
+}
<LOC>{
{ws}+ BEGIN (OP); /* LOC field is empty */
@@ -209,7 +222,7 @@ wexpr {expr}({fpart})?(,{expr}({fpart})?)*
}
symbol[1] = 'B'; /* this will be referred as nB afterwards */
BEGIN (OP);
- }
+ }
{flocsymbol}|{blocsymbol} RETURN_ERROR (MIX_PERR_UNEX_LOC, yytext);
{symbol}/({ws}+EQU) { /* store symbol name for future definition */
symbol = g_strdup (yytext);
@@ -253,10 +266,18 @@ wexpr {expr}({fpart})?(,{expr}({fpart})?)*
mix_parser_log_error (parser, MIX_PERR_LONG_ALF, lineno, NULL, TRUE);
value = mix_bytes_to_word (bytes, 5);
-
+
ADD_RAW (value);
}
- [A-Z0-9]+{ws}*/\n |
+ ALF{ws}+.*\n {
+ gchar* msg;
+ guint k = 4;
+ while ( isspace(yytext[k]) ) k++;
+ msg = g_strdup_printf("\"%5s\"", g_strchomp (yytext + k));
+ mix_parser_log_error (parser, MIX_PERR_UNQUOTED_ALF, lineno, msg, FALSE);
+ g_free (msg);
+ }
+ [A-Z0-9]+{ws}*/\n |
[A-Z0-9]+{ws}+ {
mix_ins_id_t id = mix_get_id_from_string (g_strchomp (yytext));
if ( id == mix_INVALID_INS )
@@ -268,7 +289,7 @@ wexpr {expr}({fpart})?(,{expr}({fpart})?)*
BEGIN (ADDRESS);
}
{expr} RETURN_ERROR (MIX_PERR_INV_OP, yytext);
- . RETURN_ERROR (MIX_PERR_INV_OP, yytext);
+ . RETURN_ERROR (MIX_PERR_INV_OP, yytext);
}
@@ -336,7 +357,7 @@ wexpr {expr}({fpart})?(,{expr}({fpart})?)*
[+-]?{number}[(,\n] {
ins.address = mix_short_new (atol (yytext));
switch ( yytext[yyleng-1] ) {
- case '(' : BEGIN (FSPEC); break;
+ case '(' : BEGIN (FSPEC); break;
case ',' : BEGIN (INDEX); break;
case '\n' : ADD_INS (); break;
default: g_assert_not_reached ();
@@ -363,7 +384,7 @@ wexpr {expr}({fpart})?(,{expr}({fpart})?)*
\n ADD_INS ();
. RETURN_ERROR (MIX_PERR_INV_ADDRESS, yytext);
}
-
+
<INDEX>{
{number}[\n(\t ] {
@@ -383,7 +404,7 @@ wexpr {expr}({fpart})?(,{expr}({fpart})?)*
{expr}/[\n(\t ] ENTER_EVAL ();
\n {
mix_parser_log_error (parser, MIX_PERR_INV_IDX, lineno++, NULL, FALSE);
- RESET ();
+ RESET ();
BEGIN (INITIAL);
}
. RETURN_ERROR (MIX_PERR_INV_IDX, yytext);
@@ -392,13 +413,13 @@ wexpr {expr}({fpart})?(,{expr}({fpart})?)*
<FSPEC>{
{number}")"(({ws}+.*\n)|\n) {
glong val = atol (yytext);
- if ( val < 0 || val > MIX_BYTE_MAX )
+ if ( val < 0 || val > MIX_BYTE_MAX )
RETURN_ERROR (MIX_PERR_INV_FSPEC, NULL);
- if ( ins.opcode != mix_opMOVE
+ if ( ins.opcode != mix_opMOVE
&& ( ins.opcode < mix_opJBUS || ins.opcode > mix_opJXx )
&& !mix_fspec_is_valid (mix_byte_new (val)) )
RETURN_ERROR (MIX_PERR_INV_FSPEC, NULL);
- if ( nof )
+ if ( nof )
mix_parser_log_error (parser, MIX_PERR_INV_FSPEC,
lineno, _("ignored"), TRUE);
else
@@ -426,11 +447,11 @@ wexpr {expr}({fpart})?(,{expr}({fpart})?)*
mix_parser_log_error (parser, MIX_PERR_UNDEF_SYM, lineno, s, FALSE);
yy_pop_state ();
}
- expr_val = eval_binop_ (yytext, expr_val,
+ expr_val = eval_binop_ (yytext, expr_val,
mix_symbol_table_value (parser->symbol_table, s));
}
{binop}"*" {
- expr_val = eval_binop_ (yytext, expr_val,
+ expr_val = eval_binop_ (yytext, expr_val,
mix_short_to_word_fast (parser->loc_count));
}
"*" unput_word_ (mix_short_to_word_fast (parser->loc_count));
@@ -457,13 +478,13 @@ wexpr {expr}({fpart})?(,{expr}({fpart})?)*
mix_parser_log_error (parser, MIX_PERR_MIS_PAREN, lineno, NULL, FALSE);
yy_pop_state ();
}
- if ( val < 0 || val > MIX_BYTE_MAX
+ if ( val < 0 || val > MIX_BYTE_MAX
|| !mix_fspec_is_valid (mix_byte_new (val)) ) {
mix_parser_log_error (parser, MIX_PERR_INV_FSPEC, lineno, NULL, FALSE);
yy_pop_state ();
}
is_fp = FALSE;
- wexpr_val = mix_word_store_field (mix_byte_new (val), wexpr_val_tmp,
+ wexpr_val = mix_word_store_field (mix_byte_new (val), wexpr_val_tmp,
wexpr_val);
}
{number}/[,()\n\t ] wexpr_val = mix_word_new (atol (yytext));
@@ -489,8 +510,8 @@ eval_binop_ (const gchar *op, mix_word_t x, mix_word_t y)
mix_word_t result = MIX_WORD_ZERO;
switch (op[0])
{
- case '+':
- result = mix_word_add (x,y);
+ case '+':
+ result = mix_word_add (x,y);
break;
case '-':
result = mix_word_sub (x,y);
@@ -518,16 +539,3 @@ eval_binop_ (const gchar *op, mix_word_t x, mix_word_t y)
return result;
}
-
-static void
-unput_word_ (mix_word_t word)
-{
- gchar *value;
- gint k;
- value = g_strdup_printf ("%s%ld",
- mix_word_is_negative (word)? "-":"+",
- mix_word_magnitude (word));
- for (k = strlen (value) - 1; k >= 0; --k)
- unput (value[k]);
- g_free (value);
-}