Exemple #1
0
int Scanner::GetToken(int *sub) {
  *sub = 0;
  skip_non_token();
  //
  char c = cur_char();
  if (is_dec(c)) {
    return read_num();
  }
  //
  struct OperatorTableEntry *op = lookup_op();
  if (op) {
    int r;
    r = read_op(op);
    *sub = op->sub_op;
    return r;
  }
  //
  if (c == '\"') {
    return read_str();
  }
  if (is_symhead(c)) {
    return read_sym();
  }
  return -1;
}
Exemple #2
0
atom_t* read_atom(scanner_t *scan){
	slice_t slice;
	int c = scan_while_func(scan, NULL, isspace);
	
	while (c == ';'){
		scan_until(scan, NULL, '\n');
		c = scan_peek(scan);
	}
	
	if (c == EOF) {
		return nil_atom();
	} else if (c == '(') {
		return read_list(scan);
	} else if (c == '\'') {
		// Quote
		scan_one_of(scan, '\'');
		atom_t *content = read_atom(scan);
		return pair_atom_alloc(sym_atom_alloc("quote"), pair_atom_alloc(content, nil_atom()));
	} else if (c == '"') {
		// String
		scan_one_of(scan, '"');
		scan_until(scan, &slice, '"');
		return str_atom_alloc(slice.ptr);
	} else if ( isdigit(c) ) {
		// Number
		scan_while_func(scan, &slice, isdigit);
		int64_t value = strtoll(slice.ptr, NULL, 10);
		free(slice.ptr);
		return num_atom_alloc(value);
	} else {
		return read_sym(scan);
	}
}
Exemple #3
0
int dothehardpart( void )
{
  int len, c, n=0;
  int faux_pas= 0;
  long codesize= 0;

  /* initialize globals */

  numsyms= numlines= 0;

  /* begin scanning the input stream */

  c= fgetc(fin);

  if(c != 0xf5)
  {
    warn("Hmmm... this doesn't look like an AmigaBASIC binary.\n"
         "My output will probably look a bit funny.  Proceed, for a laugh.");
  }

  if( feof(fin) || ferror(fin) )
  { warn("unexpected end of input -- no code, no symbols");
    return 1;
  }

  /* read the code segment */

  do {

    /* Stefan Reisner thought that AmigaBASIC encodes the length of a line
     * in a 2 byte word prefix.  This is not the whole truth...
     * I've experienced that the first byte holds a flag (e.g. 0x80 indicates
     * a line number) and only the second byte encodes the length.
     */

    c= fgetc(fin); /* flags */

    if( len= fgetc(fin) )
    {
      codesize += len;
      len-= 2;

      if( !feof(fin) && !ferror(fin) )
        n= read_line(fin,len,c);
    }

  } while( len && n == len && !ferror(fin) && !feof(fin) );

  if( len )
  {
    if( n != len || ferror(fin) )
    {
      warn("I'm confused; after having read the code segment, I still seem\n"
           "to want to go on.  In fact I just wanted to read another %d bytes\n"
           "when a serious problem interrupted me.  I'll try to forget about this.",len);
    }

    if( feof(fin) )
    {
      warn("Uh, oh.  I suspect there was a null missing at the end of the code segment,\n"
           "causing me to read past where I should stop.\n"
           "I'll forget about the symbols now.  Proceed, with fingers crossed.");
    }
  }
  else if( feof(fin) || ferror(fin) ) /* and len <= 0 */
    warn("This seems to be a funny program.  The input ended without any symbol definitions.\n");

  /* read the symbols */

  if( !ferror(fin) && !feof(fin) )
  {
    int ok= 1;

#ifdef DEBUG
    if(debuglevel >= 1)
      fprintf(stderr,"skipping a '\\x%02x' character\n",fgetc(fin));
    else
#endif
      (void)fgetc(fin);  /* skip null byte */

    if( (codesize & 1) == 0 )
    {
#ifdef DEBUG
      if(debuglevel >= 1)
        fprintf(stderr,"skipping another '\\x%02x' character\n",fgetc(fin));
      else
#endif
      (void)fgetc(fin);
    }

    if( feof(fin) || ferror(fin) )
    {
      warn("I was just about to read the symbols when I reached the end of file.\n"
           "Maybe we have a BASIC program without symbols?  We'll see...");
    }

    else do {
      len= fgetc(fin);

      if( !feof(fin) )
        ok= read_sym(fin, len, numsyms++);

    } while( ok && !feof(fin) && !ferror(fin) );

    if( !ok )
    {
      warn("After having read %ld %s I couldn't get another %d bytes.\n"
           "Maybe there is not enough free store?  I'll better stop reading symbols!",
           numsyms-1, (numsyms-1 == 1) ? "symbol": "symbols");
    }
  }

#ifdef DEBUG
    if(debuglevel >= 1)
      fprintf(stderr,"expanding %ld lines of code w/ %d symbols\n",numlines,numsyms);
#endif

  expand_code();

  /* we _must_ call these to become re-entrant */

  free_symbols();
  free_code();

  return faux_pas;
}
Exemple #4
0
Grammar* load_grammar(FILE* file, Grammar* g)
{
	
	enum States current_state = START;  // Stato iniziale
	//enum States error = -1;
	Symbol s;
	Production* p = NULL;
	Errors error;
	error.size = 0;

	if(file != stdin)
	g->numprod = 0; // Inizializza la grammatica

	while ( !feof(file) )
	{
		s = read_sym(file);
		
		
		switch (current_state)
		{
		case START:
			if (is_terminal(s) || is_nonterminal(s))
			{
				current_state = LEFT;

				//p = &(g->productions[g->numprod++]);
				//p->left.length = 0;
				p = add_new_production(g);
				add_symbol(&p->left, s);
				//L'istruzione precedente corrisponde a p->left.word[p->left.length++] = s;
			}
			else if (is_prodsep(s))
			{
				current_state = START;
			}
			else if (ispunct(s) || isgraph(s))
			{ 
				current_state = LEFT;
				p = add_new_production(g);
				add_symbol(&p->left, s);
				error.type[error.size] = INVALID_SYMBOL;
				error.lines[error.size] = g->numprod;
				error.size++;
			}
				
			break;
		case LEFT:
			if (is_terminal(s) || is_nonterminal(s))
			{
				current_state = LEFT;
				add_symbol(&p->left, s);
			}
			else if (is_prodsym(s))
			{
				current_state = RIGHT;

				
					
				//ErrorManager(NO_NT, p);
			}
			else if (ispunct(s) || isgraph(s))
			{
				current_state = LEFT;

				add_symbol(&p->left, s);
				error.type[error.size] =  INVALID_SYMBOL;
				error.lines[error.size] = g->numprod;
				error.size++;
			}
				
			
 			else if(is_prodsep(s) || s == EOF)
			{
				error.type[error.size] = NO_PRODSYM;
				error.lines[error.size] = g->numprod;
				error.size++;
				//ErrorManager(NO_PRODSYM_MAYBE, p, g->numprod);
				current_state = START;

				if (!CheckNonTerminal(p))
				{
					error.type[error.size] = NO_NT;
					error.lines[error.size] = g->numprod;
					error.size++;

				}
			}
			else
			{

				error.type[error.size] = NO_PRODSYM;
				error.lines[error.size] = g->numprod;
				error.size++;
				
				current_state = RIGHT;
			}
			break;

		case RIGHT:
			if (is_terminal(s) || is_nonterminal(s))
			{
				current_state = RIGHT;
				add_symbol(&p->right, s);
			}
			else if (is_prodsep(s) || s == EOF)
			{
				current_state = START;
				g->productions[g->numprod-1].left.word[g->productions[g->numprod-1].left.length] = '\0';
				g->productions[g->numprod - 1].right.word[g->productions[g->numprod - 1].right.length] = '\0';
				//ErrorManager(error, p,g->numprod);
				
			}
			else if (ispunct(s) || isgraph(s))
			{
				current_state = RIGHT;

				add_symbol(&p->right, s);
				error.type[error.size] = INVALID_SYMBOL;
				error.lines[error.size] = g->numprod;
				error.size++;
			}
			break;
		
			
			
		}
		
	}

	if (error.size > 0)
	{
		DrawErrors(error, g);
		if (!CheckInitSymbol(g))
			ErrorManager(NO_INITSYM, NULL, 0);
		
		g = NULL;
	}

	if (g)
	if (!CheckInitSymbol(g))
	{
		ErrorManager(NO_INITSYM, NULL,0);
		g = NULL;
	}

		
		

		

	return g;
}
Grammar* load_grammar(FILE* file, Grammar* g){
	enum States {START,LEFT,RIGHT,ERROR};
    /*   START  = Scansione di una nuova produzione [F]
         LEFT   = Scansione della parte sinistra
         RIGHT  = Scansione della parte destra [F]
         ERROR  = Errore di scansione
    */
	enum States current_state = START;  // Stato iniziale
	Symbol s;
	Production* p;
int contatore=0;
         
	while ( !feof(file)) {
    
		s = read_sym(file);
		if (feof(file)) 
			break;
               
		switch(current_state){
			case START:
				if (is_terminal(s) || is_nonterminal(s)||is_prodsym(s)){
					current_state = LEFT;
					p = add_new_production(g);
							
					if (is_prodsym(s)){
						current_state = RIGHT;
						p->error=4;
						add_symbol(&p->left,' ');
                    }
                    else
                    	add_symbol(&p->left,s);
                }
                else 
					if (is_prodsep(s)){
                       current_state = START;
                    }
                    else {
                    	 current_state = LEFT;
                    	 add_symbol(&p->left,s);
                         p->error=3;          
                         }
						
            break;
            
			case LEFT:
				if (is_terminal(s) || is_nonterminal(s)){
					current_state = LEFT;
					add_symbol(&p->left,s);
                }
                else 
					if (is_prodsym(s)){
						current_state = RIGHT;
                    }
                    else{
                    	if(is_prodsep(s)){
                    		p->error=1;
                    		current_state=START;
                    	}
                    	else{
                        	current_state = LEFT;
                        	add_symbol(&p->left,s);
                        	p->error=3;          
                    	}
					}
                         
            break;
            
            case RIGHT:
					if (is_terminal(s) || is_nonterminal(s)){
						current_state = RIGHT;
                   		add_symbol(&p->right,s);
				   }
					else if(is_prodsep(s)){
							current_state = START;
                    	 }
                    	 else{
                             current_state = RIGHT;
                             p->error=2;   
                             add_symbol(&p->right,s);
                         }
            break;
        }
	}
         
		return g;
}