OTWO-1213 Works around lost encoding in Ruby/C binding layer
[ohcount] / src / parsers / eiffel.rl
1 /************************* Required for every parser *************************/
2 #ifndef OHCOUNT_EIFFEL_PARSER_H
3 #define OHCOUNT_EIFFEL_PARSER_H
4
5 #include "../parser_macros.h"
6
7 // the name of the language
8 const char *EIFFEL_LANG = LANG_EIFFEL;
9
10 // the languages entities
11 const char *eiffel_entities[] = {
12   "space", "comment", "string", "any"
13 };
14
15 // constants associated with the entities
16 enum {
17   EIFFEL_SPACE = 0, EIFFEL_COMMENT, EIFFEL_STRING, EIFFEL_ANY
18 };
19
20 /*****************************************************************************/
21
22 %%{
23   machine eiffel;
24   write data;
25   include common "common.rl";
26
27   # Line counting machine
28
29   action eiffel_ccallback {
30     switch(entity) {
31     case EIFFEL_SPACE:
32       ls
33       break;
34     case EIFFEL_ANY:
35       code
36       break;
37     case INTERNAL_NL:
38       std_internal_newline(EIFFEL_LANG)
39       break;
40     case NEWLINE:
41       std_newline(EIFFEL_LANG)
42     }
43   }
44
45   eiffel_comment = '--' @comment nonnewline*;
46
47   eiffel_string = '"' @code [^\r\n\f"]* '"';
48
49   eiffel_line := |*
50     spaces      ${ entity = EIFFEL_SPACE; } => eiffel_ccallback;
51     eiffel_comment;
52     eiffel_string;
53     newline     ${ entity = NEWLINE;   } => eiffel_ccallback;
54     ^space      ${ entity = EIFFEL_ANY;   } => eiffel_ccallback;
55   *|;
56
57   # Entity machine
58
59   action eiffel_ecallback {
60     callback(EIFFEL_LANG, eiffel_entities[entity], cint(ts), cint(te),
61              userdata);
62   }
63
64   eiffel_comment_entity = '--' nonnewline*;
65
66   eiffel_entity := |*
67     space+                ${ entity = EIFFEL_SPACE;   } => eiffel_ecallback;
68     eiffel_comment_entity ${ entity = EIFFEL_COMMENT; } => eiffel_ecallback;
69     # TODO:
70     ^space;
71   *|;
72 }%%
73
74 /************************* Required for every parser *************************/
75
76 /* Parses a string buffer with Eiffel code.
77  *
78  * @param *buffer The string to parse.
79  * @param length The length of the string to parse.
80  * @param count Integer flag specifying whether or not to count lines. If yes,
81  *   uses the Ragel machine optimized for counting. Otherwise uses the Ragel
82  *   machine optimized for returning entity positions.
83  * @param *callback Callback function. If count is set, callback is called for
84  *   every line of code, comment, or blank with 'lcode', 'lcomment', and
85  *   'lblank' respectively. Otherwise callback is called for each entity found.
86  */
87 void parse_eiffel(char *buffer, int length, int count,
88                   void (*callback) (const char *lang, const char *entity, int s,
89                                     int e, void *udata),
90                   void *userdata
91   ) {
92   init
93
94   %% write init;
95   cs = (count) ? eiffel_en_eiffel_line : eiffel_en_eiffel_entity;
96   %% write exec;
97
98   // if no newline at EOF; callback contents of last line
99   if (count) { process_last_line(EIFFEL_LANG) }
100 }
101
102 #endif
103
104 /*****************************************************************************/