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

Subversion Repositories c16

[/] [c16/] [trunk/] [compiler/] [ansic.flex] - Rev 31

Go to most recent revision | Compare with Previous | Blame | View Log


D                       [0-9]
L                       [a-zA-Z_]
NQ                      [\x20-\x21\x23-\x5B\x5D-\x7E]
H                       [a-fA-F0-9]
E                       [Ee][+-]?{D}+
FS                      (f|F|l|L)
IS                      (u|U|l|L)*

%x com
%x strg

%{
#include <stdio.h>
#include "Node.hh"
#include "Name.hh"
#include "ansic_bison.hh"

extern FILE * out;

void count();
int check_type();
int StringConstant::str_count = 0;
StringConstant * StringConstant::
                 all_strings[StringConstant::MAX_STRINGS] = { 0 };

%}

%%
"//".*                  { count(); }
"/*"                    { count(); BEGIN(com); }
<com>"*/"               { count(); BEGIN(0);   }
<com>\r                 { count();    }
<com>\n                 { count();    }
<com>.                  { count();    }

"ASM"                   { count(); return(ASM); }
"auto"                  { count(); return(AUTO); }
"break"                 { count(); return(BREAK); }
"case"                  { count(); return(CASE); }
"char"                  { count(); return(CHAR); }
"const"                 { count(); return(CONST); }
"continue"              { count(); return(CONTINUE); }
"default"               { count(); return(DEFAULT); }
"do"                    { count(); return(DO); }
"double"                { count(); return(DOUBLE); }
"else"                  { count(); return(ELSE); }
"enum"                  { count(); return(ENUM); }
"extern"                { count(); return(EXTERN); }
"float"                 { count(); return(FLOAT); }
"for"                   { count(); return(FOR); }
"goto"                  { count(); return(GOTO); }
"if"                    { count(); return(IF); }
"int"                   { count(); return(INT); }
"long"                  { count(); return(LONG); }
"register"              { count(); return(REGISTER); }
"return"                { count(); return(RETURN); }
"short"                 { count(); return(SHORT); }
"signed"                { count(); return(SIGNED); }
"sizeof"                { count(); return(SIZEOF); }
"static"                { count(); return(STATIC); }
"struct"                { count(); return(STRUCT); }
"switch"                { count(); return(SWITCH); }
"typedef"               { count(); return(TYPEDEF); }
"union"                 { count(); return(UNION); }
"unsigned"              { count(); return(UNSIGNED); }
"void"                  { count(); return(VOID); }
"volatile"              { count(); return(VOLATILE); }
"while"                 { count(); return(WHILE); }

{L}({L}|{D})*           { count(); yylval._name = new char[strlen(yytext)+1];
                          strcpy((char *)(yylval._name), yytext);
                                   return(check_type()); }

0[xX]{H}+{IS}?          { count(); yylval._num = new NumericConstant(yytext);
                                   return(CONSTANT); }
0{D}+{IS}?              { count(); yylval._num = new NumericConstant(yytext);
                                   return(CONSTANT); }
{D}+{IS}?               { count(); yylval._num = new NumericConstant(yytext);
                                   return(CONSTANT); }
L?'(\\.|[^\\'])+'       { count(); yylval._num = new NumericConstant(yytext);
                                   return(CONSTANT); }
{D}+{E}{FS}?            { count(); yylval._num = 0;   /* TODO */
                                   return(CONSTANT); }
{D}*"."{D}+({E})?{FS}?  { count(); yylval._num = 0;   /* TODO */
                                   return(CONSTANT); }
{D}+"."{D}*({E})?{FS}?  { count(); yylval._num = 0;   /* TODO */
                                   return(CONSTANT); }

L?\"                    { count();   BEGIN(strg);
                          yylval._string_constant = new StringConstant(); }
