1 // boo.rl written by Mitchell Foral. mitchell<att>caladbolg<dott>net
3 /************************* Required for every parser *************************/
4 #ifndef OHCOUNT_BOO_PARSER_H
5 #define OHCOUNT_BOO_PARSER_H
7 #include "../parser_macros.h"
9 // the name of the language
10 const char *BOO_LANG = LANG_BOO;
12 // the languages entities
13 const char *boo_entities[] = {
14 "space", "comment", "string", "any"
17 // constants associated with the entities
19 BOO_SPACE = 0, BOO_COMMENT, BOO_STRING, BOO_ANY
22 /*****************************************************************************/
27 include common "common.rl";
29 # Line counting machine
31 action boo_ccallback {
40 std_internal_newline(BOO_LANG)
47 action boo_comment_nc_res { nest_count = 0; }
48 action boo_comment_nc_inc { nest_count++; }
49 action boo_comment_nc_dec { nest_count--; }
51 boo_line_comment = ('#' | '//') @comment nonnewline*;
53 '/*' >boo_comment_nc_res @comment (
54 newline %{ entity = INTERNAL_NL; } %boo_ccallback
58 '/*' @boo_comment_nc_inc @comment
60 '*/' @boo_comment_nc_dec @comment
63 )* :>> ('*/' when { nest_count == 0 }) @comment;
66 newline %{ entity = INTERNAL_NL; } %boo_ccallback
70 (nonnewline - ws) @comment
71 )* :>> '"""' @comment;
72 boo_comment = boo_line_comment | boo_block_comment | boo_doc_comment;
74 boo_char = '\'' ([^\r\n\f'\\] | '\\' nonnewline) '\'';
76 '"' ([^"] | '"' [^"] @{ fhold; }) @{ fhold; } # make sure it's not """
77 ([^\r\n\f"\\] | '\\' nonnewline)* '"';
78 boo_regex = '/' [^*/] @{ fhold; } ([^\r\n\f/\\] | '\\' nonnewline)* '/';
79 boo_string = (boo_char | boo_dq_str | boo_regex) @code;
82 spaces ${ entity = BOO_SPACE; } => boo_ccallback;
85 newline ${ entity = NEWLINE; } => boo_ccallback;
86 ^space ${ entity = BOO_ANY; } => boo_ccallback;
91 action boo_ecallback {
92 callback(BOO_LANG, boo_entities[entity], cint(ts), cint(te), userdata);
95 boo_line_comment_entity = ('#' | '//') nonnewline*;
96 boo_block_comment_entity = '/*' >boo_comment_nc_res (
97 '/*' @boo_comment_nc_inc
99 '*/' @boo_comment_nc_dec
102 )* :>> ('*/' when { nest_count == 0 });
103 boo_comment_entity = boo_line_comment_entity | boo_block_comment_entity;
106 space+ ${ entity = BOO_SPACE; } => boo_ecallback;
107 boo_comment_entity ${ entity = BOO_COMMENT; } => boo_ecallback;
113 /************************* Required for every parser *************************/
115 /* Parses a string buffer with Boo code.
117 * @param *buffer The string to parse.
118 * @param length The length of the string to parse.
119 * @param count Integer flag specifying whether or not to count lines. If yes,
120 * uses the Ragel machine optimized for counting. Otherwise uses the Ragel
121 * machine optimized for returning entity positions.
122 * @param *callback Callback function. If count is set, callback is called for
123 * every line of code, comment, or blank with 'lcode', 'lcomment', and
124 * 'lblank' respectively. Otherwise callback is called for each entity found.
126 void parse_boo(char *buffer, int length, int count,
127 void (*callback) (const char *lang, const char *entity, int s,
136 cs = (count) ? boo_en_boo_line : boo_en_boo_entity;
139 // if no newline at EOF; callback contents of last line
140 if (count) { process_last_line(BOO_LANG) }
145 /*****************************************************************************/