Beispiel #1
0
/** Do the work of getting the next element, making sure that it's
 *  a tree node or subtree.  Deal with the optimization of single-
 *  element list versus list of size > 1.  Throw an exception (or something similar)
 *  if the stream is empty or we're out of elements and size>1.
 *  You can override in a subclass if necessary.
 */
static void *
_next    (pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream)
{
    ANTLR3_UINT32	s;
    pANTLR3_BASE_TREE	t;

    s = stream->size(stream);

    if (s == 0)
    {
        // This means that the stream is empty
        //
        return (pANTLR3_BASE_TREE)ANTLR3_FUNC_PTR(NULL);	// Caller must cope with this
    }

    // Traversed all the available elements already?
    //
    if (stream->cursor >= s)
    {
        if (s == 1)
        {
            // Special case when size is single element, it will just dup a lot
            //
            return stream->singleElement;
        }

        // OUt of elements and the size is not 1, so we cannot assume
        // that we just duplicate the entry n times (such as ID ent+ -> ^(ID ent)+)
        // THis means we ran out of elements earlier than was expected.
        //
        return (pANTLR3_BASE_TREE)ANTLR3_FUNC_PTR(NULL);	// Caller must cope with this
    }

    // Elements available either for duping or just available
    //
    if (stream->singleElement != NULL)
    {
        stream->cursor++;   // Cursor advances even for single element as this tells us to dup()
        return stream->toTree(stream, stream->singleElement);
    }

    // More than just a single element so we extract it from the
    // vector.
    //
    t = stream->toTree(stream, stream->elements->get(stream->elements, stream->cursor+1));  // TODO: Why not just cursor++ ?
    stream->cursor++;
    return t;
}
Beispiel #2
0
/* Functions for creating streams
 */
static  pANTLR3_REWRITE_RULE_ELEMENT_STREAM
antlr3RewriteRuleElementStreamNewAE(pANTLR3_BASE_TREE_ADAPTOR adaptor, pANTLR3_UINT8 description)
{
    pANTLR3_REWRITE_RULE_ELEMENT_STREAM	stream;

    /* First job is to create the memory we need.
     */
    stream	= (pANTLR3_REWRITE_RULE_ELEMENT_STREAM) ANTLR3_MALLOC((size_t)(sizeof(ANTLR3_REWRITE_RULE_ELEMENT_STREAM)));

    if	(stream == NULL)
    {
        return	(pANTLR3_REWRITE_RULE_ELEMENT_STREAM)ANTLR3_FUNC_PTR(ANTLR3_ERR_NOMEM);
    }

    /* Populate the generic interface */

    stream->reset	    = reset;
    stream->add		    = add;
    stream->next	    = next;
    stream->_next	    = _next;
    stream->hasNext	    = hasNext;
    stream->size	    = size;
    stream->getDescription  = getDescription;
    stream->free	    = freeRS;

    /* Install the description
     */
    stream->elementDescription	= adaptor->strFactory->newStr8(adaptor->strFactory, description);

    /* Install the adaptor
     */
    stream->adaptor		= adaptor;

    return stream;
}
Beispiel #3
0
/** \brief Rewind the lexer input to the state specified by the supplied mark.
 * 
 * \param[in] input Input stream context pointer
 *
 * \remark
 * Assumes ASCII (or at least, 8 Bit) input stream.
 */
