OpenCores
URL https://opencores.org/ocsvn/eco32/eco32/trunk

Subversion Repositories eco32

[/] [eco32/] [tags/] [eco32-0.26/] [lcc/] [cpp/] [lex.c] - Diff between revs 4 and 270

Only display areas with differences | Details | Blame | View Log

Rev 4 Rev 270
#include <stdio.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdlib.h>
#include <string.h>
#include <string.h>
#include "cpp.h"
#include "cpp.h"
 
 
/*
/*
 * lexical FSM encoding
 * lexical FSM encoding
 *   when in state state, and one of the characters
 *   when in state state, and one of the characters
 *   in ch arrives, enter nextstate.
 *   in ch arrives, enter nextstate.
 *   States >= S_SELF are either final, or at least require special action.
 *   States >= S_SELF are either final, or at least require special action.
 *   In 'fsm' there is a line for each state X charset X nextstate.
 *   In 'fsm' there is a line for each state X charset X nextstate.
 *   List chars that overwrite previous entries later (e.g. C_ALPH
 *   List chars that overwrite previous entries later (e.g. C_ALPH
 *   can be overridden by '_' by a later entry; and C_XX is the
 *   can be overridden by '_' by a later entry; and C_XX is the
 *   the universal set, and should always be first.
 *   the universal set, and should always be first.
 *   States above S_SELF are represented in the big table as negative values.
 *   States above S_SELF are represented in the big table as negative values.
 *   S_SELF and S_SELFB encode the resulting token type in the upper bits.
 *   S_SELF and S_SELFB encode the resulting token type in the upper bits.
 *   These actions differ in that S_SELF doesn't have a lookahead char,
 *   These actions differ in that S_SELF doesn't have a lookahead char,
 *   S_SELFB does.
 *   S_SELFB does.
 *
 *
 *   The encoding is blown out into a big table for time-efficiency.
 *   The encoding is blown out into a big table for time-efficiency.
 *   Entries have
 *   Entries have
 *      nextstate: 6 bits; ?\ marker: 1 bit; tokentype: 9 bits.
 *      nextstate: 6 bits; ?\ marker: 1 bit; tokentype: 9 bits.
 */
 */
 
 
