Fixes recursion bug in disambiguate_in().
[ohcount] / src / parsers / puppet.rl
1 // puppet.rl written by Ken Barber <ken@bob.sh>
2 // Based on pascal.rl by Mitchell Foral. mitchell<att>caladbolg<dott>net
3
4 /************************* Required for every parser *************************/
5 #ifndef OHCOUNT_PUPPET_PARSER_H
6 #define OHCOUNT_PUPPET_PARSER_H
7
8 #include "../parser_macros.h"
9
10 // the name of the language
11 const char *PUPPET_LANG = LANG_PUPPET;
12
13 // the languages entities
14 const char *puppet_entities[] = {
15   "space", "comment", "string", "any"
16 };
17
18 // constants associated with the entities
19 enum {
20   PUPPET_SPACE = 0, PUPPET_COMMENT, PUPPET_STRING, PUPPET_ANY
21 };
22
23 /*****************************************************************************/
24
25 %%{
26   machine puppet;
27   write data;
28   include common "common.rl";
29
30   # Line counting machine
31
32   action puppet_ccallback {
33     switch(entity) {
34     case PUPPET_SPACE:
35       ls
36       break;
37     case PUPPET_ANY:
38       code
39       break;
40     case INTERNAL_NL:
41       std_internal_newline(PUPPET_LANG)
42       break;
43     case NEWLINE:
44       std_newline(PUPPET_LANG)
45     }
46   }
47
48   puppet_line_comment = '#' @comment nonnewline*;
49   puppet_block_comment =
50     '/*' @comment (
51       newline %{ entity = INTERNAL_NL; } %puppet_ccallback
52       |
53       ws
54       |
55       (nonnewline - ws) @code
56     )* :>> '*/';
57   puppet_comment = puppet_line_comment | puppet_block_comment;
58
59   puppet_string =
60     '\'' @code (
61       newline %{ entity = INTERNAL_NL; } %puppet_ccallback
62       |
63       ws
64       |
65       [^\r\n\f\t '\\] @code
66       |
67       '\\' nonnewline @code
68     )* '\'';
69
70   puppet_line := |*
71     spaces          ${ entity = PUPPET_SPACE; } => puppet_ccallback;
72     puppet_comment;
73     puppet_string;
74     newline         ${ entity = NEWLINE;      } => puppet_ccallback;
75     ^space          ${ entity = PUPPET_ANY;   } => puppet_ccallback;
76   *|;
77
78   # Entity machine
79
80   action puppet_ecallback {
81     callback(PUPPET_LANG, puppet_entities[entity], cint(ts), cint(te),
82              userdata);
83   }
84
85   puppet_line_comment_entity = '#' nonnewline*;
86   puppet_block_comment_entity = '/*' any* :>> '*/';
87   puppet_comment_entity = puppet_line_comment_entity |
88     puppet_block_comment_entity;
89
90   puppet_entity := |*
91     space+                ${ entity = PUPPET_SPACE;   } => puppet_ecallback;
92     puppet_comment_entity ${ entity = PUPPET_COMMENT; } => puppet_ecallback;
93     # TODO:
94     ^space;
95   *|;
96 }%%
97
98 /************************* Required for every parser *************************/
99
100 /* Parses a string buffer with Puppet DSL code.
101  *
102  * @param *buffer The string to parse.
103  * @param length The length of the string to parse.
104  * @param count Integer flag specifying whether or not to count lines. If yes,
105  *   uses the Ragel machine optimized for counting. Otherwise uses the Ragel
106  *   machine optimized for returning entity positions.
107  * @param *callback Callback function. If count is set, callback is called for
108  *   every line of code, comment, or blank with 'lcode', 'lcomment', and
109  *   'lblank' respectively. Otherwise callback is called for each entity found.
110  */
111 void parse_puppet(char *buffer, int length, int count,
112                   void (*callback) (const char *lang, const char *entity, int s,
113                                     int e, void *udata),
114                   void *userdata
115   ) {
116   init
117
118   %% write init;
119   cs = (count) ? puppet_en_puppet_line : puppet_en_puppet_entity;
120   %% write exec;
121
122   // if no newline at EOF; callback contents of last line
123   if (count) { process_last_line(PUPPET_LANG) }
124 }
125
126 #endif
127
128 /*****************************************************************************/