<strg>\"                { count();   BEGIN(0);   return(STRING_LITERAL);  }
<strg>\\\"              { count();   *yylval._string_constant += '"';     }
<strg>\\a               { count();   *yylval._string_constant += '\a';    }
<strg>\\b               { count();   *yylval._string_constant += '\b';    }
<strg>\\f               { count();   *yylval._string_constant += '\f';    }
<strg>\\n               { count();   *yylval._string_constant += '\n';    }
<strg>\\r               { count();   *yylval._string_constant += '\r';    }
<strg>\\t               { count();   *yylval._string_constant += '\t';    }
<strg>{NQ}              { count();   *yylval._string_constant += *yytext; }
<strg>\t                { count();   *yylval._string_constant += '\t';    }
<strg>\r                { count();                                        }
<strg>\n                { count();   *yylval._string_constant += '\n';    }
<strg>.                 { count();   *yylval._string_constant += *yytext; }

"..."                   { count(); return(ELLIPSIS); }
">>="                   { count(); return(RIGHT_ASSIGN); }
"<<="                   { count(); return(LEFT_ASSIGN); }
"+="                    { count(); return(ADD_ASSIGN); }
"-="                    { count(); return(SUB_ASSIGN); }
"*="                    { count(); return(MUL_ASSIGN); }
"/="                    { count(); return(DIV_ASSIGN); }
"%="                    { count(); return(MOD_ASSIGN); }
"&="                    { count(); return(AND_ASSIGN); }
"^="                    { count(); return(XOR_ASSIGN); }
"|="                    { count(); return(OR_ASSIGN); }
">>"                    { count(); return(RIGHT_OP); }
"<<"                    { count(); return(LEFT_OP); }
"++"                    { count(); return(INC_OP); }
"--"                    { count(); return(DEC_OP); }
"->"                    { count(); return(PTR_OP); }
"&&"                    { count(); return(AND_OP); }
"||"                    { count(); return(OR_OP); }
"<="                    { count(); return(LE_OP); }
">="                    { count(); return(GE_OP); }
"=="                    { count(); return(EQ_OP); }
"!="                    { count(); return(NE_OP); }
";"                     { count(); return(';'); }
("{"|"<%")              { count(); return('{'); }
("}"|"%>")              { count(); return('}'); }
","                     { count(); return(','); }
":"                     { count(); return(':'); }
"="                     { count(); return('='); }
"("                     { count(); return('('); }
")"                     { count(); return(')'); }
("["|"<:")              { count(); return('['); }
("]"|":>")              { count(); return(']'); }
"."                     { count(); return('.'); }
"&"                     { count(); return('&'); }
"!"                     { count(); return('!'); }
"~"                     { count(); return('~'); }
"-"                     { count(); return('-'); }
"+"                     { count(); return('+'); }
"*"                     { count(); return('*'); }
"/"                     { count(); return('/'); }
"%"                     { count(); return('%'); }
"<"                     { count(); return('<'); }
">"                     { count(); return('>'); }
"^"                     { count(); return('^'); }
"|"                     { count(); return('|'); }
"?"                     { count(); return('?'); }

[ \t\v\n\f]             { count(); }

<<EOF>>                 { return EOFILE; };
.                       { return ERROR ; };
%%

int yywrap()
{
        return(1);
}

int column = 0;
int row    = 1;

//-----------------------------------------------------------------------------
enum { QUOTE = '\'', BACKSLASH = '\\' };

