root/trunk/orca/util/cbparse.c

Revision 54, 4.2 kB (checked in by krobillard, 3 years ago)

Now using orDecimal() & orInt() where appropriate.

Line 
1/*============================================================================
2    ORCA - CBParser
3    Copyright (C) 2005-2006  Karl Robillard
4
5    This library is free software; you can redistribute it and/or
6    modify it under the terms of the GNU Lesser General Public
7    License as published by the Free Software Foundation; either
8    version 2.1 of the License, or (at your option) any later version.
9
10    This library is distributed in the hope that it will be useful,
11    but WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13    Lesser General Public License for more details.
14
15    You should have received a copy of the GNU Lesser General Public
16    License along with this library; if not, write to the Free Software
17    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18===========================================================================*/
19
20
21#include "ovalue.h"
22#include "cbparse.h"
23
24
25/*
26   C Block Parse (CBParse) is a small module which scans a block for simple
27   value patterns.  Matched results are handled by C code rather than by the
28   interpreter for maximum speed.
29*/
30
31
32/**
33  ruleSet is a series of rule-id/block pairs.
34  Note that the order of rules is important.  Earlier rules will match before
35  later ones.
36*/
37void cbp_beginParse( CBParser* cbp, OValue* it, OValue* end, OBlock* ruleSet )
38{
39    cbp->error     = 0;
40    cbp->_blockPos = it;
41    cbp->_blockEnd = end;
42
43    // Validate ruleSet.
44    // Set _rules to 0 if not valid so cbp_matchRule() will fail.
45    if( (ruleSet->used < 2) || (ruleSet->used & 1) )
46        cbp->_rules = 0;
47    else
48        cbp->_rules = ruleSet;
49}
50
51
52/**
53  Returns pointer to matched rule-id value or zero if no match was found.
54  If a rule was matched, cbp->values points to the matching values in
55  the input.
56
57  cbp->error will point to unmatched values or be zero if all data found
58  matches the rules given to cbp_beginParse().
59*/
60OValue* cbp_matchRule( CBParser* cbp )
61{
62    OBlock* rule;
63    OValue* rit;
64    OValue* rend;
65    OValue* vmatch;
66    OValue* ruleEnd;
67    OValue* stream;
68
69    if( ! cbp->_rules )
70        return 0;
71
72    if( cbp->_blockPos == cbp->_blockEnd )
73        return 0;
74
75    rit  = cbp->_rules->values;
76    rend = rit + cbp->_rules->used;
77    for( ; rit != rend; ++rit )
78    {
79        ++rit;
80        if( rit->type != OT_BLOCK )
81        {
82            cbp->_rules = 0;
83            return 0;
84        }
85
86        rule = orBLOCK( rit );
87        vmatch  = rule->values;
88        ruleEnd = vmatch + rule->used;
89
90        stream = cbp->_blockPos;
91        for( ; vmatch != ruleEnd; ++vmatch, ++stream )
92        {
93            if( stream == cbp->_blockEnd )
94                break;
95
96            //if( vmatch->type == OT_ANYTYPE )
97            //    continue;
98
99            if( orIs(vmatch, OT_LITWORD) )
100            {
101                if( (orType(stream) != OT_WORD) ||
102                    (orAtom(vmatch) != orAtom(stream)) )
103                    break;
104            }
105            else if( orIs(vmatch, OT_WORD) )
106            {
107#if 0
108                OContext* ctx;
109                OValue* wval;
110
111                orWordVal( vmatch, ctx, wval );
112
113                if( orIs(wval, OT_DATATYPE) )
114#else
115                if( orAtom(vmatch) < OT_COUNT )
116#endif
117                {
118#if 0
119                    int dt = orInt(wval);
120#else
121                    int dt = orAtom(vmatch);
122#endif
123                    if( dt == OT_NUMBER )
124                    {
125                        if( (orType(stream) != OT_INTEGER) &&
126                            (orType(stream) != OT_DECIMAL) )
127                            break;
128                    }
129                    else if( dt != stream->type )
130                    {
131                        break;
132                    }
133                }
134                else
135                {
136                    break;
137                }
138            }
139            else if( vmatch->type != stream->type )
140            {
141                break;
142            }
143        }
144
145        if( vmatch == ruleEnd )
146        {
147            cbp->values    = cbp->_blockPos;
148            cbp->_blockPos = stream;
149            // Return matched rule.
150            return rit - 1;
151        }
152    }
153
154    cbp->error = cbp->_blockPos;
155    return 0;
156}
157
158
159/*EOF*/
Note: See TracBrowser for help on using the browser.