1 // fsharp.rl written by Pavel Shiryaev. Hill30 http://www.hill30.com
4 /************************* Required for every parser *************************/
5 #ifndef OHCOUNT_FSHARP_PARSER_H
6 #define OHCOUNT_FSHARP_PARSER_H
8 #include "../parser_macros.h"
10 // the name of the language
11 const char *FSHARP_LANG = LANG_FSHARP;
13 // the languages entities
14 const char *fsharp_entities[] = {
15 "space", "comment", "string", "number", "preproc",
16 "keyword", "identifier", "operator", "any"
19 // constants associated with the entities
21 FSHARP_SPACE = 0, FSHARP_COMMENT, FSHARP_STRING, FSHARP_NUMBER, FSHARP_PREPROC,
22 FSHARP_KEYWORD, FSHARP_IDENTIFIER, FSHARP_OPERATOR, FSHARP_ANY
25 /*****************************************************************************/
30 include common "common.rl";
32 # Line counting machine
34 action fsharp_ccallback {
43 std_internal_newline(FSHARP_LANG)
46 std_newline(FSHARP_LANG)
52 escaped_newline %{ entity = INTERNAL_NL; } %fsharp_ccallback
56 (nonnewline - ws) @comment
58 fsharp_block_comment =
60 newline %{ entity = INTERNAL_NL; } %fsharp_ccallback
64 (nonnewline - ws) @comment
66 fsharp_comment = fsharp_line_comment | fsharp_block_comment;
70 escaped_newline %{ entity = INTERNAL_NL; } %fsharp_ccallback
80 escaped_newline %{ entity = INTERNAL_NL; } %fsharp_ccallback
88 fsharp_string = fsharp_sq_str | fsharp_dq_str;
91 spaces ${ entity = FSHARP_SPACE; } => fsharp_ccallback;
94 newline ${ entity = NEWLINE; } => fsharp_ccallback;
95 ^space ${ entity = FSHARP_ANY; } => fsharp_ccallback;
100 action fsharp_ecallback {
101 callback(FSHARP_LANG, fsharp_entities[entity], cint(ts), cint(te), userdata);
104 fsharp_line_comment_entity = '//' (escaped_newline | nonnewline)*;
105 fsharp_block_comment_entity = '(*' any* :>> '*)';
106 fsharp_comment_entity = fsharp_line_comment_entity | fsharp_block_comment_entity;
108 fsharp_string_entity = sq_str_with_escapes | dq_str_with_escapes;
110 fsharp_number_entity = float | integer;
112 fsharp_preproc_word =
113 'define' | 'elif' | 'else' | 'endif' | 'error' | 'if' | 'ifdef' |
114 'ifndef' | 'import' | 'include' | 'line' | 'pragma' | 'undef' |
116 # TODO: find some way of making preproc match the beginning of a line.
117 # Putting a 'when starts_line' conditional throws an assertion error.
118 fsharp_preproc_entity =
119 '#' space* (fsharp_block_comment_entity space*)?
120 fsharp_preproc_word (escaped_newline | nonnewline)*;
122 fsharp_identifier_entity = (alpha | '_') (alnum | '_')*;
124 fsharp_keyword_entity =
125 'and' | 'and_eq' | 'asm' | 'auto' | 'bitand' | 'bitor' | 'bool' |
126 'break' | 'case' | 'catch' | 'char' | 'class' | 'compl' | 'const' |
127 'const_cast' | 'continue' | 'default' | 'delete' | 'do' | 'double' |
128 'dynamic_cast' | 'else' | 'enum' | 'explicit' | 'export' | 'extern' |
129 'false' | 'float' | 'for' | 'friend' | 'goto' | 'if' | 'inline' | 'int' |
130 'long' | 'mutable' | 'namespace' | 'new' | 'not' | 'not_eq' |
131 'operator' | 'or' | 'or_eq' | 'private' | 'protected' | 'public' |
132 'register' | 'reinterpret_cast' | 'return' | 'short' | 'signed' |
133 'sizeof' | 'static' | 'static_cast' | 'struct' | 'switch' |
134 'template' | 'this' | 'throw' | 'true' | 'try' | 'typedef' | 'typeid' |
135 'typename' | 'union' | 'unsigned' | 'using' | 'virtual' | 'void' |
136 'volatile' | 'wchar_t' | 'while' | 'xor' | 'xor_eq';
138 fsharp_operator_entity = [+\-/*%<>!=^&|?~:;.,()\[\]{}];
141 space+ ${ entity = FSHARP_SPACE; } => fsharp_ecallback;
142 fsharp_comment_entity ${ entity = FSHARP_COMMENT; } => fsharp_ecallback;
143 fsharp_string_entity ${ entity = FSHARP_STRING; } => fsharp_ecallback;
144 fsharp_number_entity ${ entity = FSHARP_NUMBER; } => fsharp_ecallback;
145 fsharp_preproc_entity ${ entity = FSHARP_PREPROC; } => fsharp_ecallback;
146 fsharp_identifier_entity ${ entity = FSHARP_IDENTIFIER; } => fsharp_ecallback;
147 fsharp_keyword_entity ${ entity = FSHARP_KEYWORD; } => fsharp_ecallback;
148 fsharp_operator_entity ${ entity = FSHARP_OPERATOR; } => fsharp_ecallback;
149 ^(space | digit) ${ entity = FSHARP_ANY; } => fsharp_ecallback;
153 /************************* Required for every parser *************************/
155 /* Parses a string buffer with C/C++ code.
157 * @param *buffer The string to parse.
158 * @param length The length of the string to parse.
159 * @param count Integer flag specifying whether or not to count lines. If yes,
160 * uses the Ragel machine optimized for counting. Otherwise uses the Ragel
161 * machine optimized for returning entity positions.
162 * @param *callback Callback function. If count is set, callback is called for
163 * every line of code, comment, or blank with 'lcode', 'lcomment', and
164 * 'lblank' respectively. Otherwise callback is called for each entity found.
166 void parse_fsharp(char *buffer, int length, int count,
167 void (*callback) (const char *lang, const char *entity, int s,
174 cs = (count) ? fsharp_en_fsharp_line : fsharp_en_fsharp_entity;
177 // if no newline at EOF; callback contents of last line
178 if (count) { process_last_line(FSHARP_LANG) }
183 /*****************************************************************************/