RPA Toolkit
code cleanup, added more docs
[rpatk.git] / rpa / rparecord.h
1 /*
2  *  Regular Pattern Analyzer (RPA)
3  *  Copyright (c) 2009-2010 Martin Stoilov
4  *
5  *  This program is free software: you can redistribute it and/or modify
6  *  it under the terms of the GNU General Public License as published by
7  *  the Free Software Foundation, either version 3 of the License, or
8  *  (at your option) any later version.
9  *
10  *  This program 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
13  *  GNU General Public License for more details.
14  *
15  *  You should have received a copy of the GNU General Public License
16  *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
17  *
18  *  Martin Stoilov <martin@rpasearch.com>
19  */
20
21 /**
22  * \file rparecord.h
23  * \brief The public interface for working with Abstract Syntax Tree (AST), produced by @ref rpa_stat_parse.
24  *
25  *
26  * <h2>Synopsis</h2>
27  * Upon a successful call to \ref rpa_stat_parse, the parser produces a stack of \ref rparecord_t records.
28  * There are two kinds of records: \ref RPA_RECORD_START and \ref RPA_RECORD_END. \ref RPA_RECORD_START marks
29  * the beginning of a branch and \ref RPA_RECORD_END marks the end of that branch. Empty branches are specified by
30  * a record \ref RPA_RECORD_START followed immediately by \ref RPA_RECORD_END (no child records in between).
31  * Empty branches are considered leaves.
32  *
33  * Example:
34  * Consider parsing a person name:
35  * @verbatim John M. Smith @endverbatim
36  *
37  * with the following BNF:
38  * @code
39  * first  ::= [A-Za-z]+
40  * middle ::= [A-Za-z]+ '.'?
41  * last   ::= [A-Za-z]+
42  * name   ::= <first> ' ' <middle> ' ' <last>
43  * @endcode
44  *
45  * The records produced by rpa_stat_parse would look like this:
46  * @code
47  * [record offset]    [record type]       [rule name]  [input offset]  [input size]  [input]
48  *  0                  RPA_RECORD_START    name         0               13            John M. Smith
49  *  1                  RPA_RECORD_START    first        0                4            John
50  *  2                  RPA_RECORD_END      first        0                4            John
51  *  3                  RPA_RECORD_START    middle       5                2            M.
52  *  4                  RPA_RECORD_END      middle       5                2            M.
53  *  5                  RPA_RECORD_START    last         8                5            Smith
54  *  6                  RPA_RECORD_END      last         8                5            Smith
55  *  7                  RPA_RECORD_END      name         0               13            John M. Smith
56  * @endcode
57  *
58  * Note: first, middle and last are enclosed within name's RPA_RECORD_START and RPA_RECORD_END
59  */
60
61
62 #ifndef _RPARECORD_H_
63 #define _RPARECORD_H_
64
65 #include "rtypes.h"
66 #include "rarray.h"
67 #include "rlist.h"
68 #include "rpavm.h"
69
70
71 #ifdef __cplusplus
72 extern "C" {
73 #endif
74
75 #define RPA_RECORD_NONE (0)                                             /**< No record type - the record type is not initialized */
76 #define RPA_RECORD_START (1 << 0)                               /**< Start record - the parser generates this record before evaluating the rule. */
77 #define RPA_RECORD_END (1 << 1)                                 /**< End record - the parser generates this record after evaluating the rule and the rule matched some input. */
78 #define RPA_RECORD_INVALID_UID ((ruint32)-1)
79
80 /**
81  * typedef rparecord_t
82  */
83 typedef struct rparecord_s rparecord_t;
84
85 /**
86  * typedef rpa_recordtree_callback
87  */
88 typedef rlong (*rpa_recordtree_callback)(rarray_t *records, rlong rec, rpointer userdata);
89
90
91 /**
92  * \struct rparecord_s <rparecord.h> <rparecord.h>
93  * \brief Abstract Syntax Tree (AST) construction element.
94  */
95 struct rparecord_s {
96         ruint32 top;                    /**< This is a private member, used by the engine and is not significant to the user */
97         ruint32 size;                   /**< This is a private member, used by the engine and is not significant to the user */
98         const rchar *rule;              /**< Name of the rule that generated this record */
99         const rchar *input;             /**< Pointer in the input stream */
100         rsize_t inputsiz;               /**< Size of input */
101         ruint32 type;                   /**< Record Type: @ref RPA_RECORD_START or @ref RPA_RECORD_END */
102         ruint32 ruleuid;                /**< User specified Rule ID. If you used directive @ref emitid for this rulename, this member will contain the specified ID */
103         ruint32 usertype;               /**< User specified type. */
104         rword userdata;                 /**< Scratch area. This member can be used to associate some user specific data with this record. */
105 };
106
107
108 rlong rpa_recordtree_walk(rarray_t *src, rlong rec, rlong level, rpa_recordtree_callback callaback, rpointer userdata);
109 rlong rpa_recordtree_get(rarray_t *records, rlong rec, rulong type);
110 rlong rpa_recordtree_firstchild(rarray_t *records, rlong rec, rulong type);
111 rlong rpa_recordtree_lastchild(rarray_t *records, rlong rec, rulong type);
112 rlong rpa_recordtree_next(rarray_t *records, rlong rec, rulong type);
113 rlong rpa_recordtree_prev(rarray_t *records, rlong rec, rulong type);
114 rlong rpa_recordtree_parent(rarray_t *records, rlong rec, rulong type);
115 rlong rpa_recordtree_size(rarray_t *records, rlong rec);                                        /* Size of the tree */
116 rlong rpa_recordtree_copy(rarray_t *dst, rarray_t *src, rlong rec);
117
118 /**
119  * Return a pointer to a record at offset rec
120  * @param records An array of records populated by a @ref rpa_stat_parse operation.
121  * @param rec record offset.
122  */
123 rparecord_t *rpa_record_get(rarray_t *records, rlong rec);
124
125
126 void rpa_record_dumpindented(rarray_t *records, rlong rec, rinteger level);
127 void rpa_record_dump(rarray_t *records, rlong rec);
128 rlong rpa_record_getruleuid(rarray_t *records, rlong rec);
129 void rpa_record_setusertype(rarray_t *records, rlong rec, ruint32 usertype, rvalset_t op);
130 rlong rpa_record_getusertype(rarray_t *records, rlong rec);
131 rinteger rpa_record_optchar(rparecord_t *prec, rinteger defc);
132 rinteger rpa_record_loopchar(rparecord_t *prec, rinteger defc);
133 rarray_t *rpa_records_create();
134 void rpa_records_destroy(rarray_t *records);
135 rlong rpa_records_length(rarray_t *records);
136 rparecord_t *rpa_records_slot(rarray_t *records, rlong index);
137
138 #ifdef __cplusplus
139 }
140 #endif
141
142 #endif