Personal tools
You are here: Home Projects C++ Cfront releases Release 3.0.3 source libSC fs fsippsrc Lexer.c
Document Actions

Lexer.c

by Michael L Powell last modified 2007-01-26 03:23

Click here to get the file

Size 5.0 kB - File type text/plain

File contents

/*ident	"@(#)fs:fsippsrc/Lexer.c	3.1" */
/******************************************************************************
*
* C++ Standard Components, Release 3.0.
*
* Copyright (c) 1991, 1992 AT&T and Unix System Laboratories, Inc.
* Copyright (c) 1988, 1989, 1990 AT&T.  All Rights Reserved.
*
* THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF AT&T and Unix System
* Laboratories, Inc.  The copyright notice above does not evidence
* any actual or intended publication of such source code.
*
******************************************************************************/

#include "Lexer.h"

#include <stdlib.h>
#include <osfcn.h>
#include <assert.h>


static void emptywin(List_of_p<Token> &win)
{
	while (win.length() > 0)
		delete win.get();
}

void Lexer::attach(istream &f, const String &s)
{
	attach(f);
	thefilename = s;
}

void Lexer::attach(istream &f)
{
	if (inf)  // if already attached to a file
	{
		lalineno = 1;
		la = 0;
		curTok = 0;
		curToki = -1;
		atBof = 1;
		left_posinfile = 0;
		emptywin(theWindow);
	}
	inf = &f;
	thefilename.make_empty();
	in();
	move();
}

Lexer::Lexer() :
	verboselevel(0),
	thetrailsize(0), 
	contractAction(0), 
	frozen(0), 

	lalineno(1), 
	la(0), 
	curTok(0), 
	curToki(-1), 
	atBof(1), 
	left_posinfile(0), 
	theWindow(),
	inf(0), 
	thefilename()
{
}

Lexer::~Lexer()
{
	if (frozen) 
		DestroyingFrozenLexer.raise("Attempt to destroy a frozen Lexer!"); 
}

char Lexer::peek()
{
	if (inf == 0)
	{
		UnattachedLexer.raise("Attempt to peek() in unattached Lexer!");
		return 0;
	}
	if (inf->eof()) 
		return 0; 
	else 
		return inf->peek(); 
}

int Lexer::resize(int i)
{
	if (i >= 0) 
	{
		extend(i - theWindow.length() + 1);
		return 1;
	}
// This doesn't work, since adding Bofs will throw off any outstanding
// absolute positions, and it won't make i a valid absolute position
// in any case.
//	if (atBof)
//	{
//		addBofs(-i);
//		return 1;
//	}
	DiscardedToken.raise("Attempt to go to/get/insert before a discarded token in Lexer!");
	return 0;
}

// This is the only place in all the code where Tokens 
// are added to the left edge of the window (other than
// the initial put to the empty window upon attachment).
//
void Lexer::addBofs(int i)
{
	while (i-- > 0)
	{
		Token *t = new Token;
		t->type = BOF;
		theWindow.unget(t);
		--left_posinfile;
		++curToki;
	}
}

void Lexer::extend(int i)
{
	while (i-- > 0) 
	{ 
		Token *t = gettok();
		theWindow.put(t); 
		if (verboselevel > 1) cerr << *t << endl;
	}
}

void Lexer::move(int i)
{ 
	if (i != 0 && resize(absI(i))) 
	{
	  	curToki += i; 
	  	curTok = theWindow[(unsigned)curToki]; 
	  	if (thetrailsize != infinity) 
			implicitContract(curToki - thetrailsize);
	  	if (verboselevel == 1) 
			cerr << *curTok << endl;
	}
}

void Lexer::insertAfterAbs(const Token *t, int i)
{ 
	if ((i == -1) || resize(i)) 
	{
		List_of_piter<Token> theWindowp(theWindow);
		theWindowp.reset(i+1);
		theWindowp.insert_next((Token*&)t);
		if (i < curToki) 
			curToki++;
		if (verboselevel > 1) 
			cerr << *t << " (inserted at " << i << ")" << endl;
	}
}

// This is the only place in all the code where Tokens 
// fall off the left edge of the window.
//
void Lexer::dropLeftmostToken(ContractAction ca)
{
	assert(theWindow.length() > 0);
	Token *t = theWindow.get();
	++left_posinfile;
	--curToki;
	if (t->type != BOF)
	{
		if (ca)
			(*ca)(t);
		atBof = 0;
	}
	delete t;
}

int Lexer::docontract(int i, ContractAction ca, int is_explicit)
{
	if (is_explicit && frozen == 2) 
	{
		ContractingFrozenLexer.raise("Attempt to explicitly contract a completely frozen Lexer!");
		return 0;
	}
	int n = 0;
	if (is_explicit || !frozen) 
	{
		while (i-- > 0 && curToki > 0)
		{ 
			dropLeftmostToken(ca);
			n++; 
		}
	}
	return n;
}

Token *Lexer::windowAbs(int i)
{ 
	if (i == curToki) return curTok;
	else if (resize(i)) return theWindow[(unsigned)i]; 
	else return 0;
}

int Lexer::handshake(int type, int i)
{ 
	if (((Token *)(theWindow[(unsigned)absI(i)]))->type != type) 
	{
		BadHandshake.raise("Bad handshake with Lexer!");
		return 0;
	}
	return 1;
}

char Lexer::in()
{ 
	if (inf == 0)
	{
		UnattachedLexer.raise("Attempt to in() in unattached Lexer!");
		return 0;
	}
	if (la == '\n') 
		lalineno++; 
	if (inf->eof() || !inf->get(la))
		la = 0;
	return la;		
}

void Lexer::printWindow(int verbose) //const
{ 
	if (verbose)
		(ostream&)cerr << theWindow << ", current token == " << curToki;
	else {
		List_of_piter<Token> theWindowp(theWindow);
		for (theWindowp.reset(); !theWindowp.at_end(); theWindowp.step_next()) 
		{
			cerr << theWindowp.peek_next()->ws;
			if (theWindowp.position() == curToki) 
			{
				cerr << ">>>>";
				cerr << theWindowp.peek_next()->lexeme;
				cerr << "<<<<";
			} 
			else 
			{
				cerr << theWindowp.peek_next()->lexeme;
			}
		}
	}
}

static int byebye(const char *s)
{
	cout << endl;
	cerr << s << endl;
	abort();
	return 0;
}

Objection Lexer::DestroyingFrozenLexer(byebye);
Objection Lexer::ContractingFrozenLexer(byebye);
Objection Lexer::DiscardedToken(byebye);
Objection Lexer::BadHandshake(byebye);
Objection Lexer::UnattachedLexer(byebye);

« April 2024 »
Su Mo Tu We Th Fr Sa
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30
 

Powered by Plone CMS, the Open Source Content Management System

This site conforms to the following standards: