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