Merge pull request #41 from blackducksw/ubuntu_14
[ohcount] / src / parsers / augeas.rl
1 // augeas.rl, based on ocaml.rl
2 /************************* Required for every parser *************************/
3 #ifndef OHCOUNT_AUGEAS_PARSER_H
4 #define OHCOUNT_AUGEAS_PARSER_H
5
6 #include "../parser_macros.h"
7
8 // the name of the language
9 const char *AUGEAS_LANG = LANG_AUGEAS;
10
11 // the languages entities
12 const char *augeas_entities[] = {
13   "space", "comment", "string", "any"
14 };
15
16 // constants associated with the entities
17 enum {
18   AUGEAS_SPACE = 0, AUGEAS_COMMENT, AUGEAS_STRING, AUGEAS_ANY
19 };
20
21 /*****************************************************************************/
22
23 %%{
24   machine augeas;
25   write data;
26   include common "common.rl";
27
28   # Line counting machine
29
30   action augeas_ccallback {
31     switch(entity) {
32     case AUGEAS_SPACE:
33       ls
34       break;
35     case AUGEAS_ANY:
36       code
37       break;
38     case INTERNAL_NL:
39       std_internal_newline(AUGEAS_LANG)
40       break;
41     case NEWLINE:
42       std_newline(AUGEAS_LANG)
43     }
44   }
45
46   action augeas_comment_nc_res { nest_count = 0; }
47   action augeas_comment_nc_inc { nest_count++; }
48   action augeas_comment_nc_dec { nest_count--; }
49
50   augeas_nested_block_comment =
51                 '(*' >augeas_comment_nc_res @comment (
52                         newline %{ entity = INTERNAL_NL; } %augeas_ccallback
53                         |
54                         ws
55                         |
56                         '(*' @augeas_comment_nc_inc @comment
57                         |
58                         '*)' @augeas_comment_nc_dec @comment
59                         |
60                         (nonnewline - ws) @comment
61                 )* :>> ('*)' when { nest_count == 0 }) @comment;
62
63   augeas_comment = augeas_nested_block_comment;
64         augeas_string = '"' @code ([^\r\n\f"\\] | '\\' nonnewline)* '"';
65
66
67   augeas_line := |*
68     spaces          ${ entity = AUGEAS_SPACE; } => augeas_ccallback;
69     augeas_comment;
70     augeas_string;
71     newline         ${ entity = NEWLINE;      } => augeas_ccallback;
72     ^space          ${ entity = AUGEAS_ANY;   } => augeas_ccallback;
73   *|;
74
75   # Entity machine
76
77   action augeas_ecallback {
78     callback(AUGEAS_LANG, augeas_entities[entity], cint(ts), cint(te), userdata);
79   }
80
81   augeas_comment_entity = '(*' >augeas_comment_nc_res (
82     '(*' @augeas_comment_nc_inc
83     |
84     '*)' @augeas_comment_nc_dec
85     |
86     any
87   )* :>> ('*)' when { nest_count == 0 });
88
89   augeas_entity := |*
90     space+               ${ entity = AUGEAS_SPACE;   } => augeas_ecallback;
91     augeas_comment_entity ${ entity = AUGEAS_COMMENT; } => augeas_ecallback;
92     # TODO:
93     ^space;
94   *|;
95 }%%
96
97 /************************* Required for every parser *************************/
98
99 /* Parses a string buffer with Objective Caml code.
100  *
101  * @param *buffer The string to parse.
102  * @param length The length of the string to parse.
103  * @param count Integer flag specifying whether or not to count lines. If yes,
104  *   uses the Ragel machine optimized for counting. Otherwise uses the Ragel
105  *   machine optimized for returning entity positions.
106  * @param *callback Callback function. If count is set, callback is called for
107  *   every line of code, comment, or blank with 'lcode', 'lcomment', and
108  *   'lblank' respectively. Otherwise callback is called for each entity found.
109  */
110 void parse_augeas(char *buffer, int length, int count,
111                  void (*callback) (const char *lang, const char *entity, int s,
112                                    int e, void *udata),
113                  void *userdata
114   ) {
115   init
116
117   int nest_count = 0;
118
119   %% write init;
120   cs = (count) ? augeas_en_augeas_line : augeas_en_augeas_entity;
121   %% write exec;
122
123   // if no newline at EOF; callback contents of last line
124   if (count) { process_last_line(AUGEAS_LANG) }
125 }
126
127 #endif
128
129 /*****************************************************************************/