#define MAXSTATE 32
#define MAXSTATE 32
#define ACT(tok,act)    ((tok<<7)+act)
#define ACT(tok,act)    ((tok<<7)+act)
#define QBSBIT  0100
#define QBSBIT  0100
#define GETACT(st)      (st>>7)&0x1ff
#define GETACT(st)      (st>>7)&0x1ff
 
 
/* character classes */
/* character classes */
#define C_WS    1
#define C_WS    1
#define C_ALPH  2
#define C_ALPH  2
#define C_NUM   3
#define C_NUM   3
#define C_EOF   4
#define C_EOF   4
#define C_XX    5
#define C_XX    5
 
 
enum state {
enum state {
        START=0, NUM1, NUM2, NUM3, ID1, ST1, ST2, ST3, COM1, COM2, COM3, COM4,
        START=0, NUM1, NUM2, NUM3, ID1, ST1, ST2, ST3, COM1, COM2, COM3, COM4,
        CC1, CC2, WS1, PLUS1, MINUS1, STAR1, SLASH1, PCT1, SHARP1,
        CC1, CC2, WS1, PLUS1, MINUS1, STAR1, SLASH1, PCT1, SHARP1,
        CIRC1, GT1, GT2, LT1, LT2, OR1, AND1, ASG1, NOT1, DOTS1,
        CIRC1, GT1, GT2, LT1, LT2, OR1, AND1, ASG1, NOT1, DOTS1,
        S_SELF=MAXSTATE, S_SELFB, S_EOF, S_NL, S_EOFSTR,
        S_SELF=MAXSTATE, S_SELFB, S_EOF, S_NL, S_EOFSTR,
        S_STNL, S_COMNL, S_EOFCOM, S_COMMENT, S_EOB, S_WS, S_NAME
        S_STNL, S_COMNL, S_EOFCOM, S_COMMENT, S_EOB, S_WS, S_NAME
};
};
 
 
int     tottok;
int     tottok;
int     tokkind[256];
int     tokkind[256];
struct  fsm {
struct  fsm {
        int     state;          /* if in this state */
        int     state;          /* if in this state */
        uchar   ch[4];          /* and see one of these characters */
        uchar   ch[4];          /* and see one of these characters */
        int     nextstate;      /* enter this state if +ve */
        int     nextstate;      /* enter this state if +ve */
};
};
 
 
/*const*/ struct fsm fsm[] = {
/*const*/ struct fsm fsm[] = {
        /* start state */
        /* start state */
        START,  { C_XX },       ACT(UNCLASS,S_SELF),
        START,  { C_XX },       ACT(UNCLASS,S_SELF),
        START,  { ' ', '\t', '\v' },    WS1,
        START,  { ' ', '\t', '\v' },    WS1,
        START,  { C_NUM },      NUM1,
        START,  { C_NUM },      NUM1,
        START,  { '.' },        NUM3,
        START,  { '.' },        NUM3,
        START,  { C_ALPH },     ID1,
        START,  { C_ALPH },     ID1,
        START,  { 'L' },        ST1,
        START,  { 'L' },        ST1,
        START,  { '"' },        ST2,
        START,  { '"' },        ST2,
        START,  { '\'' },       CC1,
        START,  { '\'' },       CC1,
        START,  { '/' },        COM1,
        START,  { '/' },        COM1,
        START,  { EOFC },       S_EOF,
        START,  { EOFC },       S_EOF,
        START,  { '\n' },       S_NL,
        START,  { '\n' },       S_NL,
        START,  { '-' },        MINUS1,
        START,  { '-' },        MINUS1,
        START,  { '+' },        PLUS1,
        START,  { '+' },        PLUS1,
        START,  { '<' },        LT1,
        START,  { '<' },        LT1,
        START,  { '>' },        GT1,
        START,  { '>' },        GT1,
        START,  { '=' },        ASG1,
        START,  { '=' },        ASG1,
        START,  { '!' },        NOT1,
        START,  { '!' },        NOT1,
        START,  { '&' },        AND1,
        START,  { '&' },        AND1,
        START,  { '|' },        OR1,
        START,  { '|' },        OR1,
        START,  { '#' },        SHARP1,
        START,  { '#' },        SHARP1,
        START,  { '%' },        PCT1,
        START,  { '%' },        PCT1,
        START,  { '[' },        ACT(SBRA,S_SELF),
        START,  { '[' },        ACT(SBRA,S_SELF),
        START,  { ']' },        ACT(SKET,S_SELF),
        START,  { ']' },        ACT(SKET,S_SELF),
        START,  { '(' },        ACT(LP,S_SELF),
        START,  { '(' },        ACT(LP,S_SELF),
        START,  { ')' },        ACT(RP,S_SELF),
        START,  { ')' },        ACT(RP,S_SELF),
        START,  { '*' },        STAR1,
        START,  { '*' },        STAR1,
        START,  { ',' },        ACT(COMMA,S_SELF),
        START,  { ',' },        ACT(COMMA,S_SELF),
        START,  { '?' },        ACT(QUEST,S_SELF),
        START,  { '?' },        ACT(QUEST,S_SELF),
        START,  { ':' },        ACT(COLON,S_SELF),
        START,  { ':' },        ACT(COLON,S_SELF),
        START,  { ';' },        ACT(SEMIC,S_SELF),
        START,  { ';' },        ACT(SEMIC,S_SELF),
        START,  { '{' },        ACT(CBRA,S_SELF),
        START,  { '{' },        ACT(CBRA,S_SELF),
        START,  { '}' },        ACT(CKET,S_SELF),
        START,  { '}' },        ACT(CKET,S_SELF),
        START,  { '~' },        ACT(TILDE,S_SELF),
        START,  { '~' },        ACT(TILDE,S_SELF),
        START,  { '^' },        CIRC1,
        START,  { '^' },        CIRC1,
 
 
        /* saw a digit */
        /* saw a digit */
        NUM1,   { C_XX },       ACT(NUMBER,S_SELFB),
        NUM1,   { C_XX },       ACT(NUMBER,S_SELFB),
        NUM1,   { C_NUM, C_ALPH, '.' }, NUM1,
        NUM1,   { C_NUM, C_ALPH, '.' }, NUM1,
        NUM1,   { 'E', 'e' },   NUM2,
        NUM1,   { 'E', 'e' },   NUM2,
        NUM1,   { '_' },        ACT(NUMBER,S_SELFB),
        NUM1,   { '_' },        ACT(NUMBER,S_SELFB),
 
 
        /* saw possible start of exponent, digits-e */
        /* saw possible start of exponent, digits-e */
        NUM2,   { C_XX },       ACT(NUMBER,S_SELFB),
        NUM2,   { C_XX },       ACT(NUMBER,S_SELFB),
        NUM2,   { '+', '-' },   NUM1,
        NUM2,   { '+', '-' },   NUM1,
        NUM2,   { C_NUM, C_ALPH },      NUM1,
        NUM2,   { C_NUM, C_ALPH },      NUM1,
        NUM2,   { '_' },        ACT(NUMBER,S_SELFB),
        NUM2,   { '_' },        ACT(NUMBER,S_SELFB),
 
 
        /* saw a '.', which could be a number or an operator */
        /* saw a '.', which could be a number or an operator */
        NUM3,   { C_XX },       ACT(DOT,S_SELFB),
        NUM3,   { C_XX },       ACT(DOT,S_SELFB),
        NUM3,   { '.' },        DOTS1,
        NUM3,   { '.' },        DOTS1,
        NUM3,   { C_NUM },      NUM1,
        NUM3,   { C_NUM },      NUM1,
 
 
        DOTS1,  { C_XX },       ACT(UNCLASS, S_SELFB),
        DOTS1,  { C_XX },       ACT(UNCLASS, S_SELFB),
        DOTS1,  { C_NUM },      NUM1,
        DOTS1,  { C_NUM },      NUM1,
        DOTS1,  { '.' },        ACT(ELLIPS, S_SELF),
        DOTS1,  { '.' },        ACT(ELLIPS, S_SELF),
 
 
        /* saw a letter or _ */
        /* saw a letter or _ */
        ID1,    { C_XX },       ACT(NAME,S_NAME),
        ID1,    { C_XX },       ACT(NAME,S_NAME),
        ID1,    { C_ALPH, C_NUM },      ID1,
        ID1,    { C_ALPH, C_NUM },      ID1,
 
 
        /* saw L (start of wide string?) */
        /* saw L (start of wide string?) */
        ST1,    { C_XX },       ACT(NAME,S_NAME),
        ST1,    { C_XX },       ACT(NAME,S_NAME),
        ST1,    { C_ALPH, C_NUM },      ID1,
        ST1,    { C_ALPH, C_NUM },      ID1,
        ST1,    { '"' },        ST2,
        ST1,    { '"' },        ST2,
        ST1,    { '\'' },       CC1,
        ST1,    { '\'' },       CC1,
 
 
        /* saw " beginning string */
        /* saw " beginning string */
        ST2,    { C_XX },       ST2,
        ST2,    { C_XX },       ST2,
        ST2,    { '"' },        ACT(STRING, S_SELF),
        ST2,    { '"' },        ACT(STRING, S_SELF),
        ST2,    { '\\' },       ST3,
        ST2,    { '\\' },       ST3,
        ST2,    { '\n' },       S_STNL,
        ST2,    { '\n' },       S_STNL,
        ST2,    { EOFC },       S_EOFSTR,
        ST2,    { EOFC },       S_EOFSTR,
 
 
        /* saw \ in string */
        /* saw \ in string */
        ST3,    { C_XX },       ST2,
        ST3,    { C_XX },       ST2,
        ST3,    { '\n' },       S_STNL,
        ST3,    { '\n' },       S_STNL,
        ST3,    { EOFC },       S_EOFSTR,
        ST3,    { EOFC },       S_EOFSTR,
 
 
        /* saw ' beginning character const */
        /* saw ' beginning character const */
        CC1,    { C_XX },       CC1,
        CC1,    { C_XX },       CC1,
        CC1,    { '\'' },       ACT(CCON, S_SELF),
        CC1,    { '\'' },       ACT(CCON, S_SELF),
        CC1,    { '\\' },       CC2,
        CC1,    { '\\' },       CC2,
        CC1,    { '\n' },       S_STNL,
        CC1,    { '\n' },       S_STNL,
        CC1,    { EOFC },       S_EOFSTR,
        CC1,    { EOFC },       S_EOFSTR,
 
 
        /* saw \ in ccon */
        /* saw \ in ccon */
        CC2,    { C_XX },       CC1,
        CC2,    { C_XX },       CC1,
        CC2,    { '\n' },       S_STNL,
        CC2,    { '\n' },       S_STNL,
        CC2,    { EOFC },       S_EOFSTR,
        CC2,    { EOFC },       S_EOFSTR,
 
 
        /* saw /, perhaps start of comment */
        /* saw /, perhaps start of comment */
        COM1,   { C_XX },       ACT(SLASH, S_SELFB),
        COM1,   { C_XX },       ACT(SLASH, S_SELFB),
        COM1,   { '=' },        ACT(ASSLASH, S_SELF),
        COM1,   { '=' },        ACT(ASSLASH, S_SELF),
        COM1,   { '*' },        COM2,
        COM1,   { '*' },        COM2,
        COM1,   { '/' },        COM4,
        COM1,   { '/' },        COM4,
 
 
        /* saw / then *, start of comment */
        /* saw / then *, start of comment */
        COM2,   { C_XX },       COM2,
        COM2,   { C_XX },       COM2,
        COM2,   { '\n' },       S_COMNL,
        COM2,   { '\n' },       S_COMNL,
        COM2,   { '*' },        COM3,
        COM2,   { '*' },        COM3,
        COM2,   { EOFC },       S_EOFCOM,
        COM2,   { EOFC },       S_EOFCOM,
 
 
        /* saw the * possibly ending a comment */
        /* saw the * possibly ending a comment */
        COM3,   { C_XX },       COM2,
        COM3,   { C_XX },       COM2,
        COM3,   { '\n' },       S_COMNL,
        COM3,   { '\n' },       S_COMNL,
        COM3,   { '*' },        COM3,
        COM3,   { '*' },        COM3,
        COM3,   { '/' },        S_COMMENT,
        COM3,   { '/' },        S_COMMENT,
 
 
        /* // comment */
        /* // comment */
        COM4,   { C_XX },       COM4,
        COM4,   { C_XX },       COM4,
        COM4,   { '\n' },       S_NL,
        COM4,   { '\n' },       S_NL,
        COM4,   { EOFC },       S_EOFCOM,
        COM4,   { EOFC },       S_EOFCOM,
 
 
        /* saw white space, eat it up */
        /* saw white space, eat it up */
        WS1,    { C_XX },       S_WS,
        WS1,    { C_XX },       S_WS,
        WS1,    { ' ', '\t', '\v' },    WS1,
        WS1,    { ' ', '\t', '\v' },    WS1,
 
 
        /* saw -, check --, -=, -> */
        /* saw -, check --, -=, -> */
        MINUS1, { C_XX },       ACT(MINUS, S_SELFB),
        MINUS1, { C_XX },       ACT(MINUS, S_SELFB),
        MINUS1, { '-' },        ACT(MMINUS, S_SELF),
        MINUS1, { '-' },        ACT(MMINUS, S_SELF),
        MINUS1, { '=' },        ACT(ASMINUS,S_SELF),
        MINUS1, { '=' },        ACT(ASMINUS,S_SELF),
        MINUS1, { '>' },        ACT(ARROW,S_SELF),
        MINUS1, { '>' },        ACT(ARROW,S_SELF),
 
 
        /* saw +, check ++, += */
        /* saw +, check ++, += */
        PLUS1,  { C_XX },       ACT(PLUS, S_SELFB),
        PLUS1,  { C_XX },       ACT(PLUS, S_SELFB),
        PLUS1,  { '+' },        ACT(PPLUS, S_SELF),
        PLUS1,  { '+' },        ACT(PPLUS, S_SELF),
        PLUS1,  { '=' },        ACT(ASPLUS, S_SELF),
        PLUS1,  { '=' },        ACT(ASPLUS, S_SELF),
 
 
        /* saw <, check <<, <<=, <= */
        /* saw <, check <<, <<=, <= */
        LT1,    { C_XX },       ACT(LT, S_SELFB),
        LT1,    { C_XX },       ACT(LT, S_SELFB),
        LT1,    { '<' },        LT2,
        LT1,    { '<' },        LT2,
        LT1,    { '=' },        ACT(LEQ, S_SELF),
        LT1,    { '=' },        ACT(LEQ, S_SELF),
        LT2,    { C_XX },       ACT(LSH, S_SELFB),
        LT2,    { C_XX },       ACT(LSH, S_SELFB),
        LT2,    { '=' },        ACT(ASLSH, S_SELF),
        LT2,    { '=' },        ACT(ASLSH, S_SELF),
 
 
        /* saw >, check >>, >>=, >= */
        /* saw >, check >>, >>=, >= */
        GT1,    { C_XX },       ACT(GT, S_SELFB),
        GT1,    { C_XX },       ACT(GT, S_SELFB),
        GT1,    { '>' },        GT2,
        GT1,    { '>' },        GT2,
        GT1,    { '=' },        ACT(GEQ, S_SELF),
        GT1,    { '=' },        ACT(GEQ, S_SELF),
        GT2,    { C_XX },       ACT(RSH, S_SELFB),
        GT2,    { C_XX },       ACT(RSH, S_SELFB),
        GT2,    { '=' },        ACT(ASRSH, S_SELF),
        GT2,    { '=' },        ACT(ASRSH, S_SELF),
 
 
        /* = */
        /* = */
        ASG1,   { C_XX },       ACT(ASGN, S_SELFB),
        ASG1,   { C_XX },       ACT(ASGN, S_SELFB),
        ASG1,   { '=' },        ACT(EQ, S_SELF),
        ASG1,   { '=' },        ACT(EQ, S_SELF),
 
 
        /* ! */
        /* ! */
        NOT1,   { C_XX },       ACT(NOT, S_SELFB),
        NOT1,   { C_XX },       ACT(NOT, S_SELFB),
        NOT1,   { '=' },        ACT(NEQ, S_SELF),
        NOT1,   { '=' },        ACT(NEQ, S_SELF),
 
 
        /* & */
        /* & */
        AND1,   { C_XX },       ACT(AND, S_SELFB),
        AND1,   { C_XX },       ACT(AND, S_SELFB),
        AND1,   { '&' },        ACT(LAND, S_SELF),
        AND1,   { '&' },        ACT(LAND, S_SELF),
        AND1,   { '=' },        ACT(ASAND, S_SELF),
        AND1,   { '=' },        ACT(ASAND, S_SELF),
 
 
        /* | */
        /* | */
        OR1,    { C_XX },       ACT(OR, S_SELFB),
        OR1,    { C_XX },       ACT(OR, S_SELFB),
        OR1,    { '|' },        ACT(LOR, S_SELF),
        OR1,    { '|' },        ACT(LOR, S_SELF),
        OR1,    { '=' },        ACT(ASOR, S_SELF),
        OR1,    { '=' },        ACT(ASOR, S_SELF),
 
 
        /* # */
        /* # */
        SHARP1, { C_XX },       ACT(SHARP, S_SELFB),
        SHARP1, { C_XX },       ACT(SHARP, S_SELFB),
        SHARP1, { '#' },        ACT(DSHARP, S_SELF),
        SHARP1, { '#' },        ACT(DSHARP, S_SELF),
 
 
        /* % */
        /* % */
        PCT1,   { C_XX },       ACT(PCT, S_SELFB),
        PCT1,   { C_XX },       ACT(PCT, S_SELFB),
        PCT1,   { '=' },        ACT(ASPCT, S_SELF),
        PCT1,   { '=' },        ACT(ASPCT, S_SELF),
 
 
        /* * */
        /* * */
        STAR1,  { C_XX },       ACT(STAR, S_SELFB),
        STAR1,  { C_XX },       ACT(STAR, S_SELFB),
        STAR1,  { '=' },        ACT(ASSTAR, S_SELF),
        STAR1,  { '=' },        ACT(ASSTAR, S_SELF),
 
 
        /* ^ */
        /* ^ */
        CIRC1,  { C_XX },       ACT(CIRC, S_SELFB),
        CIRC1,  { C_XX },       ACT(CIRC, S_SELFB),
        CIRC1,  { '=' },        ACT(ASCIRC, S_SELF),
        CIRC1,  { '=' },        ACT(ASCIRC, S_SELF),
 
 
        -1
        -1
};
};
 
 
/* first index is char, second is state */
/* first index is char, second is state */
/* increase #states to power of 2 to encourage use of shift */
/* increase #states to power of 2 to encourage use of shift */
short   bigfsm[256][MAXSTATE];
short   bigfsm[256][MAXSTATE];
 
 
void
void
expandlex(void)
expandlex(void)
{
{
        /*const*/ struct fsm *fp;
        /*const*/ struct fsm *fp;
        int i, j, nstate;
        int i, j, nstate;
 
 
        for (fp = fsm; fp->state>=0; fp++) {
        for (fp = fsm; fp->state>=0; fp++) {
                for (i=0; fp->ch[i]; i++) {
                for (i=0; fp->ch[i]; i++) {
                        nstate = fp->nextstate;
                        nstate = fp->nextstate;
                        if (nstate >= S_SELF)
                        if (nstate >= S_SELF)
                                nstate = ~nstate;
                                nstate = ~nstate;
                        switch (fp->ch[i]) {
                        switch (fp->ch[i]) {
 
 
                        case C_XX:              /* random characters */
                        case C_XX:              /* random characters */
                                for (j=0; j<256; j++)
                                for (j=0; j<256; j++)
                                        bigfsm[j][fp->state] = nstate;
                                        bigfsm[j][fp->state] = nstate;
                                continue;
                                continue;
                        case C_ALPH:
                        case C_ALPH:
                                for (j=0; j<=256; j++)
                                for (j=0; j<=256; j++)
                                        if ('a'<=j&&j<='z' || 'A'<=j&&j<='Z'
                                        if ('a'<=j&&j<='z' || 'A'<=j&&j<='Z'
                                          || j=='_')
                                          || j=='_')
                                                bigfsm[j][fp->state] = nstate;
                                                bigfsm[j][fp->state] = nstate;
                                continue;
                                continue;
                        case C_NUM:
                        case C_NUM:
                                for (j='0'; j<='9'; j++)
                                for (j='0'; j<='9'; j++)
                                        bigfsm[j][fp->state] = nstate;
                                        bigfsm[j][fp->state] = nstate;
                                continue;
                                continue;
                        default:
                        default:
                                bigfsm[fp->ch[i]][fp->state] = nstate;
                                bigfsm[fp->ch[i]][fp->state] = nstate;
                        }
                        }
                }
                }
        }
        }
        /* install special cases for ? (trigraphs),  \ (splicing), runes, and EOB */
        /* install special cases for ? (trigraphs),  \ (splicing), runes, and EOB */
        for (i=0; i<MAXSTATE; i++) {
        for (i=0; i<MAXSTATE; i++) {
                for (j=0; j<0xFF; j++)
                for (j=0; j<0xFF; j++)
                        if (j=='?' || j=='\\') {
                        if (j=='?' || j=='\\') {
                                if (bigfsm[j][i]>0)
                                if (bigfsm[j][i]>0)
                                        bigfsm[j][i] = ~bigfsm[j][i];
                                        bigfsm[j][i] = ~bigfsm[j][i];
                                bigfsm[j][i] &= ~QBSBIT;
                                bigfsm[j][i] &= ~QBSBIT;
                        }
                        }
                bigfsm[EOB][i] = ~S_EOB;
                bigfsm[EOB][i] = ~S_EOB;
                if (bigfsm[EOFC][i]>=0)
                if (bigfsm[EOFC][i]>=0)
                        bigfsm[EOFC][i] = ~S_EOF;
                        bigfsm[EOFC][i] = ~S_EOF;
        }
        }
}
}
 
 
void
void
fixlex(void)
fixlex(void)
{
{
        /* do C++ comments? */
        /* do C++ comments? */
        if (Cplusplus==0)
        if (Cplusplus==0)
                bigfsm['/'][COM1] = bigfsm['x'][COM1];
                bigfsm['/'][COM1] = bigfsm['x'][COM1];
}
}
 
 
/*
/*
 * fill in a row of tokens from input, terminated by NL or END
 * fill in a row of tokens from input, terminated by NL or END
 * First token is put at trp->lp.
 * First token is put at trp->lp.
 * Reset is non-zero when the input buffer can be "rewound."
 * Reset is non-zero when the input buffer can be "rewound."
 * The value is a flag indicating that possible macros have
 * The value is a flag indicating that possible macros have
 * been seen in the row.
 * been seen in the row.
 */
 */
