Merge pull request #41 from blackducksw/ubuntu_14
[ohcount] / src / parsers / css.rl
1 // css.rl written by Mitchell Foral. mitchell<att>caladbolg<dott>net.
2
3 /************************* Required for every parser *************************/
4 #ifndef OHCOUNT_CSS_PARSER_H
5 #define OHCOUNT_CSS_PARSER_H
6
7 #include "../parser_macros.h"
8
9 // the name of the language
10 const char *CSS_LANG = LANG_CSS;
11
12 // the languages entities
13 const char *css_entities[] = {
14   "space", "comment", "string", "at_rule", "selector",
15   "value", "unit", "color", "url", "any"
16 };
17
18 // constants associated with the entities
19 enum {
20   CSS_SPACE = 0, CSS_COMMENT, CSS_STRING, CSS_AT_RULE, CSS_SELECTOR,
21   CSS_VALUE, CSS_UNIT, CSS_COLOR, CSS_URL, CSS_ANY
22 };
23
24 /*****************************************************************************/
25
26 %%{
27   machine css;
28   write data;
29   include common "common.rl";
30
31   # Line counting machine
32
33   action css_ccallback {
34     switch(entity) {
35     case CSS_SPACE:
36       ls
37       break;
38     case CSS_ANY:
39       code
40       break;
41     case INTERNAL_NL:
42       std_internal_newline(CSS_LANG)
43       break;
44     case NEWLINE:
45       std_newline(CSS_LANG)
46     }
47   }
48
49   css_comment =
50     '/*' @comment (
51       newline %{ entity = INTERNAL_NL; } %css_ccallback
52       |
53       ws
54       |
55       (nonnewline - ws) @comment
56     )* :>> '*/';
57
58   css_sq_str =
59     '\'' @code (
60       newline %{ entity = INTERNAL_NL; } %css_ccallback
61       |
62       ws
63       |
64       [^\r\n\f\t '\\] @code
65       |
66       '\\' nonnewline @code
67     )* '\'';
68   css_dq_str =
69     '"' @code (
70       newline %{ entity = INTERNAL_NL; } %css_ccallback
71       |
72       ws
73       |
74       [^\r\n\f\t "\\] @code
75       |
76       '\\' nonnewline @code
77     )* '"';
78   css_string = css_sq_str | css_dq_str;
79
80   css_line := |*
81     spaces      ${ entity = CSS_SPACE; } => css_ccallback;
82     css_comment;
83     css_string;
84     newline     ${ entity = NEWLINE;   } => css_ccallback;
85     ^space      ${ entity = CSS_ANY;   } => css_ccallback;
86   *|;
87
88   # Entity machine
89
90   action css_ecallback {
91     callback(CSS_LANG, css_entities[entity], cint(ts), cint(te), userdata);
92   }
93
94   css_comment_entity = '/*' any* :>> '*/';
95
96   css_entity := |*
97     space+             ${ entity = CSS_SPACE;   } => css_ecallback;
98     css_comment_entity ${ entity = CSS_COMMENT; } => css_ecallback;
99     # TODO:
100     ^space;
101   *|;
102 }%%
103
104 /************************* Required for every parser *************************/
105
106 /* Parses a string buffer with CSS code.
107  *
108  * @param *buffer The string to parse.
109  * @param length The length of the string to parse.
110  * @param count Integer flag specifying whether or not to count lines. If yes,
111  *   uses the Ragel machine optimized for counting. Otherwise uses the Ragel
112  *   machine optimized for returning entity positions.
113  * @param *callback Callback function. If count is set, callback is called for
114  *   every line of code, comment, or blank with 'lcode', 'lcomment', and
115  *   'lblank' respectively. Otherwise callback is called for each entity found.
116  */
117 void parse_css(char *buffer, int length, int count,
118                void (*callback) (const char *lang, const char *entity, int s,
119                                  int e, void *udata),
120                void *userdata
121   ) {
122   init
123
124   %% write init;
125   cs = (count) ? css_en_css_line : css_en_css_entity;
126   %% write exec;
127
128   // if no newline at EOF; callback contents of last line
129   if (count) { process_last_line(CSS_LANG) }
130 }
131
132 #endif
133
134 /*****************************************************************************/