RE/flex action | Flex action | Result |
text() | YYText() , yytext | 0-terminated const char* text match |
str() | n/a | std::string text match |
wstr() | n/a | std::wstring wide text match |
size() | YYLeng() , yyleng | size of the match in number bytes |
wsize() | n/a | number of wide chars matched |
lineno() | yylineno | line number of match (>=1) |
columno() | n/a | column number of match (>=0) |
echo() | ECHO | out().write(text(), size()) |
start() | YY_START | get current start condition |
start(n) | BEGIN n | set start condition to n |
push_state(n) | yy_push_state(n) | push current state, start n |
pop_state() | yy_pop_state() | pop state and make it current |
top_state() | yy_top_state() | get top state start condition |
in(i) | yyin = &i | set input to reflex::Input i |
in() | *yyin | get reflex::Input object |
out(s) | yyout = &s | set output to std::ostream s |
out() | *yyout | get std::ostream object |
out().write(s, n) | LexerOutput(s, n) | output chars s[0..n-1] |
out().put(c) | output(c) | output char c |
matcher().accept() | yy_act | number of the matched rule |
matcher().text() | YYText() , yytext | same as text() |
matcher().str() | n/a | same as str()
|
matcher().wstr() | n/a | same as wstr()
|
matcher().size() | YYLeng() , yyleng | same as size() |
matcher().wsize() | n/a | same as wsize() |
matcher().input() | yyinput() | get next char from input |
matcher().winput() | n/a | get wide character from input |
matcher().unput(c) | unput(c) | put back char c |
matcher().peek() | n/a | peek at next char on input |
matcher().more() | yymore() | concat next match to the match |
matcher().less(n) | yyless(n) | shrink match's length to n |
matcher().first() | n/a | first pos of match in input |
matcher().last() | n/a | last pos+1 of match in input |
matcher().rest() | n/a | get rest of input until end |
matcher().at_bob() | n/a | true if at the begin of input |
matcher().at_end() | n/a | true if at the end of input |
matcher().at_bol() | YY_AT_BOL() | true if at begin of a newline |
See the [RE/flex documentation](http://www.genivia.com/doc/reflex/html) for more details.
Second example: a JSON parser and writer {#example2}
----------------------------------------
In this example, I will demonstrate several useful techniques with RE/flex to develop a compact parser for JSON.
### JSON
[JSON](http://json.org) is a simple data format to exchange structured information. JSON and its implementations have been heavily [criticized](http://seriot.ch/parsing_json.php) for lack of standardization. No worries though, the implementation I'm presenting here was successfully tested and validated against the JSON data patterns in that critical article and therefore conforms to the so-called JSON "standard".
### A tagged JSON data structure
To hold JSON values we need a tagged data structure. A tagged data structure holds values of various types depending on the tag that can be used as a value selector. A JSON value is one of undefined (UND), null (NUL), boolean (BOO), number (NUM), string (STR), array (ARR), object (OBJ), or is an error (ERR) which is used when parsing failed. These tags and the values we need to store are defined by the `class JSON`:
class JSON {
public:
JSON() : tag(UND) { }
enum Tag { UND, NUL, BOO, NUM, STR, ARR, OBJ, ERR } tag;
bool boolean;
double number;
std::wstring string;
std::vector