Fixes recursion bug in disambiguate_in().
[ohcount] / src / parsers / xslt.rl
1 // xslt.rl written by Mitchell Foral. mitchell<att>caladbolg<dott>net.
2
3 /************************* Required for every parser *************************/
4 #ifndef OHCOUNT_XSLT_PARSER_H
5 #define OHCOUNT_XSLT_PARSER_H
6
7 #include "../parser_macros.h"
8
9 // the name of the language
10 const char *XSLT_LANG = LANG_XSLT;
11
12 // the languages entities
13 const char *xslt_entities[] = {
14   "space", "comment", "doctype",
15   "tag", "entity", "any"
16 };
17
18 // constants associated with the entities
19 enum {
20   XSLT_SPACE = 0, XSLT_COMMENT, XSLT_DOCTYPE,
21   XSLT_TAG, XSLT_ENTITY, XSLT_ANY
22 };
23
24 /*****************************************************************************/
25
26 %%{
27   machine xslt;
28   write data;
29   include common "common.rl";
30
31   # Line counting machine
32
33   action xslt_ccallback {
34     switch(entity) {
35     case XSLT_SPACE:
36       ls
37       break;
38     case XSLT_ANY:
39       code
40       break;
41     case INTERNAL_NL:
42       std_internal_newline(XSLT_LANG)
43       break;
44     case NEWLINE:
45       std_newline(XSLT_LANG)
46       break;
47     case CHECK_BLANK_ENTRY:
48       check_blank_entry(XSLT_LANG)
49     }
50   }
51
52   xslt_comment =
53     '<!--' @comment (
54       newline %{ entity = INTERNAL_NL; } %xslt_ccallback
55       |
56       ws
57       |
58       (nonnewline - ws) @comment
59     )* :>> '-->';
60
61   xslt_sq_str = '\'' ([^\r\n\f'\\] | '\\' nonnewline)* '\'' @code;
62   xslt_dq_str = '"' ([^\r\n\f"\\] | '\\' nonnewline)* '"' @code;
63   xslt_cdata_str =
64     '<![CDATA[' @code (
65       newline %{ entity = INTERNAL_NL; } %xslt_ccallback
66       |
67       ws
68       |
69       (nonnewline - ws) @code
70     )* :>> ']]>';
71   xslt_string = xslt_sq_str | xslt_dq_str | xslt_cdata_str;
72
73   xslt_line := |*
74     spaces        ${ entity = XSLT_SPACE; } => xslt_ccallback;
75     xslt_comment;
76     xslt_string;
77     newline       ${ entity = NEWLINE;    } => xslt_ccallback;
78     ^space        ${ entity = XSLT_ANY;   } => xslt_ccallback;
79   *|;
80
81   # Entity machine
82
83   action xslt_ecallback {
84     callback(XSLT_LANG, xslt_entities[entity], cint(ts), cint(te), userdata);
85   }
86
87   xslt_comment_entity = '<!--' any* :>> '-->';
88
89   xslt_entity := |*
90     space+              ${ entity = XSLT_SPACE;   } => xslt_ecallback;
91     xslt_comment_entity ${ entity = XSLT_COMMENT; } => xslt_ecallback;
92     # TODO:
93     ^space;
94   *|;
95 }%%
96
97 /************************* Required for every parser *************************/
98
99 /* Parses a string buffer with XSLT markup.
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_xslt(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   %% write init;
118   cs = (count) ? xslt_en_xslt_line : xslt_en_xslt_entity;
119   %% write exec;
120
121   // if no newline at EOF; callback contents of last line
122   if (count) { process_last_line(XSLT_LANG) }
123 }
124
125 #endif
126
127 /*****************************************************************************/