Merge pull request #41 from blackducksw/ubuntu_14
[ohcount] / src / parsers / jsp.rl
1 // jsp.rl written by Mitchell Foral. mitchell<att>caladbolg<dott>net.
2
3 /************************* Required for every parser *************************/
4 #ifndef OHCOUNT_JSP_PARSER_H
5 #define OHCOUNT_JSP_PARSER_H
6
7 #include "../parser_macros.h"
8
9 // the name of the language
10 const char *JSP_LANG = LANG_HTML;
11
12 // the languages entities
13 const char *jsp_entities[] = {
14   "space", "comment", "doctype",
15   "tag", "entity", "any"
16 };
17
18 // constants associated with the entities
19 enum {
20   JSP_SPACE = 0, JSP_COMMENT, JSP_DOCTYPE,
21   JSP_TAG, JSP_ENTITY, JSP_ANY
22 };
23
24 /*****************************************************************************/
25
26 #include "css.h"
27 #include "javascript.h"
28 #include "java.h"
29
30 %%{
31   machine jsp;
32   write data;
33   include common "common.rl";
34   #EMBED(css)
35   #EMBED(javascript)
36   #EMBED(java)
37
38   # Line counting machine
39
40   action jsp_ccallback {
41     switch(entity) {
42     case JSP_SPACE:
43       ls
44       break;
45     case JSP_ANY:
46       code
47       break;
48     case INTERNAL_NL:
49       emb_internal_newline(JSP_LANG)
50       break;
51     case NEWLINE:
52       emb_newline(JSP_LANG)
53       break;
54     case CHECK_BLANK_ENTRY:
55       check_blank_entry(JSP_LANG)
56     }
57   }
58
59   jsp_comment := (
60     newline %{ entity = INTERNAL_NL; } %jsp_ccallback
61     |
62     ws
63     |
64     ^(space | [\-<]) @comment
65     |
66     '<' '%' @{ saw(JAVA_LANG); fcall jsp_java_line; }
67     |
68     '<' !'%'
69   )* :>> '-->' @comment @{ fgoto jsp_line; };
70
71   jsp_sq_str := (
72     newline %{ entity = INTERNAL_NL; } %jsp_ccallback
73     |
74     ws
75     |
76     [^\r\n\f\t '\\<] @code
77     |
78     '\\' nonnewline @code
79     |
80     '<' '%' @{ saw(JAVA_LANG); fcall jsp_java_line; }
81     |
82     '<' !'%'
83   )* '\'' @{ fgoto jsp_line; };
84   jsp_dq_str := (
85     newline %{ entity = INTERNAL_NL; } %jsp_ccallback
86     |
87     ws
88     |
89     [^\r\n\f\t "\\<] @code
90     |
91     '\\' nonnewline @code
92     |
93     '<' '%' @{ saw(JAVA_LANG); fcall jsp_java_line; }
94     |
95     '<' !'%'
96   )* '"' @{ fgoto jsp_line; };
97
98   ws_or_inl = (ws | newline @{ entity = INTERNAL_NL; } %jsp_ccallback);
99
100   jsp_css_entry = '<' /style/i [^>]+ :>> 'text/css' [^>]+ '>' @code;
101   jsp_css_outry = '</' /style/i ws_or_inl* '>' @check_blank_outry @code;
102   jsp_css_line := |*
103     jsp_css_outry @{ p = ts; fret; };
104     # unmodified CSS patterns
105     spaces      ${ entity = CSS_SPACE; } => css_ccallback;
106     css_comment;
107     css_string;
108     newline     ${ entity = NEWLINE;   } => css_ccallback;
109     ^space      ${ entity = CSS_ANY;   } => css_ccallback;
110   *|;
111
112   jsp_js_entry = '<' /script/i [^>]+ :>> 'text/javascript' [^>]+ '>' @code;
113   jsp_js_outry = '</' /script/i ws_or_inl* '>' @check_blank_outry @code;
114   jsp_js_line := |*
115     jsp_js_outry @{ p = ts; fret; };
116     # unmodified Javascript patterns
117     spaces     ${ entity = JS_SPACE; } => js_ccallback;
118     js_comment;
119     js_string;
120     newline    ${ entity = NEWLINE;  } => js_ccallback;
121     ^space     ${ entity = JS_ANY;   } => js_ccallback;
122   *|;
123
124   jsp_java_entry = '<%' @code;
125   jsp_java_outry = '%>' @check_blank_outry @code;
126   jsp_java_line := |*
127     jsp_java_outry @{ p = ts; fret; };
128     # unmodified JAVA patterns
129     spaces        ${ entity = JAVA_SPACE; } => java_ccallback;
130     java_comment;
131     java_string;
132     newline       ${ entity = NEWLINE;    } => java_ccallback;
133     ^space        ${ entity = JAVA_ANY;   } => java_ccallback;
134   *|;
135
136   jsp_line := |*
137     jsp_css_entry @{ entity = CHECK_BLANK_ENTRY; } @jsp_ccallback
138       @{ saw(CSS_LANG); } => { fcall jsp_css_line; };
139     jsp_js_entry @{ entity = CHECK_BLANK_ENTRY; } @jsp_ccallback
140       @{ saw(JS_LANG); } => { fcall jsp_js_line; };
141     jsp_java_entry @{ entity = CHECK_BLANK_ENTRY; } @jsp_ccallback
142       @{ saw(JAVA_LANG); } => { fcall jsp_java_line; };
143     # standard JSP patterns
144     spaces       ${ entity = JSP_SPACE; } => jsp_ccallback;
145     '<!--'       @comment                 => { fgoto jsp_comment; };
146     '\''         @code                    => { fgoto jsp_sq_str;  };
147     '"'          @code                    => { fgoto jsp_dq_str;  };
148     newline      ${ entity = NEWLINE;   } => jsp_ccallback;
149     ^space       ${ entity = JSP_ANY;   } => jsp_ccallback;
150   *|;
151
152   # Entity machine
153
154   action jsp_ecallback {
155     callback(JSP_LANG, jsp_entities[entity], cint(ts), cint(te), userdata);
156   }
157
158   jsp_css_entry_entity = '<' /style/i [^>]+ :>> 'text/css' [^>]+ '>';
159   jsp_css_outry_entity = '</' /style/i ws_or_inl* '>';
160   jsp_css_entity := |*
161     jsp_css_outry_entity @{ fret; };
162     # unmodified CSS patterns
163     space+             ${ entity = CSS_SPACE;   } => css_ecallback;
164     css_comment_entity ${ entity = CSS_COMMENT; } => css_ecallback;
165     # TODO:
166     ^space;
167   *|;
168
169   jsp_js_entry_entity = '<' /script/i [^>]+ :>> 'text/javascript' [^>]+ '>';
170   jsp_js_outry_entity = '</' /script/i ws_or_inl* '>';
171   jsp_js_entity := |*
172     jsp_js_outry_entity @{ fret; };
173     # unmodified Javascript patterns
174     space+            ${ entity = JS_SPACE;   } => js_ecallback;
175     js_comment_entity ${ entity = JS_COMMENT; } => js_ecallback;
176     # TODO:
177     ^space;
178   *|;
179
180   jsp_java_entry_entity = '<%';
181   jsp_java_outry_entity = '%>';
182   jsp_java_entity := |*
183     jsp_java_outry_entity @{ fret; };
184     # unmodified Java patterns
185     space+              ${ entity = JAVA_SPACE;   } => java_ecallback;
186     java_comment_entity ${ entity = JAVA_COMMENT; } => java_ecallback;
187     # TODO:
188     ^space;
189   *|;
190
191   jsp_comment_entity = '<!--' any* :>> '-->';
192
193   jsp_entity := |*
194     # TODO: jsp_ecallback for jsp_*_{entry,outry}_entity
195     jsp_css_entry_entity  => { fcall jsp_css_entity;  };
196     jsp_js_entry_entity   => { fcall jsp_js_entity;   };
197     jsp_java_entry_entity => { fcall jsp_java_entity; };
198     # standard JSP patterns
199     space+             ${ entity = JSP_SPACE;   } => jsp_ecallback;
200     jsp_comment_entity ${ entity = JSP_COMMENT; } => jsp_ecallback;
201     # TODO:
202     ^space;
203   *|;
204 }%%
205
206 /************************* Required for every parser *************************/
207
208 /* Parses a string buffer with JSP code.
209  *
210  * @param *buffer The string to parse.
211  * @param length The length of the string to parse.
212  * @param count Integer flag specifying whether or not to count lines. If yes,
213  *   uses the Ragel machine optimized for counting. Otherwise uses the Ragel
214  *   machine optimized for returning entity positions.
215  * @param *callback Callback function. If count is set, callback is called for
216  *   every line of code, comment, or blank with 'lcode', 'lcomment', and
217  *   'lblank' respectively. Otherwise callback is called for each entity found.
218  */
219 void parse_jsp(char *buffer, int length, int count,
220                void (*callback) (const char *lang, const char *entity, int s,
221                                  int e, void *udata),
222                void *userdata
223   ) {
224   init
225
226   const char *seen = 0;
227
228   %% write init;
229   cs = (count) ? jsp_en_jsp_line : jsp_en_jsp_entity;
230   %% write exec;
231
232   // if no newline at EOF; callback contents of last line
233   if (count) { process_last_line(JSP_LANG) }
234 }
235
236 #endif
237
238 /*****************************************************************************/