root/gtags-parser/asm_parse.y

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. assembly
  2. yyerror

%{
/*
 * Copyright (c) 2004 Tama Communications Corporation
 *
 * This file is part of GNU GLOBAL.
 *
 * 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 3 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, see <http://www.gnu.org/licenses/>.
 */

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <ctype.h>
#include <stdio.h>

#include "defined.h"
#include "die.h"
#include "gctags.h"
#include "linetable.h"
#include "strbuf.h"

#define YYLTYPE         int

#define YYLLOC_DEFAULT(Current, Rhs, N) ((Current) = (Rhs)[1])

#undef PUT
#define PUT(tag, lno) do {                                              \
        if (!nflag) {                                                   \
                printf("%-16s %4d %-16s ", tag, lno, asm_input_file);   \
                linetable_print(stdout, lno);                           \
        }                                                               \
} while (0)

#define GET_SYM(offset) ((offset) < strbuf_getlen(asm_symtable)         \
                         ? &strbuf_value(asm_symtable)[offset]          \
                         : (die("BUG!!"), (char *)NULL))

int yylex(void);
void asm_initscan(void);

int asm_target;
const char *asm_input_file;
STRBUF *asm_symtable;

static void yyerror(const char *);

%}

%token ASM_CONST                /* number, string, character */

%token ASM_CALL                 /* call, jsr */
%token ASM_ENTRY                /* ENTRY, ALTENTRY, ... */
%token ASM_EXT                  /* EXT, SYMBOL_NAME, ... */
%token ASM_SYMBOL
%token ASM_LABEL                /* ^sym */

%token ASM_DEFINE "#define"
%token ASM_UNDEF "#undef"
%token ASM_DIRECTIVE            /* #xxx */

%token ASM_MACRO                /* .macro */
%token ASM_EQU                  /* .equ */

%start input
%name-prefix="asm_"

%%

input:  /* empty */
        | input line
;

line:   ASM_ENTRY '(' ASM_SYMBOL ')' error '\n'
                {
                        if (asm_target == REF) {
                                char *sym = GET_SYM($1);

                                if (defined(sym))
                                        PUT(sym, @1);
                        }
                        if (asm_target == DEF)
                                PUT(GET_SYM($3), @3);
                        strbuf_reset(asm_symtable);
                }
        | ASM_CALL ASM_SYMBOL error '\n'
                {
                        if (asm_target == REF) {
                                char *sym = GET_SYM($2);

                                if (sym[0] == '_') {
                                        int c = (unsigned char)sym[1];

                                        if ((isalpha(c) || c == '_' || c >= 0x80)
                                            && defined(&sym[1]))
                                                PUT(&sym[1], @2);
                                }
                        }
                        strbuf_reset(asm_symtable);
                }
        | ASM_CALL ASM_EXT '(' ASM_SYMBOL ')' error '\n'
                {
                        if (asm_target == REF) {
                                char *sym;

                                sym = GET_SYM($2);
                                if (defined(sym))
                                        PUT(sym, @2);

                                sym = GET_SYM($4);
                                if (defined(sym))
                                        PUT(sym, @4);
                        }
                        strbuf_reset(asm_symtable);
                }
        | "#define" ASM_SYMBOL error '\n'
                {
                        if (asm_target == DEF)
                                PUT(GET_SYM($2), @2);
                        strbuf_reset(asm_symtable);
                }
        | "#undef" ASM_SYMBOL error '\n'
                {
                        if (asm_target == DEF)
                                PUT(GET_SYM($2), @2);
                        strbuf_reset(asm_symtable);
                }
        | ASM_MACRO ASM_SYMBOL error '\n'
                {
                        if (asm_target == DEF)
                                PUT(GET_SYM($2), @2);
                        strbuf_reset(asm_symtable);
                }
        | ASM_LABEL ASM_MACRO error '\n'
                {
                        if (asm_target == DEF)
                                PUT(GET_SYM($1), @1);
                        strbuf_reset(asm_symtable);
                }
        | ASM_EQU ASM_SYMBOL ',' error '\n'
                {
                        if (asm_target == DEF)
                                PUT(GET_SYM($2), @2);
                        strbuf_reset(asm_symtable);
                }
        | ASM_LABEL ASM_EQU error '\n'
                {
                        if (asm_target == DEF)
                                PUT(GET_SYM($1), @1);
                        strbuf_reset(asm_symtable);
                }
        | error '\n'
                { strbuf_reset(asm_symtable); }
;

%%

void
assembly(const char *file)
{
        asm_target = sflag ? SYM : rflag ? REF : DEF;

        if (linetable_open(file) == -1)
                die("'%s' cannot open.", file);
        asm_input_file = file;

        asm_symtable = strbuf_open(0);
        asm_initscan();

        asm_parse();

        strbuf_close(asm_symtable);
        linetable_close();
}

static void
yyerror(const char *s)
{

}

/* [<][>][^][v][top][bottom][index][help] */