Example #1
0
void Expr::Parse(void) {
    Expr *e = AllocExpr();
    e->op = ALL_RESOLVED;
    PushOperator(e);

    for(;;) {
        Expr *n = Next();
        if(!n) throw "end of expression unexpected";

        if(n->op == CONSTANT) {
            PushOperand(n);
            Consume();
        } else if(n->op == PAREN && n->c == '(') {
            Consume();
            Parse();
            n = Next();
            if(n->op != PAREN || n->c != ')') throw "expected: )";
            Consume();
        } else if(n->op == UNARY_OP) {
            PushOperator(n);
            Consume();
            continue;
        } else if(n->op == BINARY_OP && n->c == '-') {
            // The minus sign is special, because it might be binary or
            // unary, depending on context.
            n->op = UNARY_OP;
            n->c = 'n';
            PushOperator(n);
            Consume();
            continue;
        } else {
            throw "expected expression";
        }

        n = Next();
        if(n && n->op == BINARY_OP) {
            ReduceAndPush(n);
            Consume();
        } else {
            break;
        }
    }

    while(TopOperator()->op != ALL_RESOLVED) {
        Reduce();
    }
    PopOperator(); // discard the ALL_RESOLVED marker
}
Example #2
0
void Expr::ReduceAndPush(Expr *n) {
    while(Precedence(n) <= Precedence(TopOperator())) {
        Reduce();
    }
    PushOperator(n);
}
/**
 * Function ReadParam
 * Read one aperture macro parameter
 * a parameter can be:
 *      a number
 *      a reference to an aperture definition parameter value: $1 ot $3 ...
 * a parameter definition can be complex and have operators between numbers and/or other parameter
 * like $1+3 or $2x2..
 * Note minus sign is not always an operator. It can be the sign of a value.
 * Parameters are separated by a comma ( of finish by *)
 * @param aText = pointer to the parameter to read. Will be modified to point to the next field
 * @return true if a param is read, or false
 */
bool AM_PARAM::ReadParam( char*& aText  )
{
    bool found = false;
    int ivalue;
    double dvalue;
    bool end = false;

    while( !end )
    {
        switch( *aText )
        {
            case ',':
                aText++;
                // fall through
            case 0:     // EOL
            case '*':   // Terminator in a gerber command
                end = true;
                break;

            case ' ':
                aText++;
                break;

            case '$':
                // defered value defined later, in ADD command which define defered parameters
                ++aText;
                ivalue = ReadInt( aText, false );
                if( m_index < 1 )
                    SetIndex( ivalue );
                PushOperator( PUSHPARM, ivalue );
                found = true;
                break;

            case '/':
                PushOperator( DIV );
                aText++;
                break;

            case 'x':
            case 'X':
                PushOperator( MUL );
                aText++;
                break;

            case '-':
            case '+':
                // Test if this is an operator between 2 params, or the sign of a value
                if( m_paramStack.size() > 0 && !m_paramStack.back().IsOperator() )
                {   // Seems an operator
                    PushOperator( *aText == '+' ? ADD : SUB );
                    aText++;
                }
                else
                {   // seems the sign of a value
                    dvalue = ReadDouble( aText, false );
                    PushOperator( PUSHVALUE, dvalue );
                    found = true;
                }
                break;

            case '=':   // A local definition found like $4=$3/2
                // At this point, one defered parameter is expected to be read.
                // this parameter value (the index) is stored in m_index.
                // The list of items is cleared
                aText++;
                m_paramStack.clear();
                found = false;
                break;

            default:
                dvalue = ReadDouble( aText, false );
                PushOperator( PUSHVALUE, dvalue );
                found = true;
                break;
        }
    }

    return found;
}