int
int
gettokens(Tokenrow *trp, int reset)
gettokens(Tokenrow *trp, int reset)
{
{
        register int c, state, oldstate;
        register int c, state, oldstate;
        register uchar *ip;
        register uchar *ip;
        register Token *tp, *maxp;
        register Token *tp, *maxp;
        int runelen;
        int runelen;
        Source *s = cursource;
        Source *s = cursource;
        int nmac = 0;
        int nmac = 0;
        extern char outbuf[];
        extern char outbuf[];
 
 
        tp = trp->lp;
        tp = trp->lp;
        ip = s->inp;
        ip = s->inp;
        if (reset) {
        if (reset) {
                s->lineinc = 0;
                s->lineinc = 0;
                if (ip>=s->inl) {               /* nothing in buffer */
                if (ip>=s->inl) {               /* nothing in buffer */
                        s->inl = s->inb;
                        s->inl = s->inb;
                        fillbuf(s);
                        fillbuf(s);
                        ip = s->inp = s->inb;
                        ip = s->inp = s->inb;
                } else if (ip >= s->inb+(3*INS/4)) {
                } else if (ip >= s->inb+(3*INS/4)) {
                        memmove(s->inb, ip, 4+s->inl-ip);
                        memmove(s->inb, ip, 4+s->inl-ip);
                        s->inl = s->inb+(s->inl-ip);
                        s->inl = s->inb+(s->inl-ip);
                        ip = s->inp = s->inb;
                        ip = s->inp = s->inb;
                }
                }
        }
        }
        maxp = &trp->bp[trp->max];
        maxp = &trp->bp[trp->max];
        runelen = 1;
        runelen = 1;
        for (;;) {
        for (;;) {
           continue2:
           continue2:
                if (tp>=maxp) {
                if (tp>=maxp) {
                        trp->lp = tp;
                        trp->lp = tp;
                        tp = growtokenrow(trp);
                        tp = growtokenrow(trp);
                        maxp = &trp->bp[trp->max];
                        maxp = &trp->bp[trp->max];
                }
                }
                tp->type = UNCLASS;
                tp->type = UNCLASS;
                tp->hideset = 0;
                tp->hideset = 0;
                tp->t = ip;
                tp->t = ip;
                tp->wslen = 0;
                tp->wslen = 0;
                tp->flag = 0;
                tp->flag = 0;
                state = START;
                state = START;
                for (;;) {
                for (;;) {
                        oldstate = state;
                        oldstate = state;
                        c = *ip;
                        c = *ip;
                        if ((state = bigfsm[c][state]) >= 0) {
                        if ((state = bigfsm[c][state]) >= 0) {
                                ip += runelen;
                                ip += runelen;
                                runelen = 1;
                                runelen = 1;
                                continue;
                                continue;
                        }
                        }
                        state = ~state;
                        state = ~state;
                reswitch:
                reswitch:
                        switch (state&0177) {
                        switch (state&0177) {
                        case S_SELF:
                        case S_SELF:
                                ip += runelen;
                                ip += runelen;
                                runelen = 1;
                                runelen = 1;
                        case S_SELFB:
                        case S_SELFB:
                                tp->type = GETACT(state);
                                tp->type = GETACT(state);
                                tp->len = ip - tp->t;
                                tp->len = ip - tp->t;
                                tp++;
                                tp++;
                                goto continue2;
                                goto continue2;
 
 
                        case S_NAME:    /* like S_SELFB but with nmac check */
                        case S_NAME:    /* like S_SELFB but with nmac check */
                                tp->type = NAME;
                                tp->type = NAME;
                                tp->len = ip - tp->t;
                                tp->len = ip - tp->t;
                                nmac |= quicklook(tp->t[0], tp->len>1?tp->t[1]:0);
                                nmac |= quicklook(tp->t[0], tp->len>1?tp->t[1]:0);
                                tp++;
                                tp++;
                                goto continue2;
                                goto continue2;
 
 
                        case S_WS:
                        case S_WS:
                                tp->wslen = ip - tp->t;
                                tp->wslen = ip - tp->t;
                                tp->t = ip;
                                tp->t = ip;
                                state = START;
                                state = START;
                                continue;
                                continue;
 
 
                        default:
                        default:
                                if ((state&QBSBIT)==0) {
                                if ((state&QBSBIT)==0) {
                                        ip += runelen;
                                        ip += runelen;
                                        runelen = 1;
                                        runelen = 1;
                                        continue;
                                        continue;
                                }
                                }
                                state &= ~QBSBIT;
                                state &= ~QBSBIT;
                                s->inp = ip;
                                s->inp = ip;
                                if (c=='?') {   /* check trigraph */
                                if (c=='?') {   /* check trigraph */
                                        if (trigraph(s)) {
                                        if (trigraph(s)) {
                                                state = oldstate;
                                                state = oldstate;
                                                continue;
                                                continue;
                                        }
                                        }
                                        goto reswitch;
                                        goto reswitch;
                                }
                                }
                                if (c=='\\') { /* line-folding */
                                if (c=='\\') { /* line-folding */
                                        if (foldline(s)) {
                                        if (foldline(s)) {
                                                s->lineinc++;
                                                s->lineinc++;
                                                state = oldstate;
                                                state = oldstate;
                                                continue;
                                                continue;
                                        }
                                        }
                                        goto reswitch;
                                        goto reswitch;
                                }
                                }
                                error(WARNING, "Lexical botch in cpp");
                                error(WARNING, "Lexical botch in cpp");
                                ip += runelen;
                                ip += runelen;
                                runelen = 1;
                                runelen = 1;
                                continue;
                                continue;
 
 
                        case S_EOB:
                        case S_EOB:
                                s->inp = ip;
                                s->inp = ip;
                                fillbuf(cursource);
                                fillbuf(cursource);
                                state = oldstate;
                                state = oldstate;
                                continue;
                                continue;
 
 
                        case S_EOF:
                        case S_EOF:
                                tp->type = END;
                                tp->type = END;
                                tp->len = 0;
                                tp->len = 0;
                                s->inp = ip;
                                s->inp = ip;
                                if (tp!=trp->bp && (tp-1)->type!=NL && cursource->fd!=NULL)
                                if (tp!=trp->bp && (tp-1)->type!=NL && cursource->fd!=NULL)
                                        error(WARNING,"No newline at end of file");
                                        error(WARNING,"No newline at end of file");
                                trp->lp = tp+1;
                                trp->lp = tp+1;
                                return nmac;
                                return nmac;
 
 
                        case S_STNL:
                        case S_STNL:
                                error(ERROR, "Unterminated string or char const");
                                error(ERROR, "Unterminated string or char const");
                        case S_NL:
                        case S_NL:
                                tp->t = ip;
                                tp->t = ip;
                                tp->type = NL;
                                tp->type = NL;
                                tp->len = 1;
                                tp->len = 1;
                                tp->wslen = 0;
                                tp->wslen = 0;
                                s->lineinc++;
                                s->lineinc++;
                                s->inp = ip+1;
                                s->inp = ip+1;
                                trp->lp = tp+1;
                                trp->lp = tp+1;
                                return nmac;
                                return nmac;
 
 
                        case S_EOFSTR:
                        case S_EOFSTR:
                                error(FATAL, "EOF in string or char constant");
                                error(FATAL, "EOF in string or char constant");
                                break;
                                break;
 
 
                        case S_COMNL:
                        case S_COMNL:
                                s->lineinc++;
                                s->lineinc++;
                                state = COM2;
                                state = COM2;
                                ip += runelen;
                                ip += runelen;
                                runelen = 1;
                                runelen = 1;
                                if (ip >= s->inb+(7*INS/8)) { /* very long comment */
                                if (ip >= s->inb+(7*INS/8)) { /* very long comment */
                                        memmove(tp->t, ip, 4+s->inl-ip);
                                        memmove(tp->t, ip, 4+s->inl-ip);
                                        s->inl -= ip-tp->t;
                                        s->inl -= ip-tp->t;
                                        ip = tp->t+1;
                                        ip = tp->t+1;
                                }
                                }
                                continue;
                                continue;
 
 
                        case S_EOFCOM:
                        case S_EOFCOM:
                                error(WARNING, "EOF inside comment");
                                error(WARNING, "EOF inside comment");
                                --ip;
                                --ip;
                        case S_COMMENT:
                        case S_COMMENT:
                                ++ip;
                                ++ip;
                                tp->t = ip;
                                tp->t = ip;
                                tp->t[-1] = ' ';
                                tp->t[-1] = ' ';
                                tp->wslen = 1;
                                tp->wslen = 1;
                                state = START;
                                state = START;
                                continue;
                                continue;
                        }
                        }
                        break;
                        break;
                }
                }
                ip += runelen;
                ip += runelen;
                runelen = 1;
                runelen = 1;
                tp->len = ip - tp->t;
                tp->len = ip - tp->t;
                tp++;
                tp++;
        }
        }
}
}
 
 
/* have seen ?; handle the trigraph it starts (if any) else 0 */
/* have seen ?; handle the trigraph it starts (if any) else 0 */
int
int
trigraph(Source *s)
trigraph(Source *s)
{
{
        int c;
        int c;
 
 
        while (s->inp+2 >= s->inl && fillbuf(s)!=EOF)
        while (s->inp+2 >= s->inl && fillbuf(s)!=EOF)
                ;
                ;
        if (s->inp[1]!='?')
        if (s->inp[1]!='?')
                return 0;
                return 0;
        c = 0;
        c = 0;
        switch(s->inp[2]) {
        switch(s->inp[2]) {
        case '=':
        case '=':
                c = '#'; break;
                c = '#'; break;
        case '(':
        case '(':
                c = '['; break;
                c = '['; break;
        case '/':
        case '/':
                c = '\\'; break;
                c = '\\'; break;
        case ')':
        case ')':
                c = ']'; break;
                c = ']'; break;
        case '\'':
        case '\'':
                c = '^'; break;
                c = '^'; break;
        case '<':
        case '<':
                c = '{'; break;
                c = '{'; break;
        case '!':
        case '!':
                c = '|'; break;
                c = '|'; break;
        case '>':
        case '>':
                c = '}'; break;
                c = '}'; break;
        case '-':
        case '-':
                c = '~'; break;
                c = '~'; break;
        }
        }
        if (c) {
        if (c) {
                *s->inp = c;
                *s->inp = c;
                memmove(s->inp+1, s->inp+3, s->inl-s->inp+2);
                memmove(s->inp+1, s->inp+3, s->inl-s->inp+2);
                s->inl -= 2;
                s->inl -= 2;
        }
        }
        return c;
        return c;
}
}
 
 
int
int
foldline(Source *s)
foldline(Source *s)
{
{
        while (s->inp+1 >= s->inl && fillbuf(s)!=EOF)
        while (s->inp+1 >= s->inl && fillbuf(s)!=EOF)
                ;
                ;
        if (s->inp[1] == '\n') {
        if (s->inp[1] == '\n') {
                memmove(s->inp, s->inp+2, s->inl-s->inp+3);
                memmove(s->inp, s->inp+2, s->inl-s->inp+3);
                s->inl -= 2;
                s->inl -= 2;
                return 1;
                return 1;
        }
        }
        return 0;
        return 0;
}
}
 
 
int
int
fillbuf(Source *s)
fillbuf(Source *s)
{
{
        int n, nr;
        int n, nr;
 
 
        nr = INS/8;
        nr = INS/8;
        if ((char *)s->inl+nr > (char *)s->inb+INS)
        if ((char *)s->inl+nr > (char *)s->inb+INS)
                error(FATAL, "Input buffer overflow");
                error(FATAL, "Input buffer overflow");
        if (s->fd==NULL || (n=fread((char *)s->inl, 1, INS/8, s->fd)) <= 0)
        if (s->fd==NULL || (n=fread((char *)s->inl, 1, INS/8, s->fd)) <= 0)
                n = 0;
                n = 0;
        if ((*s->inp&0xff) == EOB) /* sentinel character appears in input */
        if ((*s->inp&0xff) == EOB) /* sentinel character appears in input */
                *s->inp = EOFC;
                *s->inp = EOFC;
        s->inl += n;
        s->inl += n;
        s->inl[0] = s->inl[1]= s->inl[2]= s->inl[3] = EOB;
        s->inl[0] = s->inl[1]= s->inl[2]= s->inl[3] = EOB;
        if (n==0) {
        if (n==0) {
                s->inl[0] = s->inl[1]= s->inl[2]= s->inl[3] = EOFC;
                s->inl[0] = s->inl[1]= s->inl[2]= s->inl[3] = EOFC;
                return EOF;
                return EOF;
        }
        }
        return 0;
        return 0;
}
}
 
 
/*
/*
 * Push down to new source of characters.
 * Push down to new source of characters.
 * If fd!=NULL and str==NULL, then from a file `name';
 * If fd!=NULL and str==NULL, then from a file `name';
 * if fd==NULL and str, then from the string.
 * if fd==NULL and str, then from the string.
 */
 */