NumericConstant::NumericConstant(const char * txt)
   : Constant("NumericConstant"),
     size(0)
{
   if (*txt == 'L')    txt++;
   if (*txt == QUOTE)   // TODO: make it proper
      {
        value = 0;
        for (txt++; *txt != QUOTE; txt++)
            {
              value <<= 8;
              int next_val = *txt;
              if (*txt == BACKSLASH)
                 {
                   txt++;   // skip backslash
                   next_val = *txt;
                   switch(*txt)
                      {
                        case 'a': next_val = '\a';   break;
                        case 'b': next_val = '\b';   break;
                        case 'f': next_val = '\f';   break;
                        case 'n': next_val = '\n';   break;
                        case 'r': next_val = '\r';   break;
                        case 't': next_val = '\t';   break;

                        case '0': // octal
                             {
                               int len;
                               int s = sscanf(txt, "%i%n", &next_val, &len);
                               assert(s == 2);
                               txt += len;
                             }
                             break;

                        case 'x': // hex
                             {
                               int len;
                               txt++;   // skip 'x'
                               int s = sscanf(txt, "%x%n", &next_val, &len);
                               assert(s == 2);
                               txt += len;
                             }
                             break;
                      }
                 }
              value |= 0x00FF & next_val;
            }
        return;
      }

   if (txt[1] == 'x' || txt[1] == 'X')
      {
        assert(*txt == '0');
        int cnt = sscanf(txt + 2, "%X", &value);
        assert(cnt == 1);
        return;
      }

   if (*txt == '0')
      {
        int cnt = sscanf(txt, "%o", &value);
        assert(cnt == 1);
        return;
      }

int cnt = sscanf(txt, "%d", &value);
   assert(cnt == 1);
}
//-----------------------------------------------------------------------------
StringConstant::StringConstant()
   : Constant("StringConstant"),
     buffer(new char[80]),
     buffer_len(80),
     string_number(str_count++),
     value_len(0)
{
   assert(buffer);
   *buffer = 0;
   if (string_number == 0)   // first string
      {
         for (int i = 0; i < MAX_STRINGS; i++)   all_strings[i] = 0;
      }

   all_strings[string_number] = this;
}
//-----------------------------------------------------------------------------
void StringConstant::EmitAll(FILE * out)
{
   for (int i = 0; i < MAX_STRINGS; i++)
       {
         StringConstant * sc = all_strings[i];
         if (sc == NULL)   continue;

         fprintf(out, "Cstr_%d:\t\t\t\t;\n", sc->string_number);
         for (int i = 0; i < sc->value_len; i++)
             fprintf(out, "\t.BYTE\t0x%2.2X\t\t\t;\n", sc->buffer[i]);

         fprintf(out, "\t.BYTE\t0\t\t\t;\n");
       }
}
//-----------------------------------------------------------------------------
void StringConstant::EmitAndRemove(FILE * out, int length)
{
   if (length < (value_len + 1))
      {
        fprintf(stderr,
                "Initialization string too long (length %d, size %d)\n",
                value_len + 1, length);
        semantic_errors++;
      }

   for (int b = 0; b < length; b++)
       {
         if (b > value_len)
             fprintf(out, "\t.BYTE\t0\t\t\t; [%d]\n", b);
         else
             fprintf(out, "\t.BYTE\t0x%2.2X\t\t\t; [%d]\n", buffer[b], b);
       }
   
   all_strings[string_number] = 0;
}
//-----------------------------------------------------------------------------
StringConstant::~StringConstant()
{
   delete buffer;

   assert(all_strings[string_number] == this);
   all_strings[string_number] = 0;
}
//-----------------------------------------------------------------------------
StringConstant * StringConstant::operator & (StringConstant * other)
{
   buffer_len = value_len + other->value_len;
char * cp = new char[buffer_len + 1];
   assert(cp);
   memcpy(cp, buffer, value_len);
   memcpy(cp + value_len, other->buffer, other->value_len);
   cp[buffer_len] = 0;
   value_len += other->value_len;

   delete buffer;
   buffer = cp;
   delete other;
   return this;
}
//-----------------------------------------------------------------------------
void StringConstant::operator += (char txt)
{
   if (value_len + 1 >= buffer_len)
      {
        assert(buffer);

        char * cp = new char[2*buffer_len];
        assert(cp);
        memcpy(cp, buffer, buffer_len);
        delete buffer;
        buffer = cp;
        buffer_len *= 2;
      }

   buffer[value_len++] = txt;
   buffer[value_len]   = 0;
}
//-----------------------------------------------------------------------------
void count()
{
   for (int i = 0; yytext[i]; i++)
       {
         if (yytext[i] == '\n')        { column = 0;   row++; }
         else if (yytext[i] == '\t')   column += 8 - (column % 8);
         else                          column++;
       }
}
//-----------------------------------------------------------------------------
int check_type()
{
   if (TypedefName::IsDefined(yytext))   return TYPE_NAME;
   return(IDENTIFIER);
}
//-----------------------------------------------------------------------------
int yyerror(const char *s)
{
   printf("\n%s Line %d Col %d\n", s, row, column);
   fflush(stdout);
}
//-----------------------------------------------------------------------------

Go to most recent revision | Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

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