2 // http://www.vitanuova.com/inferno/papers/limbo.html
4 /************************* Required for every parser *************************/
5 #ifndef RAGEL_LIMBO_PARSER
6 #define RAGEL_LIMBO_PARSER
8 #include "../parser_macros.h"
10 // the name of the language
11 const char *LIMBO_LANG = "limbo";
13 // the languages entities
14 const char *limbo_entities[] = {
15 "space", "comment", "string", "number",
16 "keyword", "identifier", "operator", "any"
19 // constants associated with the entities
21 LIMBO_SPACE = 0, LIMBO_COMMENT, LIMBO_STRING, LIMBO_NUMBER,
22 LIMBO_KEYWORD, LIMBO_IDENTIFIER, LIMBO_OPERATOR, LIMBO_ANY
25 /*****************************************************************************/
30 include common "common.rl";
32 # Line counting machine
34 action limbo_ccallback {
43 std_internal_newline(LIMBO_LANG)
46 std_newline(LIMBO_LANG)
50 limbo_comment = '#' @comment nonnewline*;
64 limbo_string = limbo_sq_str | limbo_dq_str;
67 spaces ${ entity = LIMBO_SPACE; } => limbo_ccallback;
70 newline ${ entity = NEWLINE; } => limbo_ccallback;
71 ^space ${ entity = LIMBO_ANY; } => limbo_ccallback;
76 action limbo_ecallback {
77 callback(LIMBO_LANG, limbo_entities[entity], cint(ts), cint(te), userdata);
80 limbo_comment_entity = '#' nonnewline*;
82 # todo: this probably allows multi-line strings too, which limbo doesn't allow?
83 limbo_string_entity = sq_str_with_escapes | dq_str_with_escapes;
85 # todo: support numbers with specified radix? e.g. 16rFF, 8r666, 2b10101
86 limbo_number_entity = float | integer;
88 # todo: support utf-8 identifiers
89 limbo_identifier_entity = (alpha | '_') (alnum | '_')*;
91 limbo_keyword_entity =
92 'alt' | 'break' | 'continue' | 'exit' | 'return' | 'spawn' | 'implement' | 'import' | 'load' | 'raise' | 'raises'
93 'include' | 'array' | 'big' | 'byte' | 'chan' | 'con' | 'int' | 'list' | 'real' | 'string' | 'fn' |
94 'adt' | 'pick' | 'module' |
95 'for' | 'while' | 'do' |
96 'if' | 'else' | 'case' | 'or' | 'to' |
98 'ref' | 'self' | 'cyclic' | 'type' | 'of' |
99 'tl' | 'hd' | 'len' | 'tagof' |
102 limbo_operator_entity = [+\-/*%!=^&|~:;.,()\[\]{}>];
105 space+ ${ entity = LIMBO_SPACE; } => limbo_ecallback;
106 limbo_comment_entity ${ entity = LIMBO_COMMENT; } => limbo_ecallback;
107 limbo_string_entity ${ entity = LIMBO_STRING; } => limbo_ecallback;
108 limbo_number_entity ${ entity = LIMBO_NUMBER; } => limbo_ecallback;
109 limbo_keyword_entity ${ entity = LIMBO_KEYWORD; } => limbo_ecallback;
110 limbo_identifier_entity ${ entity = LIMBO_IDENTIFIER; } => limbo_ecallback;
111 limbo_operator_entity ${ entity = LIMBO_OPERATOR; } => limbo_ecallback;
112 ^(space | digit) ${ entity = C_ANY; } => limbo_ecallback;
116 /************************* Required for every parser *************************/
118 /* Parses a string buffer with Limbo code.
120 * @param *buffer The string to parse.
121 * @param length The length of the string to parse.
122 * @param count Integer flag specifying whether or not to count lines. If yes,
123 * uses the Ragel machine optimized for counting. Otherwise uses the Ragel
124 * machine optimized for returning entity positions.
125 * @param *callback Callback function. If count is set, callback is called for
126 * every line of code, comment, or blank with 'lcode', 'lcomment', and
127 * 'lblank' respectively. Otherwise callback is called for each entity found.
129 void parse_limbo(char *buffer, int length, int count,
130 void (*callback) (const char *lang, const char *entity, int s,
137 cs = (count) ? limbo_en_limbo_line : limbo_en_limbo_entity;
140 // if no newline at EOF; callback contents of last line
141 if (count) { process_last_line(LIMBO_LANG) }
146 /*****************************************************************************/