static void
antlr3AsciiSeek	(pANTLR3_INT_STREAM is, ANTLR3_MARKER seekPoint)
{
	ANTLR3_INT32   count;
	pANTLR3_INPUT_STREAM input;

	input   = ANTLR3_FUNC_PTR(((pANTLR3_INPUT_STREAM) is->super));

	/* If the requested seek point is less than the current
	* input point, then we assume that we are resetting from a mark
	* and do not need to scan, but can just set to there.
	*/
	if	(seekPoint <= (ANTLR3_MARKER)(input->nextChar))
	{
		input->nextChar	= ((pANTLR3_UINT8) seekPoint);
	}
	else
	{
		count	= (ANTLR3_UINT32)(seekPoint - (ANTLR3_MARKER)(input->nextChar));

		while (count--)
		{
			is->consume(is);
		}
	}
}
Beispiel #4
0
/**
 * \brief
 * Creates a new ANTLR3 exception structure
 * 
 * \param[in] exception
 * One of the ANTLR3_xxx_EXCEPTION indicators such as #ANTLR3_RECOGNITION_EXCEPTION
 * 
 * \param[in] message
 * Pointer to message string 
 * 
 * \param[in] freeMessage
 * Set to ANTLR3_TRUE if the message parameter should be freed by a call to 
 * ANTLR3_FREE() when the exception is destroyed.
 * 
 * \returns
 * Pointer to newly initialized exception structure, or an ANTLR3_ERR_xx defined value
 * upon failure.
 * 
 * An exception is 'thrown' by a recognizer  when input is seen that is not predicted by
 * the grammar productions or when some other error condition occurs. In C we do not have
 * the luxury of try and catch blocks, so exceptions are added in the order they occur to 
 * a list in the baserecognizer structure. The last one to be thrown is inserted at the head of
 * the list and the one currently installed is pointed to by the newly installed exception.
 * 
 * \remarks
 * After an exception is created, you may add a pointer to your own structure and a pointer
 * to a function to free this structure when the exception is destroyed.
 * 
 * \see
 * ANTLR3_EXCEPTION
 */
pANTLR3_EXCEPTION
antlr3ExceptionNew(ANTLR3_UINT32 exception, void * name, void * message, ANTLR3_BOOLEAN freeMessage)
{
    pANTLR3_EXCEPTION	ex;

    /* Allocate memory for the structure
     */
    ex	= (pANTLR3_EXCEPTION) ANTLR3_MALLOC(sizeof(ANTLR3_EXCEPTION));

    /* Check for memory allocation
     */
    if	(ex == NULL)
    {
	return	(pANTLR3_EXCEPTION)ANTLR3_FUNC_PTR(ANTLR3_ERR_NOMEM);
    }

    ex->name		= name;		/* Install exception name	*/
    ex->type		= exception;	/* Install the exception number	*/
    ex->message		= message;	/* Install message string	*/
    
    /* Indicate whether the string should be freed if exception is destroyed    
     */
    ex->freeMessage	= freeMessage;

    /* Install the API
     */
    ex->print	    =  antlr3ExceptionPrint;
    ex->freeEx	    =  antlr3ExceptionFree;

    return ex;
}
Beispiel #5
0
/** \brief Return the input element assuming an 8 bit ascii input
 *
 * \param[in] input Input stream context pointer
 * \param[in] lt 1 based offset of next input stream element
 *
 * \return Next input character in internal ANTLR3 encoding (UTF32)
 */
static void * 
antlr3AsciiLT(pANTLR3_INPUT_STREAM input, ANTLR3_INT32 lt)
{
    /* Casting is horrible but it means no warnings and LT should never be called
     * on a character stream anyway I think. If it is then, the void * will need to be 
     * cast back in a similar manner. Yuck! But this means that LT for Token streams and
     * tree streams is correct.
     */
    return (ANTLR3_FUNC_PTR(input->istream->_LA(input->istream, lt)));
}
/** A simple filter mechanism whereby you can tell this token stream
 *  to force all tokens of type ttype to be on channel.  For example,
 *  when interpreting, we cannot execute actions so we need to tell
 *  the stream to force all WS and NEWLINE to be a different, ignored,
 *  channel.
 */
