Added handling of labels including:

better symbol table functions
  calling them from yacc rather than lex
  a new warning for .label before normal_label
  locallabel_base now a symrec* instead of a strdup'd string.

Still needs some more error checking (to not allow multiple copies of
the same label, etc.)

Also includes move to y_strdup for bison.y.in (ANSI compatibility)

svn path=/trunk/yasm/; revision=51
0.3
Michael Urman 24 years ago
parent 377786e785
commit a6ef33c04c
  1. 5
      include/errwarn.h
  2. 3
      include/globals.h
  3. 42
      include/symrec.h
  4. 5
      libyasm/errwarn.c
  5. 5
      libyasm/errwarn.h
  6. 3
      libyasm/linemgr.h
  7. 105
      libyasm/symrec.c
  8. 42
      libyasm/symrec.h
  9. 24
      modules/parsers/nasm/bison.y.in
  10. 24
      modules/parsers/nasm/nasm-bison.y
  11. 60
      modules/parsers/nasm/token.l.in
  12. 24
      src/bison.y.in
  13. 5
      src/errwarn.c
  14. 5
      src/errwarn.h
  15. 3
      src/globals.h
  16. 3
      src/linemgr.h
  17. 24
      src/parsers/nasm/bison.y.in
  18. 24
      src/parsers/nasm/nasm-bison.y
  19. 60
      src/parsers/nasm/token.l.in
  20. 105
      src/symrec.c
  21. 42
      src/symrec.h
  22. 60
      src/token.l.in

@ -1,4 +1,4 @@
/* $Id: errwarn.h,v 1.4 2001/05/30 07:38:42 peter Exp $
/* $Id: errwarn.h,v 1.5 2001/06/13 05:43:59 mu Exp $
* Error and warning reporting and related functions header file.
*
* Copyright (C) 2001 Peter Johnson
@ -49,7 +49,8 @@ typedef enum {
WARN_UNREC_CHAR,
WARN_VALUE_EXCEEDS_BOUNDS,
WARN_MULT_SEG_OVERRIDE,
WARN_MULT_LOCKREP_PREFIX
WARN_MULT_LOCKREP_PREFIX,
WARN_NO_BASE_LABEL
} warn_num;
void Warning(warn_num, char *, ...);

@ -1,4 +1,4 @@
/* $Id: globals.h,v 1.1 2001/05/15 05:28:06 peter Exp $
/* $Id: globals.h,v 1.2 2001/06/13 05:43:59 mu Exp $
* Globals header file
*
* Copyright (C) 2001 Peter Johnson
@ -24,5 +24,6 @@
extern unsigned int line_number;
extern unsigned int mode_bits;
extern struct symrec_s *locallabel_base;
#endif

@ -1,7 +1,7 @@
/* $Id: symrec.h,v 1.2 2001/05/18 21:40:54 peter Exp $
/* $Id: symrec.h,v 1.3 2001/06/13 05:43:59 mu Exp $
* Symbol table handling header file
*
* Copyright (C) 2001 Peter Johnson
* Copyright (C) 2001 Michael Urman
*
* This file is part of YASM.
*
@ -22,19 +22,39 @@
#ifndef _SYMREC_H_
#define _SYMREC_H_
typedef enum {
SYM_NOSTATUS = 0,
SYM_USED = 1 << 0, /* for using variables before declared */
SYM_DECLARED = 1 << 1, /* once it's been declared */
SYM_VALUED = 1 << 2 /* once its value has been determined */
} SymStatus;
typedef enum {
SYM_CONSTANT, /* for EQU defined symbols */
SYM_LABEL, /* for labels */
SYM_DATA /* for variables */
} SymType;
typedef struct symrec_s {
char *name;
int type;
union {
double var;
double (*fnctptr)(void);
} value;
struct symrec_s *next;
SymType type;
SymStatus status;
int line;
double value;
} symrec;
extern symrec *sym_table;
typedef struct symtab_s {
symrec rec;
struct symtab_s *next;
} symtab;
extern symtab *sym_table;
/*symrec *putsym(char *, SymType);*/
/*symrec *getsym(char *);*/
symrec *putsym(char *, int);
symrec *getsym(char *);
symrec *sym_use_get (char *, SymType);
symrec *sym_def_get (char *, SymType);
void sym_foreach (int(*)(symrec *));
#endif

@ -1,4 +1,4 @@
/* $Id: errwarn.c,v 1.5 2001/05/30 07:38:42 peter Exp $
/* $Id: errwarn.c,v 1.6 2001/06/13 05:43:59 mu Exp $
* Error and warning reporting and related functions.
*
* Copyright (C) 2001 Peter Johnson
@ -51,7 +51,8 @@ static char *warn_msgs[] = {
"ignoring unrecognized character '%s'",
"%s value exceeds bounds",
"multiple segment overrides, using leftmost",
"multiple LOCK or REP prefixes, using leftmost"
"multiple LOCK or REP prefixes, using leftmost",
"no non-local label before '%s'"
};
/* hate to define these as static buffers; better solution would be to use

@ -1,4 +1,4 @@
/* $Id: errwarn.h,v 1.4 2001/05/30 07:38:42 peter Exp $
/* $Id: errwarn.h,v 1.5 2001/06/13 05:43:59 mu Exp $
* Error and warning reporting and related functions header file.
*
* Copyright (C) 2001 Peter Johnson
@ -49,7 +49,8 @@ typedef enum {
WARN_UNREC_CHAR,
WARN_VALUE_EXCEEDS_BOUNDS,
WARN_MULT_SEG_OVERRIDE,
WARN_MULT_LOCKREP_PREFIX
WARN_MULT_LOCKREP_PREFIX,
WARN_NO_BASE_LABEL
} warn_num;
void Warning(warn_num, char *, ...);

@ -1,4 +1,4 @@
/* $Id: linemgr.h,v 1.1 2001/05/15 05:28:06 peter Exp $
/* $Id: linemgr.h,v 1.2 2001/06/13 05:43:59 mu Exp $
* Globals header file
*
* Copyright (C) 2001 Peter Johnson
@ -24,5 +24,6 @@
extern unsigned int line_number;
extern unsigned int mode_bits;
extern struct symrec_s *locallabel_base;
#endif

@ -1,7 +1,7 @@
/* $Id: symrec.c,v 1.1 2001/05/15 05:24:04 peter Exp $
/* $Id: symrec.c,v 1.2 2001/06/13 05:43:59 mu Exp $
* Symbol table handling
*
* Copyright (C) 2001 Peter Johnson
* Copyright (C) 2001 Michael Urman
*
* This file is part of YASM.
*
@ -22,10 +22,105 @@
#include <stdlib.h>
#include <string.h>
#include "symrec.h"
#include "globals.h"
#include "errwarn.h"
/* The symbol table: a chain of `symrec'. */
symrec *sym_table = (symrec *)NULL;
/* private functions */
static symtab *symtab_get (char *);
static symtab *symtab_new (char *, SymType);
static symtab *symtab_get_or_new (char *, SymType);
static void symtab_insert (symtab *);
/* The symbol table: a chain of `symtab'. */
symtab *sym_table = (symtab *)NULL;
/* insert a symtab into the global sym_table */
void symtab_insert (symtab *tab)
{
tab->next = (symtab *)sym_table;
sym_table = tab;
}
/* find a symtab in the global sym_table */
symtab *symtab_get (char *name)
{
symtab *tab;
for (tab = sym_table; tab != NULL; tab = tab->next)
{
if (strcmp (tab->rec.name, name) == 0)
{
return tab;
}
}
return NULL;
}
/* call a function with each symrec. stop early if 0 returned */
void sym_foreach (int(*mapfunc)(symrec *))
{
symtab *tab;
for (tab = sym_table; tab != NULL; tab = tab->next)
{
if (mapfunc(&(tab->rec)) == 0)
{
return;
}
}
}
/* create a new symtab */
symtab *symtab_new (char *name, SymType type)
{
symtab *tab;
tab = malloc(sizeof(symtab));
if (tab == NULL) return NULL;
tab->rec.name = malloc(strlen(name)+1);
if (tab->rec.name == NULL)
{
free (tab);
return NULL;
}
strcpy(tab->rec.name, name);
tab->rec.type = type;
tab->rec.value = 0;
tab->rec.line = line_number;
tab->rec.status = SYM_NOSTATUS;
symtab_insert (tab);
return tab;
}
symtab *symtab_get_or_new (char *name, SymType type)
{
symtab *tab;
tab = symtab_get (name);
if (tab == NULL)
{
tab = symtab_new (name, type);
if (tab == NULL)
{
Fatal (FATAL_NOMEM);
}
}
return tab;
}
symrec *sym_use_get (char *name, SymType type)
{
symtab *tab;
tab = symtab_get_or_new (name, type);
tab->rec.status |= SYM_USED;
return &(tab->rec);
}
symrec *sym_def_get (char *name, SymType type)
{
symtab *tab;
tab = symtab_get_or_new (name, type);
tab->rec.status |= SYM_DECLARED;
return &(tab->rec);
}
#if 0
symrec *putsym(char *sym_name, int sym_type)
{
symrec *ptr;
@ -47,4 +142,4 @@ symrec *getsym(char *sym_name)
return ptr;
return 0;
}
#endif /* 0 */

@ -1,7 +1,7 @@
/* $Id: symrec.h,v 1.2 2001/05/18 21:40:54 peter Exp $
/* $Id: symrec.h,v 1.3 2001/06/13 05:43:59 mu Exp $
* Symbol table handling header file
*
* Copyright (C) 2001 Peter Johnson
* Copyright (C) 2001 Michael Urman
*
* This file is part of YASM.
*
@ -22,19 +22,39 @@
#ifndef _SYMREC_H_
#define _SYMREC_H_
typedef enum {
SYM_NOSTATUS = 0,
SYM_USED = 1 << 0, /* for using variables before declared */
SYM_DECLARED = 1 << 1, /* once it's been declared */
SYM_VALUED = 1 << 2 /* once its value has been determined */
} SymStatus;
typedef enum {
SYM_CONSTANT, /* for EQU defined symbols */
SYM_LABEL, /* for labels */
SYM_DATA /* for variables */
} SymType;
typedef struct symrec_s {
char *name;
int type;
union {
double var;
double (*fnctptr)(void);
} value;
struct symrec_s *next;
SymType type;
SymStatus status;
int line;
double value;
} symrec;
extern symrec *sym_table;
typedef struct symtab_s {
symrec rec;
struct symtab_s *next;
} symtab;
extern symtab *sym_table;
/*symrec *putsym(char *, SymType);*/
/*symrec *getsym(char *);*/
symrec *putsym(char *, int);
symrec *getsym(char *);
symrec *sym_use_get (char *, SymType);
symrec *sym_def_get (char *, SymType);
void sym_foreach (int(*)(symrec *));
#endif

