Beispiel #1
0
Datei: llex.c Projekt: bcrist/lua
static int llex (LexState *ls, SemInfo *seminfo) {
  luaZ_resetbuffer(ls->buff);
  for (;;) {
    switch (ls->current) {
      case '\n': case '\r': {  /* line breaks */
        inclinenumber(ls);
        break;
      }
      case ' ': case '\f': case '\t': case '\v': {  /* spaces */
        next(ls);
        break;
      }
      case '-': {  /* '-' or '--' (comment) */
        next(ls);
        if (ls->current != '-') return '-';
        /* else is a comment */
        next(ls);
        if (ls->current == '[') {  /* long comment? */
          int sep = skip_sep(ls);
          luaZ_resetbuffer(ls->buff);  /* 'skip_sep' may dirty the buffer */
          if (sep >= 0) {
            read_long_string(ls, NULL, sep);  /* skip long comment */
            luaZ_resetbuffer(ls->buff);  /* previous call may dirty the buff. */
            break;
          }
        }
        /* else short comment */
        while (!currIsNewline(ls) && ls->current != EOZ)
          next(ls);  /* skip until end of line (or end of file) */
        break;
      }
      case '[': {  /* long string or simply '[' */
        int sep = skip_sep(ls);
        if (sep >= 0) {
          read_long_string(ls, seminfo, sep);
          return TK_STRING;
        }
        else if (sep != -1)  /* '[=...' missing second bracket */
          lexerror(ls, "invalid long string delimiter", TK_STRING);
        return '[';
      }
      case '=': {
        next(ls);
        if (check_next1(ls, '=')) return TK_EQ;
        else return '=';
      }
      case '<': {
        next(ls);
        if (check_next1(ls, '=')) return TK_LE;
        else if (check_next1(ls, '<')) return TK_SHL;
        else return '<';
      }
      case '>': {
        next(ls);
        if (check_next1(ls, '=')) return TK_GE;
        else if (check_next1(ls, '>')) return TK_SHR;
        else return '>';
      }
      case '/': {
        next(ls);
        if (check_next1(ls, '/')) return TK_IDIV;
        else return '/';
      }
      case '~': {
        next(ls);
        if (check_next1(ls, '=')) return TK_NE;
        else return '~';
      }
      case ':': {
        next(ls);
        if (check_next1(ls, ':')) return TK_DBCOLON;
        else return ':';
      }
      case '"': case '\'': {  /* short literal strings */
        read_string(ls, ls->current, seminfo);
        return TK_STRING;
      }
      case '.': {  /* '.', '..', '...', or number */
        save_and_next(ls);
        if (check_next1(ls, '.')) {
          if (check_next1(ls, '.'))
            return TK_DOTS;   /* '...' */
          else return TK_CONCAT;   /* '..' */
        }
        else if (!lisdigit(ls->current)) return '.';
        else return read_numeral(ls, seminfo);
      }
      case '0': case '1': case '2': case '3': case '4':
      case '5': case '6': case '7': case '8': case '9': {
        return read_numeral(ls, seminfo);
      }
      case EOZ: {
        return TK_EOS;
      }
      default: {
        if (lislalpha(ls->current)) {  /* identifier or reserved word? */
          TString *ts;
          do {
            save_and_next(ls);
          } while (lislalnum(ls->current));
          ts = luaX_newstring(ls, luaZ_buffer(ls->buff),
                                  luaZ_bufflen(ls->buff));
          seminfo->ts = ts;
          if (isreserved(ts))  /* reserved word? */
            return ts->extra - 1 + FIRST_RESERVED;
          else {
            return TK_NAME;
          }
        }
        else {  /* single-char tokens (+ - / ...) */
          int c = ls->current;
          next(ls);
          return c;
        }
      }
    }
  }
}
Beispiel #2
0
l_noret luaX_syntaxerror (LexState *ls, const char *msg) {
  lexerror(ls, msg, ls->t.token);
}
int yylex(void)
{
    int ch;

    for(;;) {
  ch = getchar();
  switch( ch ) {
    case EOF:
      return 0;
    case '\n':
      ++yylineno;
      continue;
    case '\t': case ' ':
      continue;
    case '{':
      do {
    ch = getchar();
      } while( ch != '}' && ch != EOF );
      continue;
    case ':':  /* ASSIGN or COLON */
      ch = getchar();
      switch( ch ) {
        case '=':
    return lex_log_token(T_ASSIGN);
        default:
    ungetc(ch, stdin);
    return lex_log_token(T_COLON);
      }
    case ',':
      return lex_log_token(T_COMMA);
    case '.':  /* RCON or DOT */
      ch = getchar();
      ungetc(ch, stdin);
      if( isdigit(ch) )
    return lex_log_token(lex_number('.'));
      else
    return lex_log_token(T_DOT);
    case '[':
      return lex_log_token(T_LBRACK);
    case ']':
      return lex_log_token(T_RBRACK);
    case '(':
      return lex_log_token(T_LPAREN);
    case ')':
      return lex_log_token(T_RPAREN);
    case '<':  /* NE, LE, or LT */
      ch = getchar();
      switch( ch ) {
        case '>':
    return lex_log_token(T_NE);
        case '=':
    return lex_log_token(T_LE);
        default:
    ungetc(ch, stdin);
    return lex_log_token(T_LT);
      }
    case '=':
      return lex_log_token(T_EQ);
    case '>':  /* GE or GT */
      ch = getchar();
      switch( ch ) {
        case '=':
    return lex_log_token(T_GE);
        default:
    ungetc(ch, stdin);
    return lex_log_token(T_GT);
      }
    case '-':
      return lex_log_token(T_MINUS);
    case '*':
      return lex_log_token(T_MUL);
    case '+':
      return lex_log_token(T_PLUS);
    case '/':
      return lex_log_token(T_RDIV);
    case ';':
      return lex_log_token(T_SEMI);
    case '&':
      return lex_log_token(T_AMPER);
    case '^':
      return lex_log_token(T_CARET);
    default:
      if( isalpha(ch) || ch == '_' )
    return lex_log_token(lex_alpha_ident(ch));
      else if( isdigit(ch) )
    return lex_log_token(lex_number(ch));
      else
    lexerror("Illegal character %03o", ch);
  }
    }
}
Beispiel #4
0
Datei: llex.c Projekt: bcrist/lua
static void read_string (LexState *ls, int del, SemInfo *seminfo) {
  save_and_next(ls);  /* keep delimiter (for error messages) */
  while (ls->current != del) {
    switch (ls->current) {
      case EOZ:
        lexerror(ls, "unfinished string", TK_EOS);
        break;  /* to avoid warnings */
      case '\n':
      case '\r':
        lexerror(ls, "unfinished string", TK_STRING);
        break;  /* to avoid warnings */
      case '\\': {  /* escape sequences */
        int c;  /* final character to be saved */
        save_and_next(ls);  /* keep '\\' for error messages */
        switch (ls->current) {
          case 'a': c = '\a'; goto read_save;
          case 'b': c = '\b'; goto read_save;
          case 'f': c = '\f'; goto read_save;
          case 'n': c = '\n'; goto read_save;
          case 'r': c = '\r'; goto read_save;
          case 't': c = '\t'; goto read_save;
          case 'v': c = '\v'; goto read_save;
          case 'x': c = readhexaesc(ls); goto read_save;
          case 'u': utf8esc(ls);  goto no_save;
          case '\n': case '\r':
            inclinenumber(ls); c = '\n'; goto only_save;
          case '\\': case '\"': case '\'':
            c = ls->current; goto read_save;
          case EOZ: goto no_save;  /* will raise an error next loop */
          case 'z': {  /* zap following span of spaces */
            luaZ_buffremove(ls->buff, 1);  /* remove '\\' */
            next(ls);  /* skip the 'z' */
            while (lisspace(ls->current)) {
              if (currIsNewline(ls)) inclinenumber(ls);
              else next(ls);
            }
            goto no_save;
          }
          default: {
            esccheck(ls, lisdigit(ls->current), "invalid escape sequence");
            c = readdecesc(ls);  /* digital escape '\ddd' */
            goto only_save;
          }
        }
       read_save:
         next(ls);
         /* go through */
       only_save:
         luaZ_buffremove(ls->buff, 1);  /* remove '\\' */
         save(ls, c);
         /* go through */
       no_save: break;
      }
      default:
        save_and_next(ls);
    }
  }
  save_and_next(ls);  /* skip delimiter */
  seminfo->ts = luaX_newstring(ls, luaZ_buffer(ls->buff) + 1,
                                   luaZ_bufflen(ls->buff) - 2);
}
Beispiel #5
0
int
handle_include(char *name, int ignore_errors)
{
    char *p;
    char buf[1024];
    FILE *f;
    struct incstate *is;
    int delim;

    if (*name != '"' && *name != '<')
    {
	struct defn *d;
	if ((d = lookup_define(name)) && d->nargs == -1)
	{
	    char *q;
	    q = d->exps;
	    while (isspace(*q))
		q++;
	    return handle_include(q, ignore_errors);
	}
	else
	{
            if (!ignore_errors)
	        lexerror("Missing leading \" or < in #include");
            return 0;
	}
    }
    delim = *name++ == '"' ? '"' : '>';
    for (p = name; *p && *p != delim; p++)
	;
    if (!*p)
    {
        if (!ignore_errors)
	    lexerror("Missing trailing \" or > in #include");
	return 0;
    }
    if (strlen(name) > sizeof(buf) - 100)
    { 
        if (!ignore_errors)
	    lexerror("Include name too long.");
	return 0;
    }
    *p = 0;
    
    if ((f = inc_open(buf, sizeof(buf), name)) == NULL)
    {
        if (!ignore_errors) {
	    lexerror("Cannot #include %s\n", name);
        }

        return 0;
    }

    is = (struct incstate *)xalloc(sizeof(struct incstate));
    is->yyin = yyin;
    is->line = current_line;
    is->file = current_file;
    is->incfnum = current_incfile;
    is->slast = slast;
    is->lastchar = lastchar;
    is->next = inctop;
    is->pragma_strict_types = pragma_strict_types;

    if (nbuf)
    {
        memcpy(is->outp = (char *)xalloc(nbuf + 1), outp, nbuf);
        is->nbuf = nbuf;
        nbuf = 0;
        outp = defbuf + DEFMAX;
    }
    else
    {
        is->nbuf = 0;
        is->outp = NULL;
    }

    pragma_strict_types = 0;
    inctop = is;
    current_line = 1;
    current_file = xalloc(strlen(buf)+1);
    current_incfile = ++num_incfiles;
    (void)strcpy(current_file, buf);
    slast = lastchar = '\n';
    yyin = f;
    incdepth++;
    return 1;
}
Beispiel #6
0
static int
yylex1(void)
{
    register char *yyp;
    register int c;
    register int c1, c2;
    
    for (;;)
    {
	if (lex_fatal)
	{
	    return -1;
	}
	switch(c = mygetc())
	{
	case EOF:
	    if (inctop)
	    {
		struct incstate *p;
		p = inctop;
		(void)fclose(yyin);
		/*(void)fprintf(stderr, "popping to %s\n", p->file);*/
		free(current_file);
		nexpands = 0;
		current_file = p->file;
		current_line = p->line + 1;
		current_incfile = p->incfnum;
		pragma_strict_types = p->pragma_strict_types;
		yyin = p->yyin;
		slast = p->slast;
		lastchar = p->lastchar;
		inctop = p->next;
		
		if (p->nbuf)
		{
		    nbuf = p->nbuf;
		    outp = defbuf + DEFMAX - nbuf;
		    memcpy(outp, p->outp, nbuf);
		    free((char *)p->outp);
		}
		else
		{
		    nbuf = 0;
		    outp = defbuf + DEFMAX;
		}
		
		store_line_number_info(current_incfile, current_line);
		incdepth--;
		
		free((char *)p);
		break;
	    }
	    if (iftop)
	    {
		struct ifstate *p = iftop;
		lexerror(p->state == EXPECT_ENDIF ? "Missing #endif" : "Missing #else");
		while (iftop)
		{
		    p = iftop;
		    iftop = p->next;
		    free((char *)p);
		}
	    }
	    return -1;
	case '\n':
	{
	    nexpands=0;
	    store_line_number_info(current_incfile, current_line);
	    current_line++;
	    total_lines++;
	}
        /* FALLTHROUGH */
	case ' ':
	case '\t':
	case '\f':
	case '\v':
	    break;
	case '+':
	    TRY('+', F_INC);
	    TRY('=', F_ADD_EQ);
	    return c;
	case '-':
	    TRY('>', F_ARROW);
	    TRY('-', F_DEC);
	    TRY('=', F_SUB_EQ);
	    return c;
	case '&':
	    TRY('&', F_LAND);
	    TRY('=', F_AND_EQ);
	    return c;
	case '|':
	    TRY('|', F_LOR);
	    TRY('=', F_OR_EQ);
	    return c;
	case '^':
	    TRY('=', F_XOR_EQ);
	    return c;
	case '<':
	    if (gobble('<')) {
		TRY('=', F_LSH_EQ);
		return F_LSH;
	    }
	    TRY('=', F_LE);
	    return c;
	case '>':
	    if (gobble('>'))
	    {
		TRY('=', F_RSH_EQ);
		return F_RSH;
	    }
	    TRY('=', F_GE);
	    return c;
	case '*':
	    TRY('=', F_MULT_EQ);
	    return c;
	case '%':
	    TRY('=', F_MOD_EQ);
	    return F_MOD;
	case '/':
	    if (gobble('*'))
	    {
		skip_comment();
		break;
	    }
	    else if (gobble('/'))
	    {
		skip_comment2();
		break;
	    }
	    TRY('=', F_DIV_EQ);
	    return c;
	case '=':
	    TRY('=', F_EQ);
	    return c;
	case ';':
	case '(':
	case ')':
	case ',':
	case '{':
	case '}':
	case '~':
	case '[':
	case ']':
	case '?':
	case '@':
	    return c;
	case '!':
	    TRY('=', F_NE);
	    return F_NOT;
	case ':':
	    TRY(':', F_COLON_COLON);
	    return ':';
	case '.':
	    if (gobble('.'))
	    {
		if (gobble('.'))
		    return F_VARARG;
		else
		    return F_RANGE;
	    }
	    return c;
	case '#':
	    if (lastchar == '\n') 
	    {
		char *ssp = 0;
		int quote;
		
		yyp = yytext;
		do 
		{
		    c = mygetc();
		} while (isspace(c));
		
		for (quote = 0;;) 
		{
		    if (c == '"')
			quote ^= 1;
		    
		    /*gc - handle comments cpp-like! 1.6.91 @@@*/
		    while (!quote && c == '/')  
		    {
			if (gobble('*')) 
			{ 
			    skip_comment();
			    c = mygetc();
			}
			else 
			    break;
		    }
		    
		    if (!ssp && isspace(c))
			ssp = yyp;
		    if (c == '\n' || c == EOF)
			break;
		    SAVEC;
		    c = mygetc();
		}
		if (ssp) 
		{
		    *ssp++ = 0;
		    while (isspace(*ssp))
			ssp++;
		} 
		else 
		{
		    ssp = yyp;
		}
		*yyp = 0;
		if (strcmp("define", yytext) == 0) 
		{
		    handle_define(ssp);
		} 
		else if (strcmp("if", yytext) == 0) 
		{
#if 0
		    short int nega=0; /*@@@ allow #if !VAR gc 1.6.91*/
		    if (*ssp=='!'){ ssp++; nega=1;}
		    if (isdigit(*ssp))
		    {
			char *p;
			long l;
			l = strtol(ssp, &p, 10);
			while (isspace(*p))
			    p++;
			if (*p)
			    lexerror("Condition too complex in #if");
			else
			    handle_cond(nega ? !(int)l : (int)l);
		    }
		    else if (isalunum(*ssp))
		    {
			char *p = ssp;
			while (isalunum(*p))
			    p++;
			if (*p)
			{
			    *p++ = 0;
			    while (isspace(*p))
				p++;
			}
			if (*p)
			    lexerror("Condition too complex in #if");
			else
			{
			    struct defn *d;
			    d = lookup_define(ssp);
			    if (d)
			    {
				handle_cond(nega ? !atoi(d->exps) : atoi(d->exps));/* a hack! */
			    }
			    else
			    {
				handle_cond(nega?1:0); /* cpp-like gc*/
			    }
			}
		    }
		    else
			lexerror("Condition too complex in #if");
#else
		    int cond;
            
		    myungetc(0);
		    add_input(ssp);
		    cond = cond_get_exp(0);
		    if (mygetc()) 
		    {
			lexerror("Condition too complex in #if");
			while (mygetc())
			    ;
		    }
		    else
			handle_cond(cond);
#endif
		}
		else if (strcmp("ifdef", yytext) == 0) 
		{
		    deltrail(ssp);
		    handle_cond(lookup_define(ssp) != 0);
		}
		else if (strcmp("ifndef", yytext) == 0)
		{
		    deltrail(ssp);
		    handle_cond(lookup_define(ssp) == 0);
		} 
		else if (strcmp("else", yytext) == 0) 
		{
		    if (iftop && iftop->state == EXPECT_ELSE) 
		    {
			struct ifstate *p = iftop;
			
			/*(void)fprintf(stderr, "found else\n");*/
			iftop = p->next;
			free((char *)p);
			(void)skip_to("endif", (char *)0);
			store_line_number_info(current_incfile, current_line);
			current_line++;
			total_lines++;
		    }
		    else
		    {
			lexerror("Unexpected #else");
		    }
		} 
		else if (strcmp("endif", yytext) == 0) 
		{
		    if (iftop && (iftop->state == EXPECT_ENDIF ||
				  iftop->state == EXPECT_ELSE)) 
		    {
			struct ifstate *p = iftop;
			
			/*(void)fprintf(stderr, "found endif\n");*/
			iftop = p->next;
			free((char *)p);
		    } 
		    else 
		    {
			lexerror("Unexpected #endif");
		    }
		} 
		else if (strcmp("undef", yytext) == 0) 
		{
		    struct defn *d;
		    
		    deltrail(ssp);
		    if ((d = lookup_define(ssp)) != NULL )
			d->undef++;
		} 
		else if (strcmp("echo", yytext) == 0) 
		{
		    (void)fprintf(stderr, "%s\n", ssp);
		} 
		else if (strcmp("include", yytext) == 0) 
		{
		    /*(void)fprintf(stderr, "including %s\n", ssp);     */
		    handle_include(ssp, 0);
		}
		else if (strcmp("pragma", yytext) == 0)
		{
		    deltrail(ssp);
		    handle_pragma(ssp);
		} 
		else if (strcmp("error", yytext) == 0)
		{
		    handle_exception(ERROR, ssp);
		}
		else if (strcmp("warning", yytext) == 0)
		{
		    handle_exception(WARNING, ssp);
		}
		else 
		{
		    lexerror("Unrecognised # directive");
		}
		myungetc('\n');
		break;
	    }
	    else
		goto badlex;
	case '\'':
	    yylval.number = mygetc();
	    if (yylval.number == '\\')
	    {
		int tmp = mygetc();
		switch (tmp)
		{
		case 'n': yylval.number = '\n'; break;
		case 't': yylval.number = '\t'; break;
		case 'b': yylval.number = '\b'; break;
		case 'a': yylval.number = '\a'; break;
		case 'v': yylval.number = '\v'; break;
		case '\'':
		case '\\':
		case '"':
		    yylval.number = tmp; break;
		default:
		    lexwarning("Bad character escape sequence");
		    yylval.number = tmp;
		    break;
		}
	    }
	    if (!gobble('\''))
		lexerror("Illegal character constant");
	    return F_NUMBER;
	case '"':
	    yyp = yytext;
	    *yyp++ = c;
	    for (;;)
	    {
		c = mygetc();
		if (c == EOF)
		{
		    lexerror("End of file in string");
		    return string("\"\"");
		}
		else if (c == '\n')
		{
		    lexerror("Newline in string");
		    return string("\"\"");
		}
		SAVEC;
		if (c == '"')
		    break;
		if (c == '\\')
		{
		    c = mygetc();
		    if ( c == '\n' )
		    {
			yyp--;
			store_line_number_info(current_incfile, current_line);
			current_line++;
			total_lines++;
		    } 
		    else if ( c == EOF ) 
		    {
			/* some operating systems give EOF only once */
			myungetc(c); 
		    } 
		    else
			*yyp++ = c;
		}
	    }
	    *yyp = 0;
	    return string(yytext);

	case '0':
	    c = mygetc();
	    if ( c == 'X' || c == 'x' || c == 'o') 
	    {
                char *endptr;
                long long value;
                int base = 16;
                if (c == 'o')
                    base = 8;

                
		yyp = yytext;

		for (;;) 
		{
		    c = mygetc();
		    if (!isxdigit(c))
			break;
                    SAVEC;
		}
		myungetc(c);
                *yyp = '\0';
                
                value = strtoll(yytext, &endptr, base);
                if (*endptr != '\0')
                {
                    fprintf(stderr, "%s\n", yytext);
                    lexwarning("Invalid digits in octal number number");
                }
                
                return number(value);
	    }
	    myungetc(c);
	    c = '0';
	    /* FALLTHROUGH */
	case '1':
	case '2':
	case '3':
	case '4':
	case '5':
	case '6':
	case '7':
	case '8':
	case '9':
	    yyp = yytext;
	    *yyp++ = c;
	    for (;;)
	    {
		c = mygetc();
		if (!isdigit(c))
		    break;
		SAVEC;
	    }
	    if (c == '.')
	    {
		if (isdigit(c1 = mygetc()))
		{
		    SAVEC;
		    c = c1;
		    SAVEC;
		    for (c = mygetc(); isdigit(c); c = mygetc())
			SAVEC;
		    if (c == 'e' || c == 'E')
		    {
			c1 = mygetc();
			if (c1 == '-' || c1 == '+')
			{
			    c2 = mygetc();
			    if (isdigit(c2))
			    {
				SAVEC;
				c = c1;
				SAVEC;
				c = c2;
				SAVEC;
				for (c = mygetc(); isdigit(c); c = mygetc())
				    SAVEC;
			    }
			    else
			    {
				myungetc(c2);
				myungetc(c1);
			    }
			}
			else if (isdigit(c1))
			{
			    SAVEC;
			    c = c1;
			    SAVEC;
			    for (c = mygetc(); isdigit(c); c = mygetc())
				SAVEC;
			}
			else
			    myungetc(c1);
		    }
		    myungetc(c);
		    *yyp = 0;
		    return real(strtod(yytext, NULL));
		}
		myungetc(c1);
	    }
	    myungetc(c);
	    *yyp = 0;
	    if (*yytext == '0')
            {
                /* OCTALS */
                char *endptr;
                long long value;

                value = strtoll(yytext, &endptr, 010);

                if (*endptr != '\0')
                    lexwarning("Invalid digits in octal number");

                if (value != 0)
                    lexwarning("Obsolete octal format used. Use 0o111 syntax");
                
		return number(value);
            }
	    return number(atoll(yytext));
	default:
	    if (isalpha(c) || c == '_') {
		int r;
		
		yyp = yytext;
		*yyp++ = c;
		for (;;)
		{
		    c = mygetc();
		    if (!isalunum(c))
			break;
		    SAVEC;
		}
		*yyp = 0;
		
		myungetc(c);
		if (!expand_define())
		{
		    r = lookup_resword(yytext);
		    if (r >= 0)
		    {
			return r;
		    }
		    else
			return ident(yytext);
		}
		break;
	    }
	    goto badlex;
	}
    }
  badlex:
    {
	lexerror("Illegal character (hex %02x) '%c'", c, c);
        return ' '; 
    }
}
Beispiel #7
0
static int 
cond_get_exp(int priority)
{
    int c;
    int value, value2, x;
    
    do
	c = exgetc();
    while (isspace(c));
    
    if (c == '(')
    {
	value = cond_get_exp(0);
	do
	    c = exgetc();
	while (isspace(c));
	if (c != ')')
	{
	    lexerror("bracket not paired in #if");
	    if (!c)
		myungetc('\0');
	}
    }
    else if (ispunct(c))
    {
	x = (_optab-' ')[c];
	if (!x)
	{
	    lexerror("illegal character in #if");
	    return 0;
	}
	value = cond_get_exp(12);
	switch ( optab2[x-1] )
	{
	case BNOT  : value = ~value; break;
	case LNOT  : value = !value; break;
	case UMINUS: value = -value; break;
	case UPLUS : value =  value; break;
	default :
	    lexerror("illegal unary operator in #if");
	    return 0;
	}
    }
    else
    {
	int base;
	
	if (!isdigit(c))
	{
	    if (!c)
	    {
		lexerror("missing expression in #if");
		myungetc('\0');
	    }
	    else
		lexerror("illegal character in #if");
	    return 0;
	}
	value = 0;
	if (c!='0')
	    base = 10;
	else
	{
	    c = mygetc();
	    if ( c == 'x' || c == 'X' )
	    {
		base = 16;
		c = mygetc();
	    }
	    else
		base=8;
	}
	for (;;)
	{
	    if ( isdigit(c) )
		x = -'0';
	    else if (isupper(c))
		x = -'A' + 10;
	    else if (islower(c))
		x = -'a' + 10;
	    else
		break;
	    x += c;
	    if (x > base)
		break;
	    value = value*base + x;
	    c = mygetc();
	}
	myungetc(c);
    }
    for (;;)
    {
	do
	    c = exgetc();
	while (isspace(c));
	
	if (!ispunct(c))
	    break;
	x = (_optab-' ')[c];
	if (!x)
	    break;
	value2 = mygetc();
	for (;;x += 3)
	{
	    if (!optab2[x])
	    {
		myungetc(value2);
		if (!optab2[x + 1])
		{
		    lexerror("illegal operator use in #if");
		    return 0;
		}
		break;
	    }
	    if (value2 == optab2[x])
		break;
	}
	if (priority >= optab2[x + 2])
	{
	    if (optab2[x])
		myungetc(value2);
	    break;
	}
	value2 = cond_get_exp(optab2[x + 2]);
	switch ( optab2[x + 1] )
	{
	case MULT   : value *=  value2;                    break;
	case DIV    : value /=  value2;                    break;
	case MOD    : value %=  value2;                    break;
	case BPLUS  : value +=  value2;                    break;
	case BMINUS : value -=  value2;                    break;
	case LSHIFT : value <<= value2;                    break;
	case RSHIFT : value =   (unsigned)value >> value2; break;
	case LESS   : value =   value <  value2;           break;
	case LEQ    : value =   value <= value2;           break;
	case GREAT  : value =   value >  value2;           break;
	case GEQ    : value =   value >= value2;           break;
	case EQ     : value =   value == value2;           break;
	case NEQ    : value =   value != value2;           break;
	case BAND   : value &=  value2;                    break;
	case XOR    : value ^=  value2;                    break;
	case BOR    : value |=  value2;                    break;
	case LAND   : value =  value && value2;            break;
	case LOR    : value =  value || value2;            break;
	case QMARK  :
	    do
		c = exgetc();
	    while (isspace(c));
            if (c != ':')
	    {
		lexerror("'?' without ':' in #if");
		myungetc(c);
		return 0;
	    }
	    if (value) 
	    {
		(void)cond_get_exp(1);
		value = value2;
	    }
	    else
		value = cond_get_exp(1);
	    break;
	}
    }
    myungetc(c);
    return value;
}
Beispiel #8
0
static int
skip_to(char *token, char *atoken)
{
    char b[20], *p;
    int c;
    int nest;

    for (nest = 0;;)
    {
        c = mygetc();
        if (c == '#')
        {
            do
            {
                c = mygetc();
            } while (isspace(c));
            for (p = b; c != '\n' && c != EOF; )
            {
                if (p < b+sizeof b-1)
                    *p++ = c;
                c = mygetc();
            }
            *p++ = 0;
            for (p = b; *p && !isspace(*p); p++)
                ;
            *p = 0;
            /*(void)fprintf(stderr, "skip checks %s\n", b);*/
            if (strcmp(b, "if") == 0 || strcmp(b, "ifdef") == 0 ||
                strcmp(b, "ifndef") == 0)
            {
                nest++;
            }
            else if (nest > 0)
            {
                if (strcmp(b, "endif") == 0)
                    nest--;
            }
            else
            {
                if (strcmp(b, token) == 0)
                    return 1;
                else if (atoken && strcmp(b, atoken) == 0)
                    return 0;
            }
        }
        else 
        {
            /*(void)fprintf(stderr, "skipping (%d) %c", c, c);*/
            while (c != '\n' && c != EOF) 
            {
                c = mygetc();
                /*(void)fprintf(stderr, "%c", c);*/
            } 
            if (c == EOF)
            {
                lexerror("Unexpected end of file while skipping");
                return 1;
            }
        }
        store_line_number_info(current_incfile, current_line);
        current_line++;
        total_lines++;
    }
}
Beispiel #9
0
/* Stuff to evaluate expression.  I havn't really checked it. /LA
** Written by "J\"orn Rennecke" <*****@*****.**>
*/
static int
exgetc(void)
{
    register char c, *yyp;
    
    c = mygetc();
    while (isalpha(c) || c == '_')
    {
	yyp = yytext;
	do
	{
	    SAVEC;
	    c = mygetc();
	} while (isalunum(c));
	myungetc(c);
	*yyp = '\0';
	if (strcmp(yytext, "defined") == 0)
	{
	    /* handle the defined "function" in #if */
	    do
		c = mygetc();
	    while (isspace(c));
	    
	    if (c != '(')
	    {
		lexerror("Missing ( in defined");
		continue;
	    }
	    do
		c = mygetc();
	    while (isspace(c));
	    
	    yyp = yytext;
	    while (isalunum(c))
	    {
		SAVEC;
		c = mygetc();
	    }
	    *yyp = '\0';
	    while (isspace(c))
		c = mygetc();
	    if (c != ')')
	    {
		lexerror("Missing ) in defined");
		continue;
	    }

	    /* Skip whitespace */
	    do
		c = mygetc();
	    while (isspace(c)); 
	    myungetc(c);

	    if (lookup_define(yytext))
		add_input(" 1 ");
	    else
		add_input(" 0 ");
	}
	else
	{
	    if (!expand_define()) add_input(" 0 ");
	}
	c = mygetc();
    }
    return c;
}
Beispiel #10
0
/* Check if yytext is a macro and expand if it is. */
static int
expand_define(void)
{
    struct defn *p;
    char expbuf[DEFMAX];
    char *args[NARGS];
    char buf[DEFMAX];
    char *q, *e, *b;

    if (nexpands++ > EXPANDMAX)
    {
	lexerror("Too many macro expansions");
	return 0;
    }
    p = lookup_define(yytext);
    if (!p)
    {
	return 0;
    }
    if (p->nargs == -1)
    {
	add_input(p->exps);
    }
    else
    {
	int c, parcnt = 0, dquote = 0, squote = 0;
	int n;
	SKIPW;
	if (c != '(')
	{
	    lexerror("Missing '(' in macro call");
	    return 0;
	}
	SKIPW;
	if (c == ')')
	    n = 0;
	else
	{
	    q = expbuf;
	    args[0] = q;
	    for (n = 0; n < NARGS; )
	    {
		switch(c)
		{
		case '"':
		    if (!squote)
			dquote ^= 1;
		    break;
		case '\'':
		    if (!dquote)
			squote ^= 1;
		    break;
		case '(':
		    if (!squote && !dquote)
			parcnt++;
		    break;
		case ')':
		    if (!squote && !dquote)
			parcnt--;
		    break;
		case '\\':
		    if (squote || dquote)
		    {
			*q++ = c;
			c = mygetc();}
		    break;
		case '\n':
		    if (squote || dquote)
		    {
			lexerror("Newline in string");
			return 0;
		    }
		    break;
		}
		if (c == ',' && !parcnt && !dquote && !squote)
		{
		    *q++ = 0;
		    args[++n] = q;
		}
		else if (parcnt < 0)
		{
		    *q++ = 0;
		    n++;
		    break;
		}
		else
		{
		    if (c == EOF)
		    {
			lexerror("Unexpected end of file");
			return 0;
		    }
		    if (q >= expbuf + DEFMAX - 5)
		    {
			lexerror("Macro argument overflow");
			return 0;
		    }
		    else
		    {
			*q++ = c;
		    }
		}
		if (!squote && ! dquote)
		    c = cmygetc();
		else
		    c = mygetc();
	    }
	    if (n == NARGS)
	    {
		lexerror("Maximum macro argument count exceeded");
		return 0;
	    }
	}
	if (n != p->nargs)
	{
	    lexerror("Wrong number of macro arguments");
	    return 0;
	}
	/* Do expansion */
	b = buf;
	e = p->exps;
	while (*e)
	{
	    if (*e == MARKS)
	    {
		if (*++e == MARKS)
		    *b++ = *e++;
		else
		{
		    for (q = args[*e++ - MARKS - 1]; *q; )
		    {
			*b++ = *q++;
			if (b >= buf+DEFMAX)
			{
			    lexerror("Macro expansion overflow");
			    return 0;
			}
		    }
		}
	    }
	    else
	    {
		*b++ = *e++;
		if (b >= buf+DEFMAX)
		{
		    lexerror("Macro expansion overflow");
		    return 0;
		}
	    }
	}
	*b++ = 0;
	add_input(buf);
    }
    return 1;
}
Beispiel #11
0
static void
handle_define(char *yyt)
{
    char namebuf[NSIZE];
    char args[NARGS][NSIZE];
    char mtext[MLEN];
    char *p, *q;

    p = yyt;
    (void)strcat(p, " ");
    q = namebuf;
    GETALPHA(p, q, namebuf+NSIZE-1);
    if (*p == '(')
    {       /* if "function macro" */
	int arg;
	int inid;
	char *ids = 0;
	p++;            /* skip '(' */
	SKIPWHITE;
	if (*p == ')')
	{
	    arg = 0;
	}
	else
	{
	    for (arg = 0; arg < NARGS; )
	    {
		q = args[arg];
		GETALPHA(p, q, args[arg] + NSIZE - 1);
		arg++;
		SKIPWHITE;
		if (*p == ')')
		    break;
		if (*p++ != ',')
		{
		    lexerror("Missing ',' in #define parameter list");
		    return;
		}
		SKIPWHITE;
	    }
	    if (arg == NARGS)
	    {
		lexerror("Too many macro arguments");
		return;
	    }
	}
	p++;            /* skip ')' */
	for (inid = 0, q = mtext; *p; )
	{
	    if (isalunum(*p))
	    {
		if (!inid)
		{
		    inid++;
		    ids = p;
		}
	    }
	    else
	    {
		if (inid)
		{
		    size_t l, idlen = p - ids;
		    int n;
		    
		    for (n = 0; n < arg; n++)
		    {
			l = strlen(args[n]);
			if (l == idlen && strncmp(args[n], ids, l) == 0)
			{
			    q -= idlen;
			    *q++ = MARKS;
			    *q++ = n+MARKS+1;
			    break;
			}
		    }
		    inid = 0;
		}
	    }
	    *q = *p;
	    if (*p++ == MARKS)
		*++q = MARKS;
	    if (q < mtext + MLEN - 2)
		q++;
	    else
	    {
		lexerror("Macro text too long");
		return;
	    }
	    if (!*p && p[-2] == '\\')
	    {
		q -= 2;
		refill();
		p = yytext;
	    }
	}
	*--q = 0;
	add_define(namebuf, arg, mtext);
    }
    else
    {
	for (q = mtext; *p; )
	{
	    *q = *p++;
	    if (q < mtext + MLEN - 2)
		q++;
	    else
	    {
		lexerror("Macro text too long");
		return;
	    }
	    if (!*p && p[-2] == '\\')
	    {
		q -= 2;
		refill();
		p = yytext;
	    }
	}
	*--q = 0;
	add_define(namebuf, -1, mtext);
    }
    return;
}
Beispiel #12
0
void parseerror(int messagenr)
{
  lexerror();
  if(messagenr < 1 || messagenr > maxparseerrormessage) messagenr = 0;
  error(parseerrormessage[messagenr]);
}
Beispiel #13
0
static void
process_ucpp_token(struct ucpp_token *tok) {
	int           			*dummyptr       = n_xmalloc(sizeof *dummyptr);
	static struct input_file	infile;

#if 0
        NONE,           /* whitespace */
        NEWLINE,        /* newline */
        COMMENT,        /* comment */
        BUNCH,          /* non-C characters */
        PRAGMA,         /* a #pragma directive */
        CONTEXT,        /* new file or #line */


        SHARP,          /*      #       */
        DSHARP,         /*      ##      */

        OPT_NONE,       /* optional space to separate tokens in text output */

        DIGRAPH_TOKENS,                 /* there begin digraph tokens */

        /* for DIG_*, do not change order, unless checking undig() in cpp.c */
        DIG_LBRK,       /*      <:      */
        DIG_RBRK,       /*      :>      */
        DIG_LBRA,       /*      <%      */
        DIG_RBRA,       /*      %>      */
        DIG_SHARP,      /*      %:      */
        DIG_DSHARP,     /*      %:%:    */

        DIGRAPH_TOKENS_END,             /* digraph tokens end here */

        LAST_MEANINGFUL_TOKEN,          /* reserved words will go there */

        MACROARG,       /* special token for representing macro arguments */
#endif

        switch (tok->type) {
	case LPAR:           /*      (       */
        case RPAR:           /*      )       */
		store_token(&toklist, dummyptr,
			tok->type == LPAR? TOK_PAREN_OPEN :
				TOK_PAREN_CLOSE, lineno, NULL);
		break;
        case LBRA:           /*      {       */
        case RBRA:           /*      }       */
		store_token(&toklist, dummyptr,
			tok->type == LBRA? TOK_COMP_OPEN: TOK_COMP_CLOSE,
			lineno, NULL);
		break;
        case LBRK:           /*      [       */
        case RBRK:           /*      ]       */
		store_token(&toklist, dummyptr,
			tok->type == LBRK? TOK_ARRAY_OPEN : TOK_ARRAY_CLOSE,
			lineno, NULL);
		break;
	case SEMIC:          /*      ;       */
		store_token(&toklist, dummyptr, TOK_SEMICOLON, lineno, NULL);
		break;
	case STRING: {
		struct ty_string        *tmpstr;
		char			*str_value = tok->name;
		int			is_wide_char = 0;
	
		if (*str_value == 'L') {
			/* Wide character string */
			++str_value;
			is_wide_char = 1;
		}

		set_input_file_buffer(&infile, str_value+1); /* +1 to skip opening " */
		
		tmpstr = get_string_literal(&infile, is_wide_char);  /* not wide char?? */
		store_token(&toklist, tmpstr,
			TOK_STRING_LITERAL, lineno, NULL); 
		break;
		}
        case NAME: {           /* identifier */
		char	*ident;

		set_input_file_buffer(&infile, tok->name+1);
		ident = get_identifier(*tok->name, &infile);
		if (ident != NULL) {
			store_token(&toklist, ident,
				TOK_IDENTIFIER, lineno, n_xstrdup(tok->name));
		}
		break;
		}
	case CHAR: {
		int	err = 0;
		int	is_wide_char = 0;
		char	*str_value = tok->name;
		int	tmpi;

		if (*str_value == 'L') {
			/* Wide character string */
			++str_value;
			is_wide_char = 1;
		}

		set_input_file_buffer(&infile, str_value+1);
		tmpi = get_char_literal(&infile, &err); /* XXX cross-comp */
		if (!err) {
			int	char_type;

			/*
			 * Character literals are really treated
			 * like integer constants
			 */
			int	*tmpip = zalloc_buf(Z_CEXPR_BUF); /*n_xmalloc(16);*/ /* XXX */
			if (tmpip == NULL) {
				perror("malloc");
				exit(EXIT_FAILURE);
			}
			*tmpip = tmpi;

			if (is_wide_char) {
				char_type = backend->get_wchar_t()->code;

				/*
				 * The assignment above assumes int,
				 * i.e. 32bit on all supported
				 * platforms
				 */
				assert(backend->get_sizeof_type(
					backend->get_wchar_t(), NULL) == 4);
			} else {
				char_type = TY_INT;
			}
			store_token(&toklist, tmpip, char_type, lineno, n_xstrdup(tok->name));
		}
		is_wide_char = 0;
		break;
		}
	case NUMBER: {
		struct num	*n;

		set_input_file_buffer(&infile, tok->name+1);
		n = get_num_literal(*tok->name, &infile);
		if (n != NULL) {
			store_token(&toklist, n->value,
				n->type, lineno, n_xstrdup(tok->name));
		} else {
			lexerror("Couldn't read numeric literal");
		}
		break;
		}
	case MDOTS: {
		int	*tmp = n_xmalloc(sizeof *tmp);
		*tmp = 0; 
		store_token(&toklist, tmp, TOK_ELLIPSIS, lineno, NULL);
		break;
		}
	case SLASH:          /*      /       */
	case ASSLASH:        /*      /=      */
	case MINUS:          /*      -       */
	case MMINUS:         /*      --      */
	case ASMINUS:        /*      -=      */
	case ARROW:          /*      ->      */
	case PLUS:           /*      +       */
	case PPLUS:          /*      ++      */
	case ASPLUS:         /*      +=      */
	case LT:             /*      <       */
	case LEQ:            /*      <=      */
	case LSH:            /*      <<      */
	case ASLSH:          /*      <<=     */
	case GT:             /*      >       */
	case GEQ:            /*      >=      */
	case RSH:            /*      >>      */
	case ASRSH:          /*      >>=     */
	case ASGN:           /*      =       */
	case SAME:           /*      ==      */
#ifdef CAST_OP
	case CAST:           /*      =>      */
#endif
	case NOT:            /*      ~       */
	case NEQ:            /*      !=      */
	case AND:            /*      &       */
	case LAND:           /*      &&      */
	case ASAND:          /*      &=      */
	case OR:             /*      |       */
	case LOR:            /*      ||      */
	case ASOR:           /*      |=      */
	case PCT:            /*      %       */
	case ASPCT:          /*      %=      */
	case STAR:           /*      *       */
	case ASSTAR:         /*      *=      */
	case CIRC:           /*      ^       */
	case ASCIRC:         /*      ^=      */
	case LNOT:           /*      !       */
	case COMMA:          /*      ,       */
	case QUEST:          /*      ?       */
	case COLON:          /*      :       */
	case DOT:            /*      .       */
        case UPLUS: /* unary + */
        case UMINUS:          /* unary - */
		{
		int	*opval = n_xmalloc(sizeof *opval);
		char	*optext = operators_name[tok->type];

		set_input_file_buffer(&infile, optext+1);
		*opval = get_operator(*optext, &infile, &optext); /* XXX cross-comp */
		if (*opval == -1) {
			lexerror("Invalid operator `%s'", optext);
			free(opval);
		} else {
			store_token(&toklist, opval, TOK_OPERATOR, lineno, tok->name);
		}
		break;
		}
	default:
		printf("Unhandled token, type %d, value %s\n", tok->type, tok->name? tok->name: "?");
		break;
	}

	return NULL;
}