Example #1
0
File: node.cpp Project: OPM/IFEM
// Parse
void VariableNode::Parse(Parser &parser, Parser::size_type start, Parser::size_type end,
        Parser::size_type v1)
{
    // Check some basic syntax
    if(start != end)
    {
        SyntaxException e;
        
        e.SetStart(parser[start].GetStart());
        e.SetEnd(parser[end].GetEnd());
        throw(e);
    }
        
    // Get value list
    ValueList *vlist = m_expr->GetValueList();
    if(vlist == 0)
    {
        NoValueListException e;
        
        e.SetStart(parser[start].GetStart());
        e.SetEnd(parser[start].GetEnd());
        throw(e);
    }
    
    // Get name
    string ident = parser[start].GetIdentifier();
    
    // Get address
    double *vaddr = vlist->GetAddress(ident);
    
    if(vaddr == 0)
    {
        // If it does not already exist, try to create it
        vlist->Add(ident);
        vaddr = vlist->GetAddress(ident);
    }
        
    if(vaddr == 0)
    {
        NotFoundException e(ident);
        
        e.SetStart(parser[start].GetStart());
        e.SetEnd(parser[start].GetEnd());
        throw(e);
    }
        
    // Set information
    m_var = vaddr;
}            
Example #2
0
File: node.cpp Project: OPM/IFEM
// Parse
void ValueNode::Parse(Parser &parser, Parser::size_type start, Parser::size_type end,
        Parser::size_type v1)
{
    // Check basic syntax
    if(start != end)
    {
        SyntaxException e;
        
        e.SetStart(parser[start].GetStart());
        e.SetEnd(parser[end].GetEnd());
        throw(e);
    }
        
    // Set info
    m_val = parser[start].GetValue();
}    
Example #3
0
File: node.cpp Project: OPM/IFEM
// Parse
void NegateNode::Parse(Parser &parser, Parser::size_type start, Parser::size_type end,
        Parser::size_type v1)
{
    // Check some basic syntax
    if(start != v1 || v1 >= end)
    {
        SyntaxException e;
        
        e.SetStart(parser[start].GetStart());
        e.SetEnd(parser[end].GetEnd());
        throw(e);
    }
        
    // Parse sides
    aptr(Node) right(parser.ParseRegion(v1 + 1, end));
    
    m_rhs = right.release();
}
Example #4
0
File: node.cpp Project: OPM/IFEM
// Parse
void ExponentNode::Parse(Parser &parser, Parser::size_type start, Parser::size_type end,
        Parser::size_type v1)
{
    // Check some basic syntax
    if(v1 <= start || v1 >= end)
    {
        SyntaxException e;
        
        e.SetStart(parser[start].GetStart());
        e.SetEnd(parser[end].GetEnd());
        throw(e);
    }
        
    // Parse sides
    aptr(Node) left(parser.ParseRegion(start, v1 - 1));
    aptr(Node) right(parser.ParseRegion(v1 + 1, end));
    
    m_lhs = left.release();
    m_rhs = right.release();
}    
Example #5
0
File: node.cpp Project: OPM/IFEM
// Parse expression
void FunctionNode::Parse(Parser &parser, Parser::size_type start, Parser::size_type end,
        Parser::size_type v1)
{
    Parser::size_type pos, last;
    int plevel = 0;
    
    // Sanity check (start/end are function parenthesis)
    if(start >= end)
        throw(SyntaxException());
        
    // Look
    last = start + 1;
    for(pos = start + 1; pos <= end && start + 1 != end; pos++)
    {
        switch(parser[pos].GetType())
        {
            case Token::TypeOpenParenthesis:
            {
                plevel++;
                break;
            };
                
            case Token::TypeComma:
            case Token::TypeCloseParenthesis:            
            {
                // Handle Close parenthesis for all but the last one at the end
                if(parser[pos].GetType() == Token::TypeCloseParenthesis && pos != end)
                {
                    plevel--;
                
                    if(plevel < 0)
                    {
                        UnmatchedParenthesisException e;
                
                        e.SetStart(parser[pos].GetStart());
                        e.SetEnd(parser[pos].GetEnd());
            
                        throw(e);
                    }
                    
                    break;                    
                }
                    
                // Handle comma, or if it was the ending parenthesis treat it like comma
                if(plevel == 0)
                {
                    if(pos > last)
                    {
                        // reference parameter?
                        if(parser[last].GetType() == Token::TypeAmpersand)
                        {
                            // Reference parameter, check position and type of next parameter
                            if(last == pos - 2 && parser[last + 1].GetType() == Token::TypeIdentifier)
                            {
                                // Get value list
                                ValueList *vlist = m_expr->GetValueList();
                                if(vlist == 0)
                                {
                                    NoValueListException e;
                                    
                                    e.SetStart(parser[last + 1].GetStart());
                                    e.SetEnd(parser[last + 1].GetEnd());
                                    throw(e);
                                }
                                    
                                // Get name
                                string ident = parser[last + 1].GetIdentifier();
                                
                                // Make sure it is not a constant
                                if(vlist->IsConstant(ident))
                                {
                                    ConstantReferenceException e(ident);
                                    
                                    e.SetStart(parser[last + 1].GetStart());
                                    e.SetEnd(parser[last + 1].GetEnd());
                                    throw(e);
                                }
                                    
                                // Get address
                                double *vaddr = vlist->GetAddress(ident);
                                if(vaddr == 0)
                                {
                                    // Try to add it and get again
                                    vlist->Add(ident);
                                    vaddr = vlist->GetAddress(ident);
                                }
                                    
                                if(vaddr == 0)
                                {
                                    NotFoundException e(ident);
                                    
                                    e.SetStart(parser[last + 1].GetStart());
                                    e.SetEnd(parser[last + 1].GetEnd());
                                    
                                    throw(e);
                                }
                                    
                                // Add it
                                m_refs.push_back(vaddr);
                            }
                            else
                            {
                                SyntaxException e;
                                
                                e.SetStart(parser[last].GetStart());
                                e.SetEnd(parser[pos].GetEnd());
                                throw(e);
                            }
                        } // TypeAmpersand
                        else
                        {
                            // Create node
                            aptr(Node) n(parser.ParseRegion(last, pos - 1));
                            m_nodes.push_back(n.get());
                            n.release();
                        }
                    }
                    else
                    {
                        SyntaxException e;
                        
                        e.SetStart(parser[pos].GetStart());
                        e.SetEnd(parser[pos].GetEnd());
                        throw(e);
                    }
                    
                    last = pos + 1;
                }
                    
                break;
            }

            default:
                break;
        }
    }
        
    // plevel should be zero
    if(plevel != 0)
    {
        UnmatchedParenthesisException e;
        
        e.SetStart(parser[end].GetStart());
        e.SetEnd(parser[end].GetEnd());
        throw(e);        
    }


    // Check argument count
    if(m_argMin != -1 && m_nodes.size() < (vector<Node*>::size_type)m_argMin)
    {
        InvalidArgumentCountException e(GetName());
        
        e.SetStart(parser[start].GetStart());
        e.SetEnd(parser[end].GetEnd());
        throw(e);
    }
        
    if(m_argMax != -1 && m_nodes.size() > (vector<Node*>::size_type)m_argMax)
    {
        InvalidArgumentCountException e(GetName());
        
        e.SetStart(parser[start].GetStart());
        e.SetEnd(parser[end].GetEnd());
        throw(e);
    }
        
    if(m_refMin != -1 && m_refs.size() < (vector<double*>::size_type)m_refMin)
    {
        InvalidArgumentCountException e(GetName());
        
        e.SetStart(parser[start].GetStart());
        e.SetEnd(parser[end].GetEnd());
        throw(e);
    }
        
    if(m_refMax != -1 && m_refs.size() > (vector<double*>::size_type)m_refMax)
    {
        InvalidArgumentCountException e(GetName());
        
        e.SetStart(parser[start].GetStart());
        e.SetEnd(parser[end].GetEnd());
        throw(e);
    }
}    
Example #6
0
File: node.cpp Project: OPM/IFEM
// Parse
void AssignNode::Parse(Parser &parser, Parser::size_type start, Parser::size_type end,
        Parser::size_type v1)
{
    // Check some basic syntax
    if(v1 != start + 1 || v1 >= end)
    {
        SyntaxException e;
        
        e.SetStart(parser[start].GetStart());
        e.SetEnd(parser[end].GetEnd());
        throw(e);
    }
        
    // Get the value list
    ValueList *vlist = m_expr->GetValueList();
    if(vlist == 0)
    {
        NoValueListException e;
        
        e.SetStart(parser[start].GetStart());
        e.SetEnd(parser[start].GetEnd());
        throw(e);
    }
        
    // Determine variable name
    string ident = parser[start].GetIdentifier();
    
    // Make sure it is not a constant
    if(vlist->IsConstant(ident))
    {
        ConstantAssignException e(ident);
        
        e.SetStart(parser[start].GetStart());
        e.SetEnd(parser[v1].GetEnd());
        throw(e);
    }
        
    // Get address
    double *vaddr = vlist->GetAddress(ident);
    
    if(vaddr == 0)
    {
        // If it does not already exist, try to create it
        vlist->Add(ident);
        vaddr = vlist->GetAddress(ident);
    }
        
    if(vaddr == 0)
    {
        NotFoundException e(ident);
        
        e.SetStart(parser[start].GetStart());
        e.SetEnd(parser[start].GetEnd());
        throw(e);
    }
        
    // Parse the node (will throw if it can not parse)
    aptr(Node) n(parser.ParseRegion(v1 + 1, end));
    
    // Set data
    m_var = vaddr;
    m_rhs = n.release();
}    
Example #7
0
File: node.cpp Project: OPM/IFEM
// Parse
void MultiNode::Parse(Parser &parser, Parser::size_type start, Parser::size_type end,
        Parser::size_type v1)
{
    Parser::size_type pos, last;
    int plevel = 0;
    
    // Sanity check
    if(start >= end)
        throw(SyntaxException());
        
    // Look
    last = start;
    for(pos = start; pos <= end; pos++)
    {
        switch(parser[pos].GetType())
        {
            case Token::TypeOpenParenthesis:
            {
                plevel++;
                break;
            };
                
            case Token::TypeCloseParenthesis:
            {
                plevel--;
                
                if(plevel < 0)
                {
                    UnmatchedParenthesisException e;
                    
                    e.SetStart(parser[pos].GetStart());
                    e.SetEnd(parser[pos].GetEnd());
                    throw(e);
                }
                    
                break;
            }
                
            case Token::TypeSemicolon:
            {
                if(plevel == 0)
                {
                    if(pos > last)
                    {
                        // Everything from last to pos - 1
                        aptr(Node) n(parser.ParseRegion(last, pos - 1));
                        m_nodes.push_back(n.get());
                        n.release();
                    }
                    else
                    {
                        SyntaxException e;
                        
                        e.SetStart(parser[last].GetStart());
                        e.SetEnd(parser[pos].GetEnd());
                        throw(e);
                    }
                    
                    last = pos + 1;
                }
                    
                break;
            }
          default:
                break;
        }
    }
        
    // plevel should be zero
    if(plevel != 0)
    {
        UnmatchedParenthesisException e;
        
        e.SetStart(parser[pos].GetStart());
        e.SetEnd(parser[pos].GetEnd());
        throw(e);
    }
        
    // If the end was not a semicolon, test it as well
    if(last < end + 1)
    {
        aptr(Node) n(parser.ParseRegion(last, end));
        m_nodes.push_back(n.get());
        n.release();
    }        
}
Example #8
0
// Parse a region of tokens
Node *Parser::ParseRegion(Parser::size_type start, Parser::size_type end)
{
    size_type pos;
    size_type fgopen = (size_type)-1;
    size_type fgclose = (size_type)-1;
    size_type assignindex = (size_type)-1;
    size_type addsubindex = (size_type)-1;
    size_type muldivindex = (size_type)-1;
    size_type posnegindex = (size_type)-1;
    size_type expindex = (size_type)-1;
    bool multiexpr = false;
    int plevel = 0;
    
    // Check simple syntax
    if(start > end)
        throw(SyntaxException());
        
    // Scan through tokens
    for(pos = start; pos <= end; pos++)
    {
        switch(m_tokens[pos].GetType())
        {
            case Token::TypeOpenParenthesis:
            {
                plevel++;
                
                // Opening of first group?
                if(plevel == 1 && fgopen == (size_type)-1)
                    fgopen = pos;
                    
                break;
            };
                
            case Token::TypeCloseParenthesis:
            {
                plevel--;
                
                // First group closed?
                if(plevel == 0 && fgclose == (size_type)-1)
                    fgclose = pos;
                    
                if(plevel < 0)
                {
                    UnmatchedParenthesisException e;
                    
                    e.SetStart(m_tokens[pos].GetStart());
                    e.SetEnd(m_tokens[pos].GetEnd());
                    throw(e);
                }
                    
                break;
            }
                
            case Token::TypeEqual:
            {
                if(plevel == 0)
                {
                    if(assignindex == (size_type)-1)
                        assignindex = pos;
                }
                    
                break;
            }
                
            case Token::TypeAsterisk:
            case Token::TypeForwardSlash:
            {
                if(plevel == 0)
                {
                    muldivindex = pos;
                }
                    
                break;
            }
                
            case Token::TypeHat:
            {
                if(plevel == 0)
                {
                    expindex = pos;
                }
                
                break;
            }
                
            case Token::TypePlus:
            case Token::TypeHyphen:
            {
                if(plevel == 0)
                {
                    if(pos == start)
                    {
                        // Positive or negative sign
                        if(posnegindex == (size_type)-1)
                            posnegindex = pos;
                    }
                    else
                    {
                        // What is before us
                        switch(m_tokens[pos - 1].GetType())
                        {
                            case Token::TypeEqual:
                            case Token::TypePlus:
                            case Token::TypeHyphen:
                            case Token::TypeAsterisk:
                            case Token::TypeForwardSlash:
                            case Token::TypeHat:
                                // After any of these, we are a positive/negative
                                if(posnegindex == (size_type)-1)
                                    posnegindex = pos;
                                break;
                                
                            default:
                                // After any other, we are addition/subtration
                                addsubindex = pos;
                                break;
                        }
                    }
                }
                    
                break;
            }
                
            case Token::TypeSemicolon:
            {
                if(plevel == 0)
                {
                    multiexpr = true;
                }
                
                break;
            }
        }
    }
        
    // plevel should be 0
    if(plevel != 0)
    {
        UnmatchedParenthesisException e;
        
        e.SetStart(end);
        e.SetEnd(end);
        throw(e);
    }
        
    // Parse in certain order to maintain order of operators
    
    // Multi-expression first
    if(multiexpr)
    {
        auto_ptr<Node> n(new MultiNode(m_expr));
        n->Parse(*this, start, end);
        return n.release();
    }
    else if(assignindex != (size_type)-1)
    {
        // Assignment next
        auto_ptr<Node> n(new AssignNode(m_expr));
        n->Parse(*this, start, end, assignindex);
        return n.release();
    }
    else if(addsubindex != (size_type)-1)
    {
        // Addition/subtraction next
        if(m_tokens[addsubindex].GetType() == Token::TypePlus)
        {
            // Addition
            auto_ptr<Node> n(new AddNode(m_expr));
            n->Parse(*this, start, end, addsubindex);
            return n.release();
        }
        else
        {
            // Subtraction
            auto_ptr<Node> n(new SubtractNode(m_expr));
            n->Parse(*this, start, end, addsubindex);
            return n.release();
        }
    }
    else if(muldivindex != (size_type)-1)
    {
        // Multiplication/division next
        
        if(m_tokens[muldivindex].GetType() == Token::TypeAsterisk)
        {
            // Multiplication
            auto_ptr<Node> n(new MultiplyNode(m_expr));
            n->Parse(*this, start, end, muldivindex);
            return n.release();
        }
        else
        {
            // Division
            auto_ptr<Node> n(new DivideNode(m_expr));
            n->Parse(*this, start, end, muldivindex);
            return n.release();
        }
    }
    else if(posnegindex == start)
    {
        // Positive/negative next, must be at start and check before exponent
        if(m_tokens[posnegindex].GetType() == Token::TypePlus)
        {
            // Positive
            return ParseRegion(posnegindex + 1, end);
        }
        else
        {
            auto_ptr<Node> n(new NegateNode(m_expr));
            n->Parse(*this, start, end, posnegindex);
            return n.release();
        }
    }
    else if(expindex != (size_type)-1)
    {
        // Exponent
        auto_ptr<Node> n(new ExponentNode(m_expr));
        n->Parse(*this, start, end, expindex);
        return n.release();
    }
    else if(posnegindex != (size_type)-1)
    {
        // Check pos/neg again.  After testing for exponent, a pos/neg
        // at plevel 0 is syntax error
        SyntaxException e;
        
        e.SetStart(m_tokens[posnegindex].GetStart());
        e.SetEnd(m_tokens[posnegindex].GetEnd());
        throw(e);
    }
    else if(fgopen == start)
    {
        // Group parenthesis, make sure something in between them
        if(fgclose == end && fgclose > fgopen + 1)
        {
            return ParseRegion(fgopen + 1, fgclose - 1);
        }
        else
        {
            SyntaxException e;
            
            e.SetStart(m_tokens[fgopen].GetStart());
            if(fgclose == (size_type)-1)
                e.SetEnd(m_tokens[fgopen].GetEnd());
            else
                e.SetEnd(m_tokens[fgclose].GetEnd());
                
            throw(e);
        }
    }
    else if(fgopen == start + 1)
    {
        // Function
        if(fgclose == end)
        {
            // Find function list
            FunctionList *flist = m_expr->GetFunctionList();
            
            if(flist == 0)
            {
                NoFunctionListException e;
        
                e.SetStart(m_tokens[start].GetStart());
                e.SetEnd(m_tokens[start].GetEnd());
                throw(e);
            }
                
            // Get name
            string ident = m_tokens[start].GetIdentifier();
            
            // Create function node
            auto_ptr<FunctionNode> n(flist->Create(ident, m_expr));
            
            if(n.get())
            {
                n->Parse(*this, fgopen, fgclose);
            }
            else
            {
                NotFoundException e(ident);
        
                e.SetStart(m_tokens[start].GetStart());
                e.SetEnd(m_tokens[start].GetEnd());
                throw(e);                
            }
                
            return n.release();
        }
        else
        {
            SyntaxException e;
        
            e.SetStart(m_tokens[fgopen].GetStart());
            if(fgclose == (size_type)-1)
                e.SetEnd(m_tokens[fgopen].GetEnd());
            else
                e.SetEnd(m_tokens[fgclose].GetEnd());    
                
            throw(e);
        }
    }
    else if(start == end)
    {
        // Value, variable, or constant
        
        if(m_tokens[start].GetType() == Token::TypeIdentifier)
        {
            // Variable/constant
            auto_ptr<Node> n(new VariableNode(m_expr));
            n->Parse(*this, start, end);
            return n.release();    
        }
        else
        {
            // Value
            auto_ptr<Node> n(new ValueNode(m_expr));
            n->Parse(*this, start, end);
            return n.release();
        }
    }
    else
    {
        // Unknown, syntax
        SyntaxException e;
        
        e.SetStart(m_tokens[pos].GetStart());
        e.SetEnd(m_tokens[pos].GetEnd());
        
        throw(e);
    }
}