Added TODO: tag in lua.rl parser.
[ohcount] / ext / ohcount_native / ragel_parsers / lua.rl
1 // lua.rl written by Mitchell Foral. mitchell<att>caladbolg<dott>net.
2
3 /************************* Required for every parser *************************/
4 #include "ragel_parser_macros.h"
5
6 // the name of the language
7 const char *LUA_LANG = "lua";
8
9 // the languages entities
10 const char *lua_entities[] = {
11   "space", "comment", "string", "number", "keyword",
12   "identifier", "operator", "any"
13 };
14
15 // constants associated with the entities
16 enum {
17   LUA_SPACE = 0, LUA_COMMENT, LUA_STRING, LUA_NUMBER, LUA_KEYWORD,
18   LUA_IDENTIFIER, LUA_OPERATOR, LUA_ANY
19 };
20
21 // do not change the following variables
22
23 // used for newlines
24 #define NEWLINE -1
25
26 // used for newlines inside patterns like strings and comments that can have
27 // newlines in them
28 #define INTERNAL_NL -2
29
30 // required by Ragel
31 int cs, act;
32 char *p, *pe, *eof, *ts, *te;
33
34 // used for calculating offsets from buffer start for start and end positions
35 char *buffer_start;
36 #define cint(c) ((int) (c - buffer_start))
37
38 // state flags for line and comment counting
39 int whole_line_comment;
40 int line_contains_code;
41
42 // the beginning of a line in the buffer for line and comment counting
43 char *line_start;
44
45 // state variable for the current entity being matched
46 int entity;
47
48 /*****************************************************************************/
49
50 %%{
51   machine lua;
52   write data;
53   include common "common.rl";
54
55   # Line counting machine
56
57   action lua_ccallback {
58     switch(entity) {
59     case LUA_SPACE:
60       ls
61       break;
62     case LUA_ANY:
63       code
64       break;
65     case INTERNAL_NL:
66       std_internal_newline(LUA_LANG)
67       break;
68     case NEWLINE:
69       std_newline(LUA_LANG)
70     }
71   }
72
73   action lua_long_ec_res { equal_count = 0; }
74   action lua_long_ec_inc { equal_count++; }
75   action lua_long_ec_dec { equal_count--; }
76
77   lua_long_comment =
78     '--' @comment ('[' >lua_long_ec_res '='* $lua_long_ec_inc '[') (
79       newline %{ entity = INTERNAL_NL; } %lua_ccallback
80       |
81       ws
82       |
83       (nonnewline - ws) @comment
84     )* :>> (']' '='* $lua_long_ec_dec ']' when { equal_count == 0 });
85   lua_line_comment = '--' @comment nonnewline*;
86   lua_comment = lua_long_comment | lua_line_comment;
87
88   lua_long_string =
89     ('[' >lua_long_ec_res '='* $lua_long_ec_inc '[') @code (
90       newline %{ entity = INTERNAL_NL; } %lua_ccallback
91       |
92       ws
93       |
94       (nonnewline - ws) @code
95     )* :>> (']' '='* $lua_long_ec_dec ']' when { equal_count == 0 });
96   lua_sq_str =
97     '\'' @code (
98       newline %{ entity = INTERNAL_NL; } %lua_ccallback
99       |
100       ws
101       |
102       [^\t '\\] @code
103       |
104       '\\' nonnewline @code
105     )* '\'';
106   lua_dq_str =
107     '"' @code (
108       newline %{ entity = INTERNAL_NL; } %lua_ccallback
109       |
110       ws
111       |
112       [^\t "\\] @code
113       |
114       '\\' nonnewline @code
115     )* '"';
116   lua_string = lua_sq_str | lua_dq_str | lua_long_string;
117
118   lua_line := |*
119     spaces      ${ entity = LUA_SPACE; } => lua_ccallback;
120     lua_comment;
121     lua_string;
122     newline     ${ entity = NEWLINE;   } => lua_ccallback;
123     ^space      ${ entity = LUA_ANY;   } => lua_ccallback;
124   *|;
125
126   # Entity machine
127
128   action lua_ecallback {
129     callback(LUA_LANG, entity, cint(ts), cint(te));
130   }
131
132   lua_entity := 'TODO:';
133 }%%
134
135 /* Parses a string buffer with Lua code.
136  *
137  * @param *buffer The string to parse.
138  * @param length The length of the string to parse.
139  * @param count Integer flag specifying whether or not to count lines. If yes,
140  *   uses the Ragel machine optimized for counting. Otherwise uses the Ragel
141  *   machine optimized for returning entity positions.
142  * @param *callback Callback function. If count is set, callback is called for
143  *   every line of code, comment, or blank with 'lcode', 'lcomment', and
144  *   'lblank' respectively. Otherwise callback is called for each entity found.
145  */
146 void parse_lua(char *buffer, int length, int count,
147   void (*callback) (const char *lang, const char *entity, int start, int end)
148   ) {
149   p = buffer;
150   pe = buffer + length;
151   eof = pe;
152
153   buffer_start = buffer;
154   whole_line_comment = 0;
155   line_contains_code = 0;
156   line_start = 0;
157   entity = 0;
158
159   int equal_count = 0;
160
161   %% write init;
162   cs = (count) ? lua_en_lua_line : lua_en_lua_entity;
163   %% write exec;
164
165   // if no newline at EOF; callback contents of last line
166   if (count) { process_last_line(LUA_LANG) }
167 }