Beispiel #1
0
static int yylex2(void) {
  int ch;
  int chkcomment = FALSE;

yuk_a_goto:
	eatwhite();
	if ((ch = GETC(fname)) == EOF) {
	  if (firstsemi == 1) {
	    firstsemi = 0;
	    fclose(fname);
	    fname = fnamesave;
	    goto yuk_a_goto;
	  }
	  else {
	    return(TENDOFFILE);
	  }
	}
	do {
		if (ch == '/')
			if ((ch = GETC(fname)) == '*') {
				eatcomment();
				eatwhite();
				chkcomment = TRUE;
				if ((ch = GETC(fname)) == EOF)
					return(TENDOFFILE);
			} else {
				UNGETC(ch, fname);
				ch = '/';
				chkcomment = FALSE;
			}
		else if (ch == '-')	/* -- is a comment in our language */
		{
			if ((ch = GETC(fname)) == '-')
			{
				eatline();	 /* ignore rest of line */
				if (firstsemi != 1) yylineno++;
				eatwhite();
				chkcomment = TRUE;
				if ((ch = GETC(fname)) == EOF)
					return(TENDOFFILE);
			}
			else
			{
				UNGETC(ch, fname);
				ch = '-';
				chkcomment = FALSE;
			}
		}
		else
			chkcomment = FALSE;
	} while (chkcomment);
	if (isalpha(ch) || ch == '_')
		return(eatident(ch));
	if (isdigit(ch))
		return(eatnumber(ch));
	if (ch == '"')
		return(eatstring());
	if (ch == '\'') {
	  char ch2;
	  char ch3;
	  char chat;
	  int ate;
	  
	  ch2 = GETC(fname);
	  ch3 = GETC(fname);
	  UNGETC(ch3,fname);
	  UNGETC(ch2,fname);
	  if (ch2 != ' ' || ch3 != '\'') {
	    /* can't eat whitespace if char contains whitespace */
	    ate = eatwhite();
	    chat = GETC(fname);
	    UNGETC(chat,fname);
	    if (chat == '@') {
	      if (ate || (ch2 != '@' && ch3 != '\'')) {
		return TPRIME;
	      }
	    }
	  }
	  return eatcharacter();
	}
	if (ch == '.') {
		if (isdigit(ch = GETC(fname))) {
			UNGETC(ch, fname);
			ch = '.';
			return(eatnumber(ch));
		} else {
			UNGETC(ch, fname);
			ch = '.';
		}
	}
	if (ch == '#') {
	  char ch2;
		eatwhite();
		/* remove "line" if it exists - some vers of cpp have this */
		if ((ch2 = GETC(fname)) == '[') {
		  UNGETC(ch2, fname);
		  return eatleftovers(ch);
		}
		else {
		  UNGETC(ch2, fname);
		}
		if (!isdigit(ch = GETC(fname))) {
			UNGETC(ch, fname);
			yylex2();
			if (!strcmp(buffer,"pragma")) {
			  for (ch = GETC(fname); ch != '\n'; ch = GETC(fname)) ;
			  goto yuk_a_goto;
			}
			if (strcmp(buffer,"line")) {
			  USR_FATALX(yylineno, in_file,
				     "syntax error (appears to be a cpp directive: try -cpp)");
			}
			eatwhite();
		} else {
			UNGETC(ch, fname);
		}

		if (!isdigit(ch = GETC(fname))) {
			UNGETC(ch, fname);
			USR_FATALX(yylineno, in_file,
				   "syntax error (appears to be a cpp directive: use -cpp)");
		} else
			UNGETC(ch, fname);
		yylex2();
		yylineno = atoi(buffer);

		for (ch = GETC(fname); ch != '"' && ch != '\n'; ch = GETC(fname))
			;
		if (ch != '"') {
			goto yuk_a_goto;
		} else
			UNGETC(ch, fname);
		yylex2();

		
		in_file = (char *)PMALLOC((strlen(buffer) + 1)*sizeof(char));
		strcpy(in_file, buffer);
		base_in_file = strrchr(in_file,'/');
		if (base_in_file == NULL) {
		  base_in_file = in_file;
		} else {
		  base_in_file++;
		}
		for (ch = GETC(fname); ch != '\n'; ch = GETC(fname))
			;

		goto yuk_a_goto;
	}
	if (ispunct(ch))
		return(eatleftovers(ch));

	
	buffer[0] = ch; buffer[1] = '\0';

	  if (firstsemi == 1) {
	    firstsemi = 0;
	    fclose(fname);
	    fname = fnamesave;
	    goto yuk_a_goto;
	  }

	return(-1);
}
Beispiel #2
0
int
yylex(void)
{
    int c;
    extern char vfmt[];

loop:
    Bflush(bout);
    c = lexc();
    switch(c) {
    case Eof:
        if(gotint) {
            gotint = 0;
            stacked = 0;
            Bprint(bout, "\nacid: ");
            goto loop;
        }
        return Eof;

    case '"':
        eatstring();
        return Tstring;

    case ' ':
    case '\r':
    case '\t':
        goto loop;

    case '\n':
        line++;
        if(interactive == 0)
            goto loop;
        if(stacked) {
            print("\t");
            goto loop;
        }
        return ';';

    case '.':
        c = lexc();
        unlexc(c);
        if(isdigit(c))
            return numsym('.');

        return '.';

    case '(':
    case ')':
    case '[':
    case ']':
    case ';':
    case ':':
    case ',':
    case '~':
    case '?':
    case '*':
    case '@':
    case '^':
    case '%':
        return c;
    case '{':
        stacked++;
        return c;
    case '}':
        stacked--;
        return c;

    case '\\':
        c = lexc();
        if(strchr(vfmt, c) == 0) {
            unlexc(c);
            return '\\';
        }
        yylval.ival = c;
        return Tfmt;

    case '!':
        c = lexc();
        if(c == '=')
            return Tneq;
        unlexc(c);
        return '!';

    case '+':
        c = lexc();
        if(c == '+')
            return Tinc;
        unlexc(c);
        return '+';

    case '/':
        c = lexc();
        if(c == '/') {
            eatnl();
            goto loop;
        }
        unlexc(c);
        return '/';

    case '\'':
        c = lexc();
        if(c == '\\')
            yylval.ival = escchar(lexc());
        else
            yylval.ival = c;
        c = lexc();
        if(c != '\'') {
            error("missing '");
            unlexc(c);
        }
        return Tconst;

    case '&':
        c = lexc();
        if(c == '&')
            return Tandand;
        unlexc(c);
        return '&';

    case '=':
        c = lexc();
        if(c == '=')
            return Teq;
        unlexc(c);
        return '=';

    case '|':
        c = lexc();
        if(c == '|')
            return Toror;
        unlexc(c);
        return '|';

    case '<':
        c = lexc();
        if(c == '=')
            return Tleq;
        if(c == '<')
            return Tlsh;
        unlexc(c);
        return '<';

    case '>':
        c = lexc();
        if(c == '=')
            return Tgeq;
        if(c == '>')
            return Trsh;
        unlexc(c);
        return '>';

    case '-':
        c = lexc();

        if(c == '>')
            return Tindir;

        if(c == '-')
            return Tdec;
        unlexc(c);
        return '-';

    default:
        return numsym(c);
    }
}
Beispiel #3
0
void CodeEditor::SyntaxState::ScanSyntax(const wchar *ln, const wchar *e, int tab_size)
{
	Grounding(ln, e);
	if(!linecont) {
		linecomment = false;
		string = false;
	}
	linecont = e > ln && e[-1] == '\\';
	const wchar *p = ln;
	int lindent = 0, pos = 0;
	while(p < e && (*p == '\t' || *p == ' ')) {
		if(*p++ == '\t' || ++pos >= tab_size) {
			pos = 0;
			lindent++;
		}
	}
	int n;
	Color c = GetUvsHighlight(p, n);
	if(n) {
		uvscolor = c;
		p += n;
	}
	if(!comment && *p == '#') {
		while(++p < e && (*p == ' ' || *p == '\t'))
			p++;
		const wchar *id = p;
		while(p < e && iscidl(*p))
			p++;
		int idlen = int(p - id);
		if(id[0] == 'i' && id[1] == 'f'
		&& (idlen == 2 || idlen == 5 && id[2] == 'd' && id[3] == 'e' && id[4] == 'f'
		|| idlen == 6 && id[2] == 'n' && id[3] == 'd' && id[4] == 'e' && id[5] == 'f')) {
			IfState& ifstate = ifstack.Add();
			ifstate.state = IfState::IF;
			ifstate.iftext = sReadLn(ln);
			ifstate.ifline = line + 1;
		}
		switch(idlen)
		{
		case 6:
			if(id[0] == 'd' && id[1] == 'e' && id[2] == 'f' && id[3] == 'i' && id[4] == 'n' && id[5] == 'e')
				macro = SyntaxState::MACRO_CONT;
			break;

		case 4:
			if(id[0] == 'e' && id[1] == 'l')
				if(id[2] == 'i' && id[3] == 'f')
					if(ifstack.GetCount() == 0) {
						IfState& ifstate = ifstack.Add();
						ifstate.ifline = 0;
						ifstate.state = IfState::ELSE_ERROR;
					}
					else {
						IfState& ifstate = ifstack.Top();
						if(ifstate.state == IfState::IF || ifstate.state == IfState::ELIF) {
							ifstate.state = IfState::ELIF;
							ifstate.iftext = WString().Cat() << sReadLn(ln) << ", " << ifstate.iftext;
						}
						else
							ifstate.state = IfState::ELSE_ERROR;
					}
				else
				if(id[2] == 's' && id[3] == 'e')
					if(ifstack.GetCount() == 0) {
						IfState& ifstate = ifstack.Add();
						ifstate.ifline = 0;
						ifstate.state = IfState::ELSE_ERROR;
					}
					else {
						IfState& ifstate = ifstack.Top();
						if(ifstate.state == IfState::IF || ifstate.state == IfState::ELIF) {
							ifstate.state = IfState::ELSE;
							ifstate.iftext = "#else, " + ifstate.iftext;
						}
						else
							ifstate.state = IfState::ELSE_ERROR;
					}
			break;

		case 5:
			if(id[0] == 'e' && id[1] == 'n' && id[2] == 'd' && id[3] == 'i' && id[4] == 'f')
			{
				int itop = ifstack.GetCount() - 1;
				if(itop < 0) {
					IfState& ifstate = ifstack.Add();
					ifstate.ifline = 0;
					ifstate.state = IfState::ENDIF_ERROR;
				}
				else if(ifstack[itop].state != IfState::ENDIF_ERROR)
					ifstack.Trim(itop);
			}
			break;
		}
	}
	if(macro == SyntaxState::MACRO_CONT && !(p < e && e[-1] == '\\'))
		macro = SyntaxState::MACRO_END;
	for(;;) {
		if(comment) {
			p = strnext(p, e, '*');
			if(!p) break;
			if(*++p == '/') {
				comment = false;
				p++;
			}
		}
		else {
			int pc = 0;
			for(;;) {
				if(p >= e) return;
				const wchar *pp;
				if(!iscidl(pc) && (pp = isstmt(p)) != NULL) {
					stmtline = line;
					spar = 0;
					pc = 0;
					p = pp;
				}
				else
				if(!iscidl(pc) && p[0] == 'n' && p[1] == 'a' && p[2] == 'm' && p[3] == 'e' &&
				   p[4] == 's' && p[5] == 'p' && p[6] == 'a' && p[7] == 'c' && p[8] == 'e' &&
				   !iscidl(p[9])) {
					was_namespace = true;
					p += 9;
				}
				else {
					int c = *p++;
					if(c == '/') break;
					if(c == '\'' || c == '\"') {
						p = eatstring(p - 1);
						if(p >= e) {
							string = true;
							return;
						}
					}
					else
					if(c == ';' && spar == 0) {
						seline = stmtline;
						endstmtline = line;
						stmtline = -1;
						was_namespace = false;
					}
					else
					if(c == '{') {
						if(was_namespace) {
							brk.Add(0);
							was_namespace = false;
						}
						else {
							cl++;
							brk.Add('}');
							bid.Add(lindent + 1);
						}
						blk.Add() = line;
						stmtline = -1;
						par.Clear();
					}
					else
					if(c == '}') {
						if(brk.GetCount()) {
							if(brk.Top()) {
								cl--;
								if(bid.GetCount() > 1)
									bid.Drop();
							}
							brk.Drop();
						}
						if(blk.GetCount())
							blk.Drop();
						stmtline = -1;
						par.Clear();
					}
					else
					if(c == '(') {
						pl++;
						brk.Add(')');
						Isx& m = par.Add();
						m.line = line;
						m.pos = int(p - ln);
						spar++;
					}
					else
					if(c == '[') {
						bl++;
						brk.Add(']');
						Isx& m = par.Add();
						m.line = line;
						m.pos = int(p - ln);
						spar++;
					}
					else
					if(c == ')') {
						if(brk.GetCount()) {
							pl--;
							brk.Drop();
						}
						if(par.GetCount())
							par.Drop();
						spar--;
					}
					else
					if(c == ']') {
						if(brk.GetCount()) {
							bl--;
							brk.Drop();
						}
						if(par.GetCount())
							par.Drop();
						spar--;
					}
					pc = c;
				}
			}
			if(*p == '/') {
				linecomment = true;
				return;
			}
			if(*p == '*') {
				comment = true;
				p++;
			}
		}
	}
}
Beispiel #4
0
int
yylex(void)
{
	int c;

loop:
	c = Bgetc(bin);
	switch(c) {
	case Eof:
		return Eof;
	case '"':
		eatstring();
		return TSTRING;
	case ' ':
	case '\t':
	case '\r':
		goto loop;
	case '\n':
		line++;
		goto loop;
	case '.':
		c = Bgetc(bin);
		Bungetc(bin);
		if(isdigit(c))
			return numsym('.');
		return '.';
	case '#':
		eatnl();
		goto loop;
	case '(':
	case ')':
	case ';':
	case ',':
	case '~':
	case '$':
	case '+':
	case '/':
	case '%':
	case '^':
	case '*':
	case '&':
	case '=':
	case '|':
	case '<':
	case '>':
	case '-':
	case ':':
		return c;
	case '\'':
		c = Bgetrune(bin);
		if(c == '\\')
			yylval.ival = escchar(Bgetc(bin));
		else
			yylval.ival = c;
		c = Bgetc(bin);
		if(c != '\'') {
			diag("missing '");
			Bungetc(bin);
		}
		return TCONST;

	default:
		return numsym(c);
	}
}