Merge pull request #41 from blackducksw/ubuntu_14
[ohcount] / src / parsers / classic_basic.rl
1 /************************* Required for every parser *************************/
2 #ifndef OHCOUNT_CLASSIC_BASIC_PARSER_H
3 #define OHCOUNT_CLASSIC_BASIC_PARSER_H
4
5 #include "../parser_macros.h"
6
7 // the name of the language
8 const char *CB_LANG = LANG_CLASSIC_BASIC;
9
10 // the languages entities
11 const char *cb_entities[] = {
12   "space", "comment", "string", "any"
13 };
14
15 // constants associated with the entities
16 enum {
17   CB_SPACE = 0, CB_COMMENT, CB_STRING, CB_ANY,
18 };
19
20 /*****************************************************************************/
21
22 %%{
23   machine classic_basic;
24   write data;
25   include common "common.rl";
26
27   # Line counting machine
28
29   action cb_ccallback {
30     switch(entity) {
31     case CB_SPACE:
32       ls
33       break;
34     case CB_ANY:
35       code
36       break;
37     case INTERNAL_NL:
38       std_internal_newline(CB_LANG)
39       break;
40     case NEWLINE:
41       std_newline(CB_LANG)
42     }
43   }
44
45   cb_comment = dec_num spaces ("'" | /rem/i) @comment nonnewline*;
46
47   cb_string = '"' @code ([^\r\n\f"\\] | '\\' nonnewline)* '"';
48
49   cb_line := |*
50     spaces      ${ entity = CB_SPACE; } => cb_ccallback;
51     cb_comment;
52     cb_string;
53     newline     ${ entity = NEWLINE;  } => cb_ccallback;
54     ^space      ${ entity = CB_ANY;   } => cb_ccallback;
55   *|;
56
57   # Entity machine
58
59   action cb_ecallback {
60     callback(CB_LANG, cb_entities[entity], cint(ts), cint(te), userdata);
61   }
62
63   cb_comment_entity = ("'" | /rem/i ws+) nonnewline*;
64
65   cb_entity := |*
66     space+            ${ entity = CB_SPACE;   } => cb_ecallback;
67     cb_comment_entity ${ entity = CB_COMMENT; } => cb_ecallback;
68     # TODO:
69     ^space;
70   *|;
71 }%%
72
73 /************************* Required for every parser *************************/
74
75 /* Parses a string buffer with Structured BASIC code.
76  *
77  * @param *buffer The string to parse.
78  * @param length The length of the string to parse.
79  * @param count Integer flag specifying whether or not to count lines. If yes,
80  *   uses the Ragel machine optimized for counting. Otherwise uses the Ragel
81  *   machine optimized for returning entity positions.
82  * @param *callback Callback function. If count is set, callback is called for
83  *   every line of code, comment, or blank with 'lcode', 'lcomment', and
84  *   'lblank' respectively. Otherwise callback is called for each entity found.
85  */
86 void parse_classic_basic(char *buffer, int length, int count,
87                          void (*callback) (const char *lang, const char *entity,
88                                            int s, int e, void *udata),
89                          void *userdata
90   ) {
91   init
92
93   %% write init;
94   cs = (count) ? classic_basic_en_cb_line : classic_basic_en_cb_entity;
95   %% write exec;
96
97   // if no newline at EOF; callback contents of last line
98   if (count) { process_last_line(CB_LANG) }
99 }
100
101 #endif
102
103 /*****************************************************************************/