Added Ada parser.
[ohcount] / ext / ohcount_native / ragel_parsers / html.rl
1 // html.rl written by Mitchell Foral. mitchell<att>caladbolg<dott>net.
2
3 /************************* Required for every parser *************************/
4 #ifndef RAGEL_HTML_PARSER
5 #define RAGEL_HTML_PARSER
6
7 #include "ragel_parser_macros.h"
8
9 // the name of the language
10 const char *HTML_LANG = "html";
11
12 // the languages entities
13 const char *html_entities[] = {
14   "space", "comment", "doctype",
15   "tag", "entity", "any"
16 };
17
18 // constants associated with the entities
19 enum {
20   HTML_SPACE = 0, HTML_COMMENT, HTML_DOCTYPE,
21   HTML_TAG, HTML_ENTITY, HTML_ANY
22 };
23
24 /*****************************************************************************/
25
26 #include "css_parser.h"
27 #include "javascript_parser.h"
28
29 %%{
30   machine html;
31   write data;
32   include common "common.rl";
33   #EMBED(css)
34   #EMBED(javascript)
35
36   # Line counting machine
37
38   action html_ccallback {
39     switch(entity) {
40     case HTML_SPACE:
41       ls
42       break;
43     case HTML_ANY:
44       code
45       break;
46     case INTERNAL_NL:
47       std_internal_newline(HTML_LANG)
48       break;
49     case NEWLINE:
50       std_newline(HTML_LANG)
51       break;
52     case CHECK_BLANK_ENTRY:
53       check_blank_entry(HTML_LANG)
54     }
55   }
56
57   html_comment =
58     '<!--' @comment (
59       newline %{ entity = INTERNAL_NL; } %html_ccallback
60       |
61       ws
62       |
63       (nonnewline - ws) @comment
64     )* :>> '-->';
65
66   html_sq_str =
67     '\'' @code (
68       newline %{ entity = INTERNAL_NL; } %html_ccallback
69       |
70       ws
71       |
72       [^\t '\\] @code
73       |
74       '\\' nonnewline @code
75     )* '\'';
76   html_dq_str =
77     '"' @code (
78       newline %{ entity = INTERNAL_NL; } %html_ccallback
79       |
80       ws
81       |
82       [^\t "\\] @code
83       |
84       '\\' nonnewline @code
85     )* '"';
86   html_string = html_sq_str | html_dq_str;
87
88   ws_or_inl = (ws | newline @{ entity = INTERNAL_NL; } %html_ccallback);
89
90   html_css_entry = '<' /style/i [^>]+ :>> 'text/css' [^>]+ '>' @code;
91   html_css_outry = '</' /style/i ws_or_inl* '>' @code;
92   html_css_line := |*
93     html_css_outry @{ p = ts; fgoto html_line; };
94     # unmodified CSS patterns
95     spaces      ${ entity = CSS_SPACE; } => css_ccallback;
96     css_comment;
97     css_string;
98     newline     ${ entity = NEWLINE;   } => css_ccallback;
99     ^space      ${ entity = CSS_ANY;   } => css_ccallback;
100   *|;
101
102   html_js_entry = '<' /script/i [^>]+ :>> 'text/javascript' [^>]+ '>' @code;
103   html_js_outry = '</' /script/i ws_or_inl* '>' @code;
104   html_js_line := |*
105     html_js_outry @{ p = ts; fgoto html_line; };
106     # unmodified Javascript patterns
107     spaces     ${ entity = JS_SPACE; } => js_ccallback;
108     js_comment;
109     js_string;
110     newline    ${ entity = NEWLINE;  } => js_ccallback;
111     ^space     ${ entity = JS_ANY;   } => js_ccallback;
112   *|;
113
114   html_line := |*
115     html_css_entry @{ entity = CHECK_BLANK_ENTRY; } @html_ccallback
116       @{ fgoto html_css_line; };
117     html_js_entry @{ entity = CHECK_BLANK_ENTRY; } @html_ccallback
118       @{ fgoto html_js_line; };
119     # standard HTML patterns
120     spaces       ${ entity = HTML_SPACE; } => html_ccallback;
121     html_comment;
122     html_string;
123     newline      ${ entity = NEWLINE;    } => html_ccallback;
124     ^space       ${ entity = HTML_ANY;   } => html_ccallback;
125   *|;
126
127   # Entity machine
128
129   action html_ecallback {
130     callback(HTML_LANG, entity, cint(ts), cint(te));
131   }
132
133   html_entity := 'TODO:';
134 }%%
135
136 /************************* Required for every parser *************************/
137
138 /* Parses a string buffer with HTML markup.
139  *
140  * @param *buffer The string to parse.
141  * @param length The length of the string to parse.
142  * @param count Integer flag specifying whether or not to count lines. If yes,
143  *   uses the Ragel machine optimized for counting. Otherwise uses the Ragel
144  *   machine optimized for returning entity positions.
145  * @param *callback Callback function. If count is set, callback is called for
146  *   every line of code, comment, or blank with 'lcode', 'lcomment', and
147  *   'lblank' respectively. Otherwise callback is called for each entity found.
148  */
149 void parse_html(char *buffer, int length, int count,
150   void (*callback) (const char *lang, const char *entity, int start, int end)
151   ) {
152   init
153
154   %% write init;
155   cs = (count) ? html_en_html_line : html_en_html_entity;
156   %% write exec;
157
158   // if no newline at EOF; callback contents of last line
159   if (count) { process_last_line(HTML_LANG) }
160 }
161
162 #endif
163
164 /*****************************************************************************/