@ -1,7 +1,7 @@
/* $Id: bison.y.in,v 1.9 2001/05/30 07:41:27 peter Exp $
/* $Id: bison.y.in,v 1.10 2001/06/13 05:43:59 mu Exp $
* Main bison parser
*
* Copyright (C) 2001 Peter Johnson
* Copyright (C) 2001 Peter Johnson, Michael Urman
*
* This file is part of YASM.
*
@ -40,6 +40,10 @@ extern void yyerror(char *);
char *str_val;
double double_val;
symrec *sym;
struct {
char *name;
int line;
} syminfo;
effaddr ea_val;
immval im_val;
bytecode bc;
@ -63,14 +67,14 @@ extern void yyerror(char *);
%token <int_val> REG_ES REG_CS REG_SS REG_DS REG_FS REG_GS
%token LEFT_OP RIGHT_OP SIGNDIV SIGNMOD
%token START_SECTION_OFFSET ENTRY_POINT
%token <sym> ID
%token <syminfo> ID LOCAL_ID SPECIAL_ID
/* instruction tokens (dynamically generated) */
/* @TOKENS@ */
/* @TYPES@ */
%type <bc> line exp instr instrbase
%type <bc> line exp instr instrbase label
%type <int_val> fpureg reg32 reg16 reg8 segreg
%type <ea_val> mem memaddr memexp
@ -79,6 +83,7 @@ extern void yyerror(char *);
%type <ea_val> rm8x rm16x rm32x /*rm64x rm128x*/
%type <ea_val> rm8 rm16 rm32 rm64 rm128
%type <im_val> immexp imm imm8x imm16x imm32x imm8 imm16 imm32
%type <sym> label_id
%left '-' '+'
%left '*' '/'
@ -90,6 +95,8 @@ input: /* empty */
line: '\n' { $$.len = 0; }
| exp '\n' { DebugPrintBC(&$1); $$ = $1; }
| label exp '\n' { DebugPrintBC(&$2); $$ = $2; }
| label '\n'
| directive '\n' { }
| error '\n' { Error(ERR_INVALID_LINE, (char *)NULL); yyerrok; }
;
@ -97,6 +104,15 @@ line: '\n' { $$.len = 0; }
exp: instr
;
label: label_id { $1->value = 0; } /* TODO: calculate offset */
| label_id ':' { $1->value = 0; } /* TODO: calculate offset */
;
label_id: ID { $$ = locallabel_base = sym_def_get ($1.name, SYM_LABEL); }
| SPECIAL_ID { $$ = sym_def_get ($1.name, SYM_LABEL); }
| LOCAL_ID { $$ = sym_def_get ($1.name, SYM_LABEL); }
;
/* directives */
directive: '[' DIRECTIVE_NAME DIRECTIVE_VAL ']' {
printf("Directive: Name='%s' Value='%s'\n", $2, $3);

@ -1,7 +1,7 @@
/* $Id: nasm-bison.y,v 1.9 2001/05/30 07:41:27 peter Exp $
/* $Id: nasm-bison.y,v 1.10 2001/06/13 05:43:59 mu Exp $
* Main bison parser
*
* Copyright (C) 2001 Peter Johnson
* Copyright (C) 2001 Peter Johnson, Michael Urman
*
* This file is part of YASM.
*
@ -40,6 +40,10 @@ extern void yyerror(char *);
char *str_val;
double double_val;
symrec *sym;
struct {
char *name;
int line;
} syminfo;
effaddr ea_val;
immval im_val;
bytecode bc;
@ -63,14 +67,14 @@ extern void yyerror(char *);
%token <int_val> REG_ES REG_CS REG_SS REG_DS REG_FS REG_GS
%token LEFT_OP RIGHT_OP SIGNDIV SIGNMOD
%token START_SECTION_OFFSET ENTRY_POINT
%token <sym> ID
%token <syminfo> ID LOCAL_ID SPECIAL_ID
/* instruction tokens (dynamically generated) */
/* @TOKENS@ */
/* @TYPES@ */
%type <bc> line exp instr instrbase
%type <bc> line exp instr instrbase label
%type <int_val> fpureg reg32 reg16 reg8 segreg
%type <ea_val> mem memaddr memexp
@ -79,6 +83,7 @@ extern void yyerror(char *);
%type <ea_val> rm8x rm16x rm32x /*rm64x rm128x*/
%type <ea_val> rm8 rm16 rm32 rm64 rm128
%type <im_val> immexp imm imm8x imm16x imm32x imm8 imm16 imm32
%type <sym> label_id
%left '-' '+'
%left '*' '/'
@ -90,6 +95,8 @@ input: /* empty */
line: '\n' { $$.len = 0; }
| exp '\n' { DebugPrintBC(&$1); $$ = $1; }
| label exp '\n' { DebugPrintBC(&$2); $$ = $2; }
| label '\n'
| directive '\n' { }
| error '\n' { Error(ERR_INVALID_LINE, (char *)NULL); yyerrok; }
;
@ -97,6 +104,15 @@ line: '\n' { $$.len = 0; }
exp: instr
;
label: label_id { $1->value = 0; } /* TODO: calculate offset */
| label_id ':' { $1->value = 0; } /* TODO: calculate offset */
;
label_id: ID { $$ = locallabel_base = sym_def_get ($1.name, SYM_LABEL); }
| SPECIAL_ID { $$ = sym_def_get ($1.name, SYM_LABEL); }
| LOCAL_ID { $$ = sym_def_get ($1.name, SYM_LABEL); }
;
/* directives */
directive: '[' DIRECTIVE_NAME DIRECTIVE_VAL ']' {
printf("Directive: Name='%s' Value='%s'\n", $2, $3);

@ -1,4 +1,4 @@
/* $Id: token.l.in,v 1.5 2001/05/21 22:10:02 peter Exp $
/* $Id: token.l.in,v 1.6 2001/06/13 05:43:59 mu Exp $
* Main lexer
*
* Copyright (C) 2001 Peter Johnson
@ -25,13 +25,15 @@
#include "symrec.h"
#include "bytecode.h"
#include "errwarn.h"
#include "util.h"
#include "bison.tab.h"
%}
%option noyywrap
%option nounput
%option case-insensitive
static char *locallabel_base = (char *)NULL;
symrec *locallabel_base = (symrec *)NULL;
int line_number;
%x DIRECTIVE DIRECTIVE2
@ -88,14 +90,14 @@ WS [ \t\r]
<DIRECTIVE2>{WS}+ ;
<DIRECTIVE>[a-z]+ {
BEGIN DIRECTIVE2;
yylval.str_val = strdup(yytext);
yylval.str_val = y_strdup(yytext);
if(!yylval.str_val)
Fatal(FATAL_NOMEM);
return DIRECTIVE_NAME;
}
/* everything printable except for ' ', '[' and ']'. */
<DIRECTIVE2>[!-@a-z\\^-`{|}~]+ {
yylval.str_val = strdup(yytext);
yylval.str_val = y_strdup(yytext);
if(!yylval.str_val)
Fatal(FATAL_NOMEM);
return DIRECTIVE_VAL;
@ -220,21 +222,33 @@ gs { yylval.int_val = 5; return REG_GS; }
/* special non-local ..@label */
\.\.@[a-z0-9_$#@~.?]+ {
symrec *s = getsym(yytext);
if(!s)
s = putsym(yytext, ID);
yylval.sym = s;
return s->type;
yylval.syminfo.name = y_strdup (yytext);
if (yylval.syminfo.name == NULL) Fatal (FATAL_NOMEM);
yylval.syminfo.line = line_number;
return SPECIAL_ID;
}
/* local label (.label) */
\.[a-z0-9_$#@~?][a-z0-9_$#@~.?]* {
/* TODO: append yytext to locallabel_base before testing */
symrec *s = getsym(yytext);
if(!s)
s = putsym(yytext, ID);
yylval.sym = s;
return s->type;
if (locallabel_base == NULL)
{
Warning (WARN_NO_BASE_LABEL, (char *)NULL, yytext);
yylval.syminfo.name = y_strdup (yytext);
if (yylval.syminfo.name == NULL) Fatal (FATAL_NOMEM);
}
else
{
yylval.syminfo.name = malloc (strlen (yytext)
+ strlen (locallabel_base->name)
+ 1);
if (yylval.syminfo.name == NULL) Fatal (FATAL_NOMEM);
strcpy (yylval.syminfo.name, locallabel_base->name);
strcat (yylval.syminfo.name, yytext);
}
yylval.syminfo.line = line_number;
return LOCAL_ID;
}
/* instructions */
@ -242,19 +256,11 @@ gs { yylval.int_val = 5; return REG_GS; }
/* label */
[a-z_?][a-z0-9_$#@~.?]* {
symrec *s = getsym(yytext);
if(!s)
s = putsym(yytext, ID);
yylval.sym = s;
/* TODO: optimize to decrease number of allocations */
if(locallabel_base)
free(locallabel_base);
locallabel_base = strdup(yytext);
if(!locallabel_base)
Fatal(FATAL_NOMEM);
yylval.syminfo.name = y_strdup (yytext);
if (yylval.syminfo.name == NULL) Fatal (FATAL_NOMEM);
yylval.syminfo.line = line_number;
return s->type;
return ID;
}
;.* ;

@ -1,7 +1,7 @@
/* $Id: bison.y.in,v 1.9 2001/05/30 07:41:27 peter Exp $
/* $Id: bison.y.in,v 1.10 2001/06/13 05:43:59 mu Exp $
* Main bison parser
*
* Copyright (C) 2001 Peter Johnson
* Copyright (C) 2001 Peter Johnson, Michael Urman
*
* This file is part of YASM.
*
@ -40,6 +40,10 @@ extern void yyerror(char *);
char *str_val;
double double_val;
symrec *sym;
struct {
char *name;
int line;
} syminfo;
effaddr ea_val;
immval im_val;
bytecode bc;
@ -63,14 +67,14 @@ extern void yyerror(char *);
%token <int_val> REG_ES REG_CS REG_SS REG_DS REG_FS REG_GS
%token LEFT_OP RIGHT_OP SIGNDIV SIGNMOD
%token START_SECTION_OFFSET ENTRY_POINT
%token <sym> ID
%token <syminfo> ID LOCAL_ID SPECIAL_ID
/* instruction tokens (dynamically generated) */
/* @TOKENS@ */
/* @TYPES@ */
%type <bc> line exp instr instrbase
%type <bc> line exp instr instrbase label
%type <int_val> fpureg reg32 reg16 reg8 segreg
%type <ea_val> mem memaddr memexp
@ -79,6 +83,7 @@ extern void yyerror(char *);
%type <ea_val> rm8x rm16x rm32x /*rm64x rm128x*/
%type <ea_val> rm8 rm16 rm32 rm64 rm128
%type <im_val> immexp imm imm8x imm16x imm32x imm8 imm16 imm32
%type <sym> label_id
%left '-' '+'
%left '*' '/'
@ -90,6 +95,8 @@ input: /* empty */
line: '\n' { $$.len = 0; }
| exp '\n' { DebugPrintBC(&$1); $$ = $1; }
| label exp '\n' { DebugPrintBC(&$2); $$ = $2; }
| label '\n'
| directive '\n' { }
| error '\n' { Error(ERR_INVALID_LINE, (char *)NULL); yyerrok; }
;
@ -97,6 +104,15 @@ line: '\n' { $$.len = 0; }
exp: instr
;
label: label_id { $1->value = 0; } /* TODO: calculate offset */
| label_id ':' { $1->value = 0; } /* TODO: calculate offset */
;
label_id: ID { $$ = locallabel_base = sym_def_get ($1.name, SYM_LABEL); }
| SPECIAL_ID { $$ = sym_def_get ($1.name, SYM_LABEL); }
| LOCAL_ID { $$ = sym_def_get ($1.name, SYM_LABEL); }
;
/* directives */
directive: '[' DIRECTIVE_NAME DIRECTIVE_VAL ']' {
printf("Directive: Name='%s' Value='%s'\n", $2, $3);

@ -1,4 +1,4 @@
/* $Id: errwarn.c,v 1.5 2001/05/30 07:38:42 peter Exp $
/* $Id: errwarn.c,v 1.6 2001/06/13 05:43:59 mu Exp $
* Error and warning reporting and related functions.
*
* Copyright (C) 2001 Peter Johnson
@ -51,7 +51,8 @@ static char *warn_msgs[] = {
"ignoring unrecognized character '%s'",
"%s value exceeds bounds",
"multiple segment overrides, using leftmost",
"multiple LOCK or REP prefixes, using leftmost"
"multiple LOCK or REP prefixes, using leftmost",
"no non-local label before '%s'"
};
/* hate to define these as static buffers; better solution would be to use

@ -1,4 +1,4 @@
/* $Id: errwarn.h,v 1.4 2001/05/30 07:38:42 peter Exp $
/* $Id: errwarn.h,v 1.5 2001/06/13 05:43:59 mu Exp $
* Error and warning reporting and related functions header file.
*
* Copyright (C) 2001 Peter Johnson
@ -49,7 +49,8 @@ typedef enum {
WARN_UNREC_CHAR,
WARN_VALUE_EXCEEDS_BOUNDS,
WARN_MULT_SEG_OVERRIDE,
WARN_MULT_LOCKREP_PREFIX
WARN_MULT_LOCKREP_PREFIX,
WARN_NO_BASE_LABEL
} warn_num;
void Warning(warn_num, char *, ...);

@ -1,4 +1,4 @@
/* $Id: globals.h,v 1.1 2001/05/15 05:28:06 peter Exp $
/* $Id: globals.h,v 1.2 2001/06/13 05:43:59 mu Exp $
* Globals header file
*
* Copyright (C) 2001 Peter Johnson
@ -24,5 +24,6 @@
extern unsigned int line_number;
extern unsigned int mode_bits;
extern struct symrec_s *locallabel_base;
#endif

@ -1,4 +1,4 @@
/* $Id: linemgr.h,v 1.1 2001/05/15 05:28:06 peter Exp $
/* $Id: linemgr.h,v 1.2 2001/06/13 05:43:59 mu Exp $
* Globals header file
*
* Copyright (C) 2001 Peter Johnson
@ -24,5 +24,6 @@
extern unsigned int line_number;
extern unsigned int mode_bits;
extern struct symrec_s *locallabel_base;
#endif

@ -1,7 +1,7 @@
/* $Id: bison.y.in,v 1.9 2001/05/30 07:41:27 peter Exp $
/* $Id: bison.y.in,v 1.10 2001/06/13 05:43:59 mu Exp $
* Main bison parser
*
* Copyright (C) 2001 Peter Johnson
* Copyright (C) 2001 Peter Johnson, Michael Urman
*
* This file is part of YASM.
*
@ -40,6 +40,10 @@ extern void yyerror(char *);
char *str_val;
double double_val;
symrec *sym;
struct {
char *name;
int line;
} syminfo;
effaddr ea_val;
immval im_val;
bytecode bc;
@ -63,14 +67,14 @@ extern void yyerror(char *);
%token <int_val> REG_ES REG_CS REG_SS REG_DS REG_FS REG_GS
%token LEFT_OP RIGHT_OP SIGNDIV SIGNMOD
%token START_SECTION_OFFSET ENTRY_POINT
%token <sym> ID
%token <syminfo> ID LOCAL_ID SPECIAL_ID
/* instruction tokens (dynamically generated) */
/* @TOKENS@ */
/* @TYPES@ */
%type <bc> line exp instr instrbase
%type <bc> line exp instr instrbase label
%type <int_val> fpureg reg32 reg16 reg8 segreg
%type <ea_val> mem memaddr memexp
@ -79,6 +83,7 @@ extern void yyerror(char *);
%type <ea_val> rm8x rm16x rm32x /*rm64x rm128x*/
%type <ea_val> rm8 rm16 rm32 rm64 rm128
%type <im_val> immexp imm imm8x imm16x imm32x imm8 imm16 imm32
%type <sym> label_id
%left '-' '+'
%left '*' '/'
@ -90,6 +95,8 @@ input: /* empty */
line: '\n' { $$.len = 0; }
| exp '\n' { DebugPrintBC(&$1); $$ = $1; }
| label exp '\n' { DebugPrintBC(&$2); $$ = $2; }
| label '\n'
| directive '\n' { }
| error '\n' { Error(ERR_INVALID_LINE, (char *)NULL); yyerrok; }
;
@ -97,6 +104,15 @@ line: '\n' { $$.len = 0; }
exp: instr
;
label: label_id { $1->value = 0; } /* TODO: calculate offset */
| label_id ':' { $1->value = 0; } /* TODO: calculate offset */
;
label_id: ID { $$ = locallabel_base = sym_def_get ($1.name, SYM_LABEL); }
| SPECIAL_ID { $$ = sym_def_get ($1.name, SYM_LABEL); }
| LOCAL_ID { $$ = sym_def_get ($1.name, SYM_LABEL); }
;
/* directives */
directive: '[' DIRECTIVE_NAME DIRECTIVE_VAL ']' {
printf("Directive: Name='%s' Value='%s'\n", $2, $3);

@ -1,7 +1,7 @@
/* $Id: nasm-bison.y,v 1.9 2001/05/30 07:41:27 peter Exp $
/* $Id: nasm-bison.y,v 1.10 2001/06/13 05:43:59 mu Exp $
* Main bison parser
*
* Copyright (C) 2001 Peter Johnson
* Copyright (C) 2001 Peter Johnson, Michael Urman
*
* This file is part of YASM.
*
@ -40,6 +40,10 @@ extern void yyerror(char *);
char *str_val;
double double_val;
symrec *sym;
struct {
char *name;
int line;
} syminfo;
effaddr ea_val;
immval im_val;
bytecode bc;
@ -63,14 +67,14 @@ extern void yyerror(char *);
%token <int_val> REG_ES REG_CS REG_SS REG_DS REG_FS REG_GS
%token LEFT_OP RIGHT_OP SIGNDIV SIGNMOD
%token START_SECTION_OFFSET ENTRY_POINT
%token <sym> ID
%token <syminfo> ID LOCAL_ID SPECIAL_ID
/* instruction tokens (dynamically generated) */
/* @TOKENS@ */
/* @TYPES@ */
%type <bc> line exp instr instrbase
%type <bc> line exp instr instrbase label
%type <int_val> fpureg reg32 reg16 reg8 segreg
%type <ea_val> mem memaddr memexp
@ -79,6 +83,7 @@ extern void yyerror(char *);
%type <ea_val> rm8x rm16x rm32x /*rm64x rm128x*/
%type <ea_val> rm8 rm16 rm32 rm64 rm128
%type <im_val> immexp imm imm8x imm16x imm32x imm8 imm16 imm32
%type <sym> label_id
%left '-' '+'
%left '*' '/'
@ -90,6 +95,8 @@ input: /* empty */
line: '\n' { $$.len = 0; }
| exp '\n' { DebugPrintBC(&$1); $$ = $1; }
| label exp '\n' { DebugPrintBC(&$2); $$ = $2; }
| label '\n'
| directive '\n' { }
| error '\n' { Error(ERR_INVALID_LINE, (char *)NULL); yyerrok; }
;
@ -97,6 +104,15 @@ line: '\n' { $$.len = 0; }
exp: instr
;
label: label_id { $1->value = 0; } /* TODO: calculate offset */
| label_id ':' { $1->value = 0; } /* TODO: calculate offset */
;
label_id: ID { $$ = locallabel_base = sym_def_get ($1.name, SYM_LABEL); }
| SPECIAL_ID { $$ = sym_def_get ($1.name, SYM_LABEL); }
| LOCAL_ID { $$ = sym_def_get ($1.name, SYM_LABEL); }
;
/* directives */
directive: '[' DIRECTIVE_NAME DIRECTIVE_VAL ']' {
printf("Directive: Name='%s' Value='%s'\n", $2, $3);

@ -1,4 +1,4 @@
/* $Id: token.l.in,v 1.5 2001/05/21 22:10:02 peter Exp $
/* $Id: token.l.in,v 1.6 2001/06/13 05:43:59 mu Exp $
* Main lexer
*
* Copyright (C) 2001 Peter Johnson
@ -25,13 +25,15 @@
#include "symrec.h"
#include "bytecode.h"
#include "errwarn.h"
#include "util.h"
#include "bison.tab.h"
%}
%option noyywrap
%option nounput
%option case-insensitive
static char *locallabel_base = (char *)NULL;
symrec *locallabel_base = (symrec *)NULL;
int line_number;
%x DIRECTIVE DIRECTIVE2
@ -88,14 +90,14 @@ WS [ \t\r]
<DIRECTIVE2>{WS}+ ;
<DIRECTIVE>[a-z]+ {
BEGIN DIRECTIVE2;
yylval.str_val = strdup(yytext);
yylval.str_val = y_strdup(yytext);
if(!yylval.str_val)
Fatal(FATAL_NOMEM);
return DIRECTIVE_NAME;
}
/* everything printable except for ' ', '[' and ']'. */
<DIRECTIVE2>[!-@a-z\\^-`{|}~]+ {
yylval.str_val = strdup(yytext);
yylval.str_val = y_strdup(yytext);
if(!yylval.str_val)
Fatal(FATAL_NOMEM);
return DIRECTIVE_VAL;
@ -220,21 +222,33 @@ gs { yylval.int_val = 5; return REG_GS; }
/* special non-local ..@label */
\.\.@[a-z0-9_$#@~.?]+ {
symrec *s = getsym(yytext);
if(!s)
s = putsym(yytext, ID);
yylval.sym = s;
return s->type;
yylval.syminfo.name = y_strdup (yytext);
if (yylval.syminfo.name == NULL) Fatal (FATAL_NOMEM);
yylval.syminfo.line = line_number;
return SPECIAL_ID;
}
/* local label (.label) */
\.[a-z0-9_$#@~?][a-z0-9_$#@~.?]* {
/* TODO: append yytext to locallabel_base before testing */
symrec *s = getsym(yytext);
if(!s)
s = putsym(yytext, ID);
yylval.sym = s;
return s->type;
if (locallabel_base == NULL)
{
Warning (WARN_NO_BASE_LABEL, (char *)NULL, yytext);
yylval.syminfo.name = y_strdup (yytext);
if (yylval.syminfo.name == NULL) Fatal (FATAL_NOMEM);
}
else
{
yylval.syminfo.name = malloc (strlen (yytext)
+ strlen (locallabel_base->name)
+ 1);
if (yylval.syminfo.name == NULL) Fatal (FATAL_NOMEM);
strcpy (yylval.syminfo.name, locallabel_base->name);
strcat (yylval.syminfo.name, yytext);
}
yylval.syminfo.line = line_number;
return LOCAL_ID;
}
/* instructions */
@ -242,19 +256,11 @@ gs { yylval.int_val = 5; return REG_GS; }
/* label */
[a-z_?][a-z0-9_$#@~.?]* {
symrec *s = getsym(yytext);
if(!s)
s = putsym(yytext, ID);
yylval.sym = s;
/* TODO: optimize to decrease number of allocations */
if(locallabel_base)
free(locallabel_base);
locallabel_base = strdup(yytext);
if(!locallabel_base)
Fatal(FATAL_NOMEM);
yylval.syminfo.name = y_strdup (yytext);
if (yylval.syminfo.name == NULL) Fatal (FATAL_NOMEM);
yylval.syminfo.line = line_number;
return s->type;
return ID;
}
;.* ;

@ -1,7 +1,7 @@
/* $Id: symrec.c,v 1.1 2001/05/15 05:24:04 peter Exp $
/* $Id: symrec.c,v 1.2 2001/06/13 05:43:59 mu Exp $
* Symbol table handling
*
* Copyright (C) 2001 Peter Johnson
* Copyright (C) 2001 Michael Urman
*
* This file is part of YASM.
*
@ -22,10 +22,105 @@
#include <stdlib.h>
#include <string.h>
#include "symrec.h"
#include "globals.h"
#include "errwarn.h"
/* The symbol table: a chain of `symrec'. */
symrec *sym_table = (symrec *)NULL;
/* private functions */
static symtab *symtab_get (char *);
static symtab *symtab_new (char *, SymType);
static symtab *symtab_get_or_new (char *, SymType);
static void symtab_insert (symtab *);
/* The symbol table: a chain of `symtab'. */
symtab *sym_table = (symtab *)NULL;
/* insert a symtab into the global sym_table */
void symtab_insert (symtab *tab)
{
tab->next = (symtab *)sym_table;
sym_table = tab;
}
/* find a symtab in the global sym_table */
symtab *symtab_get (char *name)
{
symtab *tab;
for (tab = sym_table; tab != NULL; tab = tab->next)
{
if (strcmp (tab->rec.name, name) == 0)
{
return tab;
}
}
return NULL;
}
/* call a function with each symrec. stop early if 0 returned */
void sym_foreach (int(*mapfunc)(symrec *))
{
symtab *tab;
for (tab = sym_table; tab != NULL; tab = tab->next)
{
if (mapfunc(&(tab->rec)) == 0)
{
return;
}
}
}
/* create a new symtab */
symtab *symtab_new (char *name, SymType type)
{
symtab *tab;
tab = malloc(sizeof(symtab));
if (tab == NULL) return NULL;
tab->rec.name = malloc(strlen(name)+1);
if (tab->rec.name == NULL)
{
free (tab);
return NULL;
}
strcpy(tab->rec.name, name);
tab->rec.type = type;
tab->rec.value = 0;
tab->rec.line = line_number;
tab->rec.status = SYM_NOSTATUS;
symtab_insert (tab);
return tab;
}
symtab *symtab_get_or_new (char *name, SymType type)
{
symtab *tab;
tab = symtab_get (name);
if (tab == NULL)
{
tab = symtab_new (name, type);
if (tab == NULL)
{
Fatal (FATAL_NOMEM);
}
}
return tab;
}
symrec *sym_use_get (char *name, SymType type)
{
symtab *tab;
tab = symtab_get_or_new (name, type);
tab->rec.status |= SYM_USED;
return &(tab->rec);
}
symrec *sym_def_get (char *name, SymType type)
{
symtab *tab;
tab = symtab_get_or_new (name, type);
tab->rec.status |= SYM_DECLARED;
return &(tab->rec);
}
#if 0
symrec *putsym(char *sym_name, int sym_type)
{
symrec *ptr;
@ -47,4 +142,4 @@ symrec *getsym(char *sym_name)
return ptr;
return 0;
}
#endif /* 0 */

@ -1,7 +1,7 @@
/* $Id: symrec.h,v 1.2 2001/05/18 21:40:54 peter Exp $
/* $Id: symrec.h,v 1.3 2001/06/13 05:43:59 mu Exp $
* Symbol table handling header file
*
* Copyright (C) 2001 Peter Johnson
* Copyright (C) 2001 Michael Urman
*
* This file is part of YASM.
*
@ -22,19 +22,39 @@
#ifndef _SYMREC_H_
#define _SYMREC_H_
typedef enum {
SYM_NOSTATUS = 0,
SYM_USED = 1 << 0, /* for using variables before declared */
SYM_DECLARED = 1 << 1, /* once it's been declared */
SYM_VALUED = 1 << 2 /* once its value has been determined */
} SymStatus;
typedef enum {
SYM_CONSTANT, /* for EQU defined symbols */
SYM_LABEL, /* for labels */
SYM_DATA /* for variables */
} SymType;
typedef struct symrec_s {
char *name;
int type;
union {
double var;
double (*fnctptr)(void);
} value;
struct symrec_s *next;
SymType type;
SymStatus status;
int line;
double value;
} symrec;
extern symrec *sym_table;
typedef struct symtab_s {
symrec rec;
struct symtab_s *next;
} symtab;
extern symtab *sym_table;
/*symrec *putsym(char *, SymType);*/
/*symrec *getsym(char *);*/
symrec *putsym(char *, int);
symrec *getsym(char *);
symrec *sym_use_get (char *, SymType);
symrec *sym_def_get (char *, SymType);
void sym_foreach (int(*)(symrec *));
#endif

@ -1,4 +1,4 @@
/* $Id: token.l.in,v 1.5 2001/05/21 22:10:02 peter Exp $
/* $Id: token.l.in,v 1.6 2001/06/13 05:43:59 mu Exp $
* Main lexer
*
* Copyright (C) 2001 Peter Johnson
@ -25,13 +25,15 @@
#include "symrec.h"
#include "bytecode.h"
#include "errwarn.h"
#include "util.h"
#include "bison.tab.h"
%}
%option noyywrap
%option nounput
%option case-insensitive
static char *locallabel_base = (char *)NULL;
symrec *locallabel_base = (symrec *)NULL;
int line_number;
%x DIRECTIVE DIRECTIVE2
@ -88,14 +90,14 @@ WS [ \t\r]
<DIRECTIVE2>{WS}+ ;
<DIRECTIVE>[a-z]+ {
BEGIN DIRECTIVE2;
yylval.str_val = strdup(yytext);
yylval.str_val = y_strdup(yytext);
if(!yylval.str_val)
Fatal(FATAL_NOMEM);
return DIRECTIVE_NAME;
}
/* everything printable except for ' ', '[' and ']'. */
<DIRECTIVE2>[!-@a-z\\^-`{|}~]+ {
yylval.str_val = strdup(yytext);
yylval.str_val = y_strdup(yytext);
if(!yylval.str_val)
Fatal(FATAL_NOMEM);
return DIRECTIVE_VAL;
@ -220,21 +222,33 @@ gs { yylval.int_val = 5; return REG_GS; }
/* special non-local ..@label */
\.\.@[a-z0-9_$#@~.?]+ {
symrec *s = getsym(yytext);
if(!s)
s = putsym(yytext, ID);
yylval.sym = s;
return s->type;
yylval.syminfo.name = y_strdup (yytext);
if (yylval.syminfo.name == NULL) Fatal (FATAL_NOMEM);
yylval.syminfo.line = line_number;
return SPECIAL_ID;
}
/* local label (.label) */
\.[a-z0-9_$#@~?][a-z0-9_$#@~.?]* {
/* TODO: append yytext to locallabel_base before testing */
symrec *s = getsym(yytext);
if(!s)
s = putsym(yytext, ID);
yylval.sym = s;
return s->type;
if (locallabel_base == NULL)
{
Warning (WARN_NO_BASE_LABEL, (char *)NULL, yytext);
yylval.syminfo.name = y_strdup (yytext);
if (yylval.syminfo.name == NULL) Fatal (FATAL_NOMEM);
}
else
{
yylval.syminfo.name = malloc (strlen (yytext)
+ strlen (locallabel_base->name)
+ 1);
if (yylval.syminfo.name == NULL) Fatal (FATAL_NOMEM);
strcpy (yylval.syminfo.name, locallabel_base->name);
strcat (yylval.syminfo.name, yytext);
}
yylval.syminfo.line = line_number;
return LOCAL_ID;
}
/* instructions */
@ -242,19 +256,11 @@ gs { yylval.int_val = 5; return REG_GS; }
/* label */
[a-z_?][a-z0-9_$#@~.?]* {
symrec *s = getsym(yytext);
if(!s)
s = putsym(yytext, ID);
yylval.sym = s;
/* TODO: optimize to decrease number of allocations */
if(locallabel_base)
free(locallabel_base);
locallabel_base = strdup(yytext);
if(!locallabel_base)
Fatal(FATAL_NOMEM);
yylval.syminfo.name = y_strdup (yytext);
if (yylval.syminfo.name == NULL) Fatal (FATAL_NOMEM);
yylval.syminfo.line = line_number;
return s->type;
return ID;
}
;.* ;

Loading…
Cancel
Save