Source *
Source *
setsource(char *name, FILE *fd, char *str)
setsource(char *name, FILE *fd, char *str)
{
{
        Source *s = new(Source);
        Source *s = new(Source);
        int len;
        int len;
 
 
        s->line = 1;
        s->line = 1;
        s->lineinc = 0;
        s->lineinc = 0;
        s->fd = fd;
        s->fd = fd;
        s->filename = name;
        s->filename = name;
        s->next = cursource;
        s->next = cursource;
        s->ifdepth = 0;
        s->ifdepth = 0;
        cursource = s;
        cursource = s;
        /* slop at right for EOB */
        /* slop at right for EOB */
        if (str) {
        if (str) {
                len = strlen(str);
                len = strlen(str);
                s->inb = domalloc(len+4);
                s->inb = domalloc(len+4);
                s->inp = s->inb;
                s->inp = s->inb;
                strncpy((char *)s->inp, str, len);
                strncpy((char *)s->inp, str, len);
        } else {
        } else {
                s->inb = domalloc(INS+4);
                s->inb = domalloc(INS+4);
                s->inp = s->inb;
                s->inp = s->inb;
                len = 0;
                len = 0;
        }
        }
        s->inl = s->inp+len;
        s->inl = s->inp+len;
        s->inl[0] = s->inl[1] = EOB;
        s->inl[0] = s->inl[1] = EOB;
        return s;
        return s;
}
}
 
 
void
void
unsetsource(void)
unsetsource(void)
{
{
        Source *s = cursource;
        Source *s = cursource;
 
 
        if (s->fd != NULL) {
        if (s->fd != NULL) {
                fclose(s->fd);
                fclose(s->fd);
                dofree(s->inb);
                dofree(s->inb);
        }
        }
        cursource = s->next;
        cursource = s->next;
        dofree(s);
        dofree(s);
}
}
 
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.