static void		    
setTokenTypeChannel (pANTLR3_COMMON_TOKEN_STREAM tokenStream, ANTLR3_UINT32 ttype, ANTLR3_UINT32 channel)
{
    if	(tokenStream->channelOverrides == NULL)
    {
	tokenStream->channelOverrides	= antlr3ListNew(10);
    }

    /* We add one to the channel so we can distinguish NULL as being no entry in the
     * table for a particular token type.
     */
    tokenStream->channelOverrides->put(tokenStream->channelOverrides, ttype, ANTLR3_FUNC_PTR((ANTLR3_UINT32)channel + 1), NULL);
}
static void		    
discardTokenType    (pANTLR3_COMMON_TOKEN_STREAM tokenStream, ANTLR3_INT32 ttype)
{
    if	(tokenStream->discardSet == NULL)
    {
	tokenStream->discardSet	= antlr3ListNew(31);
    }

    /* We add one to the channel so we can distinguish NULL as being no entry in the
     * table for a particular token type. We could use bitsets for this I suppose too.
     */
    tokenStream->discardSet->put(tokenStream->discardSet, ttype, ANTLR3_FUNC_PTR((ANTLR3_UINT32)ttype + 1), NULL);
}
Beispiel #8
0
ANTLR3_API pANTLR3_COMMON_TOKEN
antlr3CommonTokenNew(ANTLR3_UINT32 ttype)
{
    pANTLR3_COMMON_TOKEN    token;
    
    /* Create a raw token with the interface installed
     */
    token   = newToken();

    if	(token != (pANTLR3_COMMON_TOKEN)ANTLR3_FUNC_PTR(ANTLR3_ERR_NOMEM))
    {
	token->setType(token, ttype);
    }

    /* All good
     */
    return  token;
}
Beispiel #9
0
static pANTLR3_REWRITE_RULE_ELEMENT_STREAM
antlr3RewriteRuleElementStreamNewAEE(pANTLR3_BASE_TREE_ADAPTOR adaptor, pANTLR3_UINT8 description, void * oneElement)
{
    pANTLR3_REWRITE_RULE_ELEMENT_STREAM	stream;

    /* First job is to create the memory we need.
     */
    stream	= antlr3RewriteRuleElementStreamNewAE(adaptor, description);

    if (stream == (pANTLR3_REWRITE_RULE_ELEMENT_STREAM)ANTLR3_FUNC_PTR(ANTLR3_ERR_NOMEM))
    {
        return stream;
    }

    /* Stream seems good so we need to add the supplied element
     */
    stream->add(stream, oneElement, NULL);
    return stream;
}
Beispiel #10
0
/** \brief Use the contents of an operating system file as the input
 *         for an input stream.
 *
 * \param fileName Name of operating system file to read.
 * \return
 *	- Pointer to new input stream context upon success
 *	- One of the ANTLR3_ERR_ defines on error.
 */
ANTLR3_API pANTLR3_INPUT_STREAM
antlr3AsciiFileStreamNew(pANTLR3_UINT8 fileName)
{
    /* Pointer to the input stream we are going to create
     */
    pANTLR3_INPUT_STREAM    input;
    ANTLR3_UINT64	    status;

    /* Allocate memory for the input stream structure
     */
    input   = (pANTLR3_INPUT_STREAM)
		    ANTLR3_MALLOC(sizeof(ANTLR3_INPUT_STREAM));

    if	(input == NULL)
    {
	return	(pANTLR3_INPUT_STREAM) ANTLR3_ERR_NOMEM;
    }

    input->fileName  = ANTLR3_STRDUP(fileName);

    /* Structure was allocated correctly, now we can read the file.
     */
    status  = antlr3readAscii(input);

    if	(status != ANTLR3_SUCCESS)
    {
	ANTLR3_FREE(input->fileName);
	ANTLR3_FREE(input);

	return	ANTLR3_FUNC_PTR(status);
    }

    /* Call the common 8 bit ASCII input stream handler
     * intializer type thingy doobry function.
     */
    antlr3AsciiSetupStream(input, ANTLR3_CHARSTREAM);



    return  input;
}
Beispiel #11
0
static	pANTLR3_COMMON_TOKEN	
newToken(void)
{
    pANTLR3_COMMON_TOKEN    token;

    /* Allocate memory for this
     */
    token   = (pANTLR3_COMMON_TOKEN) ANTLR3_MALLOC((size_t)(sizeof(ANTLR3_COMMON_TOKEN)));

    if	(token == NULL)
    {
	return	(pANTLR3_COMMON_TOKEN)ANTLR3_FUNC_PTR(ANTLR3_ERR_NOMEM);
    }

    /* Install the API
     */
    antlr3SetTokenAPI(token);
    token->factoryMade = ANTLR3_FALSE;

    return  token;
}
Beispiel #12
0
ANTLR3_API pANTLR3_TOKEN_FACTORY
antlr3TokenFactoryNew(pANTLR3_INPUT_STREAM input)
{
    pANTLR3_TOKEN_FACTORY   factory;

    /* allocate memory
     */
    factory	= (pANTLR3_TOKEN_FACTORY) ANTLR3_MALLOC((size_t)sizeof(ANTLR3_TOKEN_FACTORY));

    if	(factory == NULL)
    {
	return	(pANTLR3_TOKEN_FACTORY)ANTLR3_FUNC_PTR(ANTLR3_ERR_NOMEM);
    }

    /* Install factory API
     */
    factory->newToken	    =  newPoolToken;
    factory->close	    =  factoryClose;
    factory->setInputStream = setInputStream;
    
    /* Allocate the initial pool
     */
    factory->thisPool	= -1;
    factory->pools	= NULL;
    newPool(factory);

    /* Factory space is good, we now want to initialize our cheating token
     * which one it is initialized is the model for all tokens we manufacture
     */
    antlr3SetTokenAPI(&factory->unTruc);

    /* Set some initial variables for future copying
     */
    factory->unTruc.factoryMade	= ANTLR3_TRUE;
    setInputStream(factory, input);
    
    return  factory;

}
Beispiel #13
0
static pANTLR3_REWRITE_RULE_ELEMENT_STREAM
antlr3RewriteRuleElementStreamNewAEV(pANTLR3_BASE_TREE_ADAPTOR adaptor, pANTLR3_UINT8 description, pANTLR3_VECTOR vector)
{
    pANTLR3_REWRITE_RULE_ELEMENT_STREAM	stream;

    /* First job is to create the memory we need.
     */
    stream	= antlr3RewriteRuleElementStreamNewAE(adaptor, description);

    if (stream == (pANTLR3_REWRITE_RULE_ELEMENT_STREAM)ANTLR3_FUNC_PTR(ANTLR3_ERR_NOMEM))
    {
        return stream;
    }

    /* Stream seems good so we need to install the vector we were
     * given. We assume that someone else is going to free the
     * vector.
     */
    stream->elements	= vector;

    return stream;
}
Beispiel #14
0
ANTLR3_API pANTLR3_REWRITE_RULE_TOKEN_STREAM
antlr3RewriteRuleTokenStreamNewAE(pANTLR3_BASE_TREE_ADAPTOR adaptor, pANTLR3_UINT8 description)
{
    pANTLR3_REWRITE_RULE_TOKEN_STREAM	stream;

    /* First job is to create the memory we need.
     */
    stream	= antlr3RewriteRuleElementStreamNewAE(adaptor, description);

    if (stream == (pANTLR3_REWRITE_RULE_TOKEN_STREAM)ANTLR3_FUNC_PTR(ANTLR3_ERR_NOMEM))
    {
        return stream;
    }

    /* Install the token based overrides
     */
    stream->dup	    = dupTok;
    stream->toTree  = toTreeToken;

    /* No nextNode implementation for a token rewrite stream */
    return stream;
}
Beispiel #15
0
ANTLR3_API pANTLR3_REWRITE_RULE_SUBTREE_STREAM
antlr3RewriteRuleSubtreeStreamNewAEV(pANTLR3_BASE_TREE_ADAPTOR adaptor, pANTLR3_UINT8 description, pANTLR3_VECTOR vector)
{
    pANTLR3_REWRITE_RULE_SUBTREE_STREAM	stream;

    /* First job is to create the memory we need.
     */
    stream	= antlr3RewriteRuleElementStreamNewAEV(adaptor, description, vector);

    if (stream == (pANTLR3_REWRITE_RULE_SUBTREE_STREAM)ANTLR3_FUNC_PTR(ANTLR3_ERR_NOMEM))
    {
        return stream;
    }

    /* Install the token based overrides
     */
    stream->dup		= dupTree;
    stream->toTree	= toTreeTree;
    stream->nextNode	= nextNode;

    return stream;
}
static  void
push                                            (pANTLR3_COMMON_TREE_NODE_STREAM ctns, ANTLR3_INT32 index)
{
        ctns->nodeStack->push(ctns->nodeStack, ANTLR3_FUNC_PTR(ctns->p), NULL); // Save current index
        ctns->tnstream->istream->seek(ctns->tnstream->istream, index);
}
Beispiel #17
0
/** Pointer to a function to return whether the rule has parsed input starting at the supplied 
 *  start index before. If the rule has not parsed input starting from the supplied start index,
 *  then it will return ANTLR3_MEMO_RULE_UNKNOWN. If it has parsed from the suppled start point
 *  then it will return the point where it last stopped parsing after that start point.
 *
 * \remark
 * The rule memos are an ANTLR3_LIST of ANTLR3_LISTS, however if this becomes any kind of performance
 * issue (it probably won't, the hash tables are pretty quick) then we could make a special int only
 * version of the table.
 */
static ANTLR3_UINT64	
getRuleMemoization		    (pANTLR3_BASE_RECOGNIZER recognizer, ANTLR3_UINT32 ruleIndex, ANTLR3_UINT64 ruleParseStart)
{
    /* The rule memos are an ANTLR3_LIST of ANTLR3_LIST.
     */
    pANTLR3_INT_TRIE	ruleList;
    ANTLR3_UINT64	stopIndex;
    pANTLR3_TRIE_ENTRY	entry;

    /* See if we have a list in the ruleMemos for this rule, and if not, then create one
     * as we will need it eventually if we are being asked for the memo here.
     */
    entry	= recognizer->ruleMemo->get(recognizer->ruleMemo, (ANTLR3_UINT64)ruleIndex);

    if	(entry == NULL)
    {
	/* Did not find it, so create a new one for it, with a bit depth based on the 
	 * size of the input stream. We need the bit depth to incorporate the number if
	 * bits required to represen the largest possible stop index in the input, which is the
	 * last character. An int stream is free to return the largest 64 bit offset if it has
	 * no idea of the size, but you should remember that this will cause the leftmost
	 * bit match algorithm to run to 63 bits, whcih will be the whole time spent in the trie ;-)
	 */
	ruleList    = antlr3IntTrieNew(63);	/* Depth is theoretically 64 bits, but probably not ;-)	*/

	if (ruleList != (pANTLR3_INT_TRIE)ANTLR3_ERR_NOMEM)
	{
	    recognizer->ruleMemo->add(recognizer->ruleMemo, (ANTLR3_UINT64)ruleIndex, ANTLR3_HASH_TYPE_STR, 0, ANTLR3_FUNC_PTR(ruleList), freeIntTrie);
	}

	/* We cannot have a stopIndex in a trie we have just created of course
	 */
	return	MEMO_RULE_UNKNOWN;
    }

    ruleList	= (pANTLR3_INT_TRIE) (entry->data.ptr);

    /* See if there is a stop index associated with the supplied start index.
     */
    stopIndex	= 0;

    entry = ruleList->get(ruleList, ruleParseStart);
    if (entry != NULL)
    {
	stopIndex = entry->data.intVal;

    }

    if	(stopIndex == 0)
    {
	return MEMO_RULE_UNKNOWN;
    }

    return  stopIndex;
}