1 /************************* Required for every parser *************************/
2 #ifndef OHCOUNT_COFFEESCRIPT_PARSER_H
3 #define OHCOUNT_COFFEESCRIPT_PARSER_H
5 #include "../parser_macros.h"
7 // the name of the language
8 const char *COFFEESCRIPT_LANG = LANG_COFFEESCRIPT;
10 // the languages entities
11 const char *coffeescript_entities[] = {
12 "space", "comment", "string", "any"
15 // constants associated with the entities
17 COFFEESCRIPT_SPACE = 0, COFFEESCRIPT_COMMENT, COFFEESCRIPT_STRING, COFFEESCRIPT_ANY
20 /*****************************************************************************/
22 #include "javascript.h"
27 include common "common.rl";
30 # Line counting machine
32 action coffeescript_ccallback {
34 case COFFEESCRIPT_SPACE:
37 case COFFEESCRIPT_ANY:
41 std_internal_newline(COFFEESCRIPT_LANG)
44 std_newline(COFFEESCRIPT_LANG)
48 coffeescript_line_comment = ('#') @comment nonnewline*;
49 coffeescript_block_comment =
51 newline %{ entity = INTERNAL_NL; } %coffeescript_ccallback
55 (nonnewline - ws) @comment
57 coffeescript_comment = coffeescript_line_comment | coffeescript_block_comment;
61 newline %{ entity = INTERNAL_NL; } %coffeescript_ccallback
68 )* '\'' @commit @code;
71 newline %{ entity = INTERNAL_NL; } %coffeescript_ccallback
79 coffeescript_sq_here_doc =
81 newline %{ entity = INTERNAL_NL; } %coffeescript_ccallback
85 (nonnewline - ws) @code
86 )* :>> '\'\'\'' @code;
87 coffeescript_dq_here_doc =
89 newline %{ entity = INTERNAL_NL; } %coffeescript_ccallback
93 (nonnewline - ws) @code
95 coffeescript_string = (coffeescript_sq_str | coffeescript_dq_str |
96 coffeescript_sq_here_doc | coffeescript_dq_here_doc) @code;
98 coffeescript_js_entry = '`' @code;
99 coffeescript_js_outry = '`' @check_blank_outry @code;
100 coffeescript_js_line := |*
101 coffeescript_js_outry @{ p = ts; fret; };
102 # unmodified JavaScript patterns
103 spaces ${ entity = JS_SPACE; } => js_ccallback;
106 newline ${ entity = NEWLINE; } => js_ccallback;
107 ^space ${ entity = JS_ANY; } => js_ccallback;
110 coffeescript_line := |*
111 coffeescript_js_entry @coffeescript_ccallback
112 @{ saw(JS_LANG); } => { fcall coffeescript_js_line; };
113 spaces ${ entity = COFFEESCRIPT_SPACE; } => coffeescript_ccallback;
114 coffeescript_comment;
116 newline ${ entity = NEWLINE; } => coffeescript_ccallback;
117 ^space ${ entity = COFFEESCRIPT_ANY; } => coffeescript_ccallback;
122 action coffeescript_ecallback {
123 callback(COFFEESCRIPT_LANG, coffeescript_entities[entity], cint(ts), cint(te),
127 coffeescript_line_comment_entity = ('#') nonnewline*;
128 coffeescript_block_comment_entity = '###' any* :>> '###';
129 coffeescript_comment_entity = coffeescript_line_comment_entity |
130 coffeescript_block_comment_entity;
132 coffeescript_entity := |*
133 space+ ${ entity = COFFEESCRIPT_SPACE; } => coffeescript_ecallback;
134 coffeescript_comment_entity ${ entity = COFFEESCRIPT_COMMENT; } => coffeescript_ecallback;
140 /************************* Required for every parser *************************/
142 /* Parses a string buffer with CoffeeScript code.
144 * @param *buffer The string to parse.
145 * @param length The length of the string to parse.
146 * @param count Integer flag specifying whether or not to count lines. If yes,
147 * uses the Ragel machine optimized for counting. Otherwise uses the Ragel
148 * machine optimized for returning entity positions.
149 * @param *callback Callback function. If count is set, callback is called for
150 * every line of code, comment, or blank with 'lcode', 'lcomment', and
151 * 'lblank' respectively. Otherwise callback is called for each entity found.
153 void parse_coffeescript(char *buffer, int length, int count,
154 void (*callback) (const char *lang, const char *entity, int s,
161 cs = (count) ? coffeescript_en_coffeescript_line : coffeescript_en_coffeescript_entity;
164 // if no newline at EOF; callback contents of last line
165 if (count) { process_last_line(COFFEESCRIPT_LANG) }
170 /*****************************************************************************/