New upstream version 3.1.1
Sylvestre Ledru
5 years ago
49 | 49 | |
50 | 50 | Ohcount does not support Windows. |
51 | 51 | |
52 | Ohcount targets Ruby 1.9.3. The build script requires a bash shell. You | |
52 | Ohcount targets Ruby 2.2.3. The build script requires a bash shell. You | |
53 | 53 | also need a C compiler to build the native extensions. |
54 | 54 | |
55 | 55 | Source Code |
62 | 62 | Building Ohcount |
63 | 63 | ---------------- |
64 | 64 | |
65 | > Last updated: 2018-05-10 | |
66 | ||
65 | 67 | You will need ragel 6.8 or higher, bash, gperf, libpcre3-dev, libmagic-dev, gcc (version 4.8.2 or greater) |
66 | and SWIG (2.0.11). Once you have them, go to the top directory of ohcount and run | |
68 | and SWIG (2.0.11). To get these dependencies on Ubuntu/Debian you can run this command: | |
69 | ||
70 | sudo apt-get install libpcre3 libpcre3-dev libmagic-dev gperf gcc ragel swig | |
71 | ||
72 | There is a Ruby dependency of 'test-unit' gem for Ruby 2.2.3. You will need to run this command: | |
73 | ||
74 | gem install test-unit | |
75 | ||
76 | Once you have them, go to the top directory of ohcount and run | |
67 | 77 | |
68 | 78 | ``` |
69 | 79 | ./build |
Binary diff not shown
437 | 437 | } |
438 | 438 | return NULL; // only blanks |
439 | 439 | } |
440 | ||
441 | const char *disambiguate_fs(SourceFile *sourcefile) { | |
442 | /* .fs could be Forth or F# */ | |
443 | char *contents = ohcount_sourcefile_get_contents(sourcefile); | |
444 | if (contents == NULL) | |
445 | return NULL; | |
446 | char *p = contents; | |
447 | char c = *p; | |
448 | long forthcount=0; | |
449 | long fsharpcount=0; | |
450 | while (c != '\0') { | |
451 | while (c == ' ' || c == '\t') | |
452 | c = *++p; | |
453 | if (strncmp(p,"\\ ",2)==0) forthcount++; | |
454 | else if (strncmp(p,": ",2)==0) forthcount++; | |
455 | else if (strncmp(p,"|",1)==0) fsharpcount++; | |
456 | else if (strncmp(p,"let ",4)==0) fsharpcount++; | |
457 | else if (strncmp(p,"type ",5)==0) fsharpcount++; | |
458 | else if (strncmp(p,"//",2)==0) fsharpcount++; | |
459 | while (c != '\0' && c != '\n' && c != '\r') | |
460 | c = *++p; | |
461 | while (c == '\n' || c == '\r') | |
462 | c = *++p; | |
463 | } | |
464 | if (forthcount > fsharpcount) | |
465 | return LANG_FORTH; | |
466 | else if (forthcount < fsharpcount) | |
467 | return LANG_FSHARP; | |
468 | else | |
469 | return NULL; | |
470 | } | |
440 | 471 | |
441 | 472 | const char *disambiguate_fortran(SourceFile *sourcefile) { |
442 | 473 | char *p; |
9 | 9 | const char *disambiguate_dat(SourceFile *sourcefile); |
10 | 10 | const char *disambiguate_def(SourceFile *sourcefile); |
11 | 11 | const char *disambiguate_fortran(SourceFile *sourcefile); |
12 | const char *disambiguate_fs(SourceFile *sourcefile); | |
12 | 13 | const char *disambiguate_h(SourceFile *sourcefile); |
13 | 14 | const char *disambiguate_in(SourceFile *sourcefile); |
14 | 15 | const char *disambiguate_inc(SourceFile *sourcefile); |
31 | 32 | dat, disambiguate_dat |
32 | 33 | def, disambiguate_def |
33 | 34 | fortran, disambiguate_fortran |
35 | fs, disambiguate_fs | |
34 | 36 | h, disambiguate_h |
35 | 37 | in, disambiguate_in |
36 | 38 | inc, disambiguate_inc |
42 | 42 | coffee, LANG_COFFEESCRIPT |
43 | 43 | com, LANG_DCL |
44 | 44 | cpp, LANG_CPP |
45 | cr, LANG_CRYSTAL | |
45 | 46 | cs, DISAMBIGUATE("cs") |
46 | 47 | csproj, LANG_XML |
47 | 48 | css, LANG_CSS |
73 | 74 | factor, LANG_FACTOR |
74 | 75 | fr, LANG_FORTH |
75 | 76 | frag, LANG_GLSL |
77 | frt, LANG_FORTH | |
76 | 78 | for, DISAMBIGUATE("fortran") |
79 | forth, LANG_FORTH | |
77 | 80 | fpp, DISAMBIGUATE("fortran") |
78 | 81 | frm, LANG_VISUALBASIC |
79 | 82 | frx, LANG_VISUALBASIC |
80 | fs, LANG_FSHARP | |
83 | fs, DISAMBIGUATE("fs") | |
84 | fth, LANG_FORTH | |
81 | 85 | ftn, DISAMBIGUATE("fortran") |
82 | 86 | gemspec, LANG_RUBY |
83 | 87 | gif, BINARY |
111 | 115 | js, LANG_JAVASCRIPT |
112 | 116 | jsp, LANG_JSP |
113 | 117 | kdebuild-1, LANG_EBUILD |
118 | kt, LANG_KOTLIN | |
119 | lc, LANG_LIVECODE | |
114 | 120 | latex, LANG_TEX |
115 | 121 | lisp, LANG_LISP |
116 | 122 | lsp, LANG_LISP |
127 | 133 | ml4, LANG_OCAML |
128 | 134 | mli, LANG_OCAML |
129 | 135 | mm, LANG_OBJECTIVE_C |
136 | mo, LANG_MODELICA | |
130 | 137 | mod, DISAMBIGUATE("mod") |
131 | 138 | mov, BINARY |
132 | 139 | mp, LANG_METAPOST_WITH_TEX |
162 | 169 | pp, DISAMBIGUATE("pp") |
163 | 170 | ppt, BINARY |
164 | 171 | pro, DISAMBIGUATE("pro") |
172 | ps, LANG_POSTSCRIPT | |
165 | 173 | py, LANG_PYTHON |
166 | 174 | qml, LANG_QML |
167 | 175 | qt, BINARY |
207 | 215 | tif, BINARY |
208 | 216 | tiff, BINARY |
209 | 217 | tpl, LANG_HTML |
218 | uc, LANG_UNREALSCRIPT | |
210 | 219 | ts, LANG_TYPESCRIPT |
211 | 220 | tsx, LANG_TYPESCRIPT |
212 | 221 | vala, LANG_VALA |
17 | 17 | rakefile, LANG_RUBY |
18 | 18 | Gemfile, LANG_RUBY |
19 | 19 | Vagrantfile, LANG_RUBY |
20 | PKGBUILD, LANG_SHELL | |
21 | script.utf8, LANG_LIVECODE |
26 | 26 | coffescript, LANG_COFFEESCRIPT, "CoffeeScript", 0 |
27 | 27 | coq, LANG_COQ, "Coq", 0 |
28 | 28 | cpp, LANG_CPP, "C++", 0 |
29 | crystal, LANG_CRYSTAL, "Crystal", 0 | |
29 | 30 | cs_aspx, LANG_CS_ASPX, "", 0 |
30 | 31 | csharp, LANG_CSHARP, "C#", 0 |
31 | 32 | css, LANG_CSS, "CSS", 1 |
59 | 60 | java, LANG_JAVA, "Java", 0 |
60 | 61 | javascript, LANG_JAVASCRIPT, "JavaScript", 0 |
61 | 62 | jsp, LANG_JSP, "", 0 |
63 | kotlin, LANG_KOTLIN, "Kotlin", 0 | |
62 | 64 | limbo, LANG_LIMBO, "Limbo", 0 |
63 | 65 | lisp, LANG_LISP, "Lisp", 0 |
66 | livecode, LANG_LIVECODE, "LiveCode", 0 | |
64 | 67 | logtalk, LANG_LOGTALK, "Logtalk", 0 |
65 | 68 | lua, LANG_LUA, "Lua", 0 |
66 | 69 | make, LANG_MAKE, "Make", 2 |
69 | 72 | metafont, LANG_METAFONT, "MetaFont", 1 |
70 | 73 | metapost, LANG_METAPOST, "MetaPost", 1 |
71 | 74 | metapost_with_tex, LANG_METAPOST_WITH_TEX, "", 0 |
75 | modelica, LANG_MODELICA, "Modelica", 0 | |
72 | 76 | modula2, LANG_MODULA2, "Modula-2", 0 |
73 | 77 | modula3, LANG_MODULA3, "Modula-3", 0 |
74 | 78 | mxml, LANG_MXML, "MXML", 1 |
83 | 87 | perl, LANG_PERL, "Perl", 0 |
84 | 88 | php, LANG_PHP, "PHP", 0 |
85 | 89 | pike, LANG_PIKE, "Pike", 0 |
90 | postscript, LANG_POSTSCRIPT, "PostScript", 1 | |
86 | 91 | prolog, LANG_PROLOG, "Prolog", 0 |
87 | 92 | puppet, LANG_PUPPET, "Puppet", 0 |
88 | 93 | python, LANG_PYTHON, "Python", 0 |
104 | 109 | sql, LANG_SQL, "SQL", 0 |
105 | 110 | tcl, LANG_TCL, "TCL", 0 |
106 | 111 | tex, LANG_TEX, "TeX/LaTeX", 1 |
112 | unrealscript, LANG_UNREALSCRIPT, "UnrealScript", 0 | |
107 | 113 | typescript, LANG_TYPESCRIPT, "TypeScript", 0 |
108 | 114 | vala, LANG_VALA, "Vala", 0 |
109 | 115 | vb_aspx, LANG_VB_ASPX, "", 0 |
19 | 19 | #include "../parsers/coffeescript.h" |
20 | 20 | #include "../parsers/cmake.h" |
21 | 21 | #include "../parsers/coq.h" |
22 | #include "../parsers/crystal.h" | |
22 | 23 | #include "../parsers/cs_aspx.h" |
23 | 24 | #include "../parsers/css.h" |
24 | 25 | #include "../parsers/d.h" |
46 | 47 | #include "../parsers/java.h" |
47 | 48 | #include "../parsers/javascript.h" |
48 | 49 | #include "../parsers/jsp.h" |
50 | #include "../parsers/kotlin.h" | |
49 | 51 | #include "../parsers/lisp.h" |
50 | 52 | #include "../parsers/limbo.h" |
53 | #include "../parsers/livecode.h" | |
51 | 54 | #include "../parsers/logtalk.h" |
52 | 55 | #include "../parsers/lua.h" |
53 | 56 | #include "../parsers/makefile.h" |
56 | 59 | #include "../parsers/metafont.h" |
57 | 60 | #include "../parsers/metapost.h" |
58 | 61 | #include "../parsers/metapost_with_tex.h" |
62 | #include "../parsers/modelica.h" | |
59 | 63 | #include "../parsers/modula2.h" |
60 | 64 | #include "../parsers/modula3.h" |
61 | 65 | #include "../parsers/mxml.h" |
70 | 74 | #include "../parsers/perl.h" |
71 | 75 | #include "../parsers/phphtml.h" |
72 | 76 | #include "../parsers/pike.h" |
77 | #include "../parsers/postscript.h" | |
73 | 78 | #include "../parsers/prolog.h" |
74 | 79 | #include "../parsers/puppet.h" |
75 | 80 | #include "../parsers/python.h" |
89 | 94 | #include "../parsers/tcl.h" |
90 | 95 | #include "../parsers/tex.h" |
91 | 96 | #include "../parsers/tex_dtx.h" |
97 | #include "../parsers/unrealscript.h" | |
92 | 98 | #include "../parsers/vb_aspx.h" |
93 | 99 | #include "../parsers/vhdl.h" |
94 | 100 | #include "../parsers/vim.h" |
122 | 128 | clojure, parse_clojure |
123 | 129 | coffeescript, parse_coffeescript |
124 | 130 | coq, parse_coq |
131 | crystal, parse_crystal | |
125 | 132 | cpp, parse_cpp |
126 | 133 | cs_aspx, parse_cs_aspx |
127 | 134 | csharp, parse_csharp |
155 | 162 | java, parse_java |
156 | 163 | javascript, parse_javascript |
157 | 164 | jsp, parse_jsp |
165 | kotlin, parse_kotlin | |
158 | 166 | lisp, parse_lisp |
159 | 167 | limbo, parse_limbo |
168 | lisp, parse_lisp | |
169 | livecode, parse_livecode | |
160 | 170 | logtalk, parse_logtalk |
161 | 171 | lua, parse_lua |
162 | 172 | make, parse_makefile |
165 | 175 | metafont, parse_metafont |
166 | 176 | metapost, parse_metapost |
167 | 177 | metapost_with_tex, parse_mptex |
178 | modelica, parse_modelica | |
168 | 179 | modula2, parse_modula2 |
169 | 180 | modula3, parse_modula3 |
170 | 181 | mxml, parse_mxml |
179 | 190 | perl, parse_perl |
180 | 191 | php, parse_phtml |
181 | 192 | pike, parse_pike |
193 | postscript, parse_postscript | |
182 | 194 | prolog, parse_prolog |
183 | 195 | puppet, parse_puppet |
184 | 196 | python, parse_python |
201 | 213 | tcl, parse_tcl |
202 | 214 | tex, parse_tex |
203 | 215 | tex_dtx, parse_tex_dtx |
216 | unrealscript, parse_unrealscript | |
204 | 217 | typescript, parse_typescript |
205 | 218 | vala, parse_vala |
206 | 219 | vb_aspx, parse_vb_aspx |
28 | 28 | #define LANG_COFFEESCRIPT "coffeescript" |
29 | 29 | #define LANG_COQ "coq" |
30 | 30 | #define LANG_CPP "cpp" |
31 | #define LANG_CRYSTAL "crystal" | |
31 | 32 | #define LANG_CS_ASPX "cs_aspx" |
32 | 33 | #define LANG_CSHARP "csharp" |
33 | 34 | #define LANG_CSS "css" |
60 | 61 | #define LANG_JAVA "java" |
61 | 62 | #define LANG_JAVASCRIPT "javascript" |
62 | 63 | #define LANG_JSP "jsp" |
64 | #define LANG_KOTLIN "kotlin" | |
63 | 65 | #define LANG_LIMBO "limbo" |
64 | 66 | #define LANG_LISP "lisp" |
67 | #define LANG_LIVECODE "livecode" | |
65 | 68 | #define LANG_LOGTALK "logtalk" |
66 | 69 | #define LANG_LUA "lua" |
67 | 70 | #define LANG_MAKE "make" |
70 | 73 | #define LANG_METAFONT "metafont" |
71 | 74 | #define LANG_METAPOST "metapost" |
72 | 75 | #define LANG_METAPOST_WITH_TEX "metapost_with_tex" |
76 | #define LANG_MODELICA "modelica" | |
73 | 77 | #define LANG_MODULA2 "modula2" |
74 | 78 | #define LANG_MODULA3 "modula3" |
75 | 79 | #define LANG_MXML "mxml" |
84 | 88 | #define LANG_PERL "perl" |
85 | 89 | #define LANG_PHP "php" |
86 | 90 | #define LANG_PIKE "pike" |
91 | #define LANG_POSTSCRIPT "postscript" | |
87 | 92 | #define LANG_PROLOG "prolog" |
88 | 93 | #define LANG_PUPPET "puppet" |
89 | 94 | #define LANG_PYTHON "python" |
106 | 111 | #define LANG_TCL "tcl" |
107 | 112 | #define LANG_TEX "tex" |
108 | 113 | #define LANG_TEX_DTX "tex_dtx" |
114 | #define LANG_UNREALSCRIPT "unrealscript" | |
109 | 115 | #define LANG_TYPESCRIPT "typescript" |
110 | 116 | #define LANG_VALA "vala" |
111 | 117 | #define LANG_VB_ASPX "vb_aspx" |
0 | // renamed copy of ruby.rl(without *_sq_str). | |
1 | ||
2 | /************************* Required for every parser *************************/ | |
3 | #ifndef OHCOUNT_CRYSTAL_PARSER_H | |
4 | #define OHCOUNT_CRYSTAL_PARSER_H | |
5 | ||
6 | #include "../parser_macros.h" | |
7 | ||
8 | // the name of the language | |
9 | const char *CRYSTAL_LANG = LANG_CRYSTAL; | |
10 | ||
11 | // the languages entities | |
12 | const char *crystal_entities[] = { | |
13 | "space", "comment", "string", "any" | |
14 | }; | |
15 | ||
16 | // constants associated with the entities | |
17 | enum { | |
18 | CRYSTAL_SPACE = 0, CRYSTAL_COMMENT, CRYSTAL_STRING, CRYSTAL_ANY | |
19 | }; | |
20 | ||
21 | /*****************************************************************************/ | |
22 | ||
23 | %%{ | |
24 | machine crystal; | |
25 | write data; | |
26 | include common "common.rl"; | |
27 | ||
28 | # Line counting machine | |
29 | ||
30 | action crystal_ccallback { | |
31 | switch(entity) { | |
32 | case CRYSTAL_SPACE: | |
33 | ls | |
34 | break; | |
35 | case CRYSTAL_ANY: | |
36 | code | |
37 | break; | |
38 | case INTERNAL_NL: | |
39 | std_internal_newline(CRYSTAL_LANG) | |
40 | break; | |
41 | case NEWLINE: | |
42 | std_newline(CRYSTAL_LANG) | |
43 | } | |
44 | } | |
45 | ||
46 | crystal_line_comment = '#' @comment nonnewline*; | |
47 | # TODO: detect =begin and =end at start of their lines | |
48 | # Can't do that now because using 'when starts_line' fails a Ragel assertion. | |
49 | crystal_block_comment = | |
50 | '=begin' @enqueue @comment ( | |
51 | newline %{ entity = INTERNAL_NL; } %crystal_ccallback | |
52 | | | |
53 | ws | |
54 | | | |
55 | (nonnewline - ws) @comment | |
56 | )* :>> '=end' @commit; | |
57 | crystal_comment = crystal_line_comment | crystal_block_comment; | |
58 | ||
59 | crystal_dq_str = | |
60 | '"' @enqueue @code ( | |
61 | newline %{ entity = INTERNAL_NL; } %crystal_ccallback | |
62 | | | |
63 | ws | |
64 | | | |
65 | [^\r\n\f\t "\\] @code | |
66 | | | |
67 | '\\' nonnewline @code | |
68 | )* '"' @commit @code; | |
69 | # TODO: true literal string detection | |
70 | # Turns out any non-alphanum char can be after the initial '%' for a literal | |
71 | # string. I only have '(', '[', '{' for now because they are common(?). Their | |
72 | # respective closing characters need to be escaped though, which is not | |
73 | # accurate; only the single closing character needs to be escaped in a literal | |
74 | # string. | |
75 | # We need to detect which non-alphanum char opens a literal string, somehow | |
76 | # let Ragel know what it is (currently unsupported), and put its respective | |
77 | # closing char in the literal string below. | |
78 | crystal_lit_str = | |
79 | '%' [qQ]? [(\[{] @enqueue @code ( | |
80 | newline %{ entity = INTERNAL_NL; } %crystal_ccallback | |
81 | | | |
82 | ws | |
83 | | | |
84 | [^\r\n\f\t )\]}\\] @code | |
85 | | | |
86 | '\\' nonnewline @code | |
87 | )* [)\]}] @commit @code; | |
88 | crystal_cmd_str = | |
89 | '`' @enqueue @code ( | |
90 | newline %{ entity = INTERNAL_NL; } %crystal_ccallback | |
91 | | | |
92 | ws | |
93 | | | |
94 | [^\r\n\f\t `\\] @code | |
95 | | | |
96 | '\\' nonnewline @code | |
97 | )* '`' @commit @code; | |
98 | crystal_regex = '/' ([^\r\n\f/\\] | '\\' nonnewline)* '/' @code; | |
99 | # TODO: true literal array and command detection | |
100 | # See TODO above about literal string detection | |
101 | crystal_lit_other = | |
102 | '%' [wrx] [(\[{] @enqueue @code ( | |
103 | newline %{ entity = INTERNAL_NL; } %crystal_ccallback | |
104 | | | |
105 | ws | |
106 | | | |
107 | [^\r\n\f\t )\]}\\] @code | |
108 | | | |
109 | '\\' nonnewline @code | |
110 | )* [)\]}] @commit @code; | |
111 | # TODO: heredoc detection | |
112 | # This is impossible with current Ragel. We need to extract what the end | |
113 | # delimiter should be from the heredoc and search up to it on a new line. | |
114 | # crystal_heredoc = | |
115 | crystal_string = | |
116 | crystal_dq_str | crystal_lit_str | crystal_cmd_str | crystal_regex | | |
117 | crystal_lit_other; | |
118 | ||
119 | crystal_line := |* | |
120 | spaces ${ entity = CRYSTAL_SPACE; } => crystal_ccallback; | |
121 | crystal_comment; | |
122 | crystal_string; | |
123 | newline ${ entity = NEWLINE; } => crystal_ccallback; | |
124 | ^space ${ entity = CRYSTAL_ANY; } => crystal_ccallback; | |
125 | *|; | |
126 | ||
127 | # Entity machine | |
128 | ||
129 | action crystal_ecallback { | |
130 | callback(CRYSTAL_LANG, crystal_entities[entity], cint(ts), cint(te), userdata); | |
131 | } | |
132 | ||
133 | crystal_line_comment_entity = '#' nonnewline*; | |
134 | crystal_block_comment_entity = ('=' when starts_line) 'begin' | |
135 | any* :>> (('=' when starts_line) 'end'); | |
136 | crystal_comment_entity = crystal_line_comment_entity | crystal_block_comment_entity; | |
137 | ||
138 | crystal_entity := |* | |
139 | space+ ${ entity = CRYSTAL_SPACE; } => crystal_ecallback; | |
140 | crystal_comment_entity ${ entity = CRYSTAL_COMMENT; } => crystal_ecallback; | |
141 | # TODO: | |
142 | ^space; | |
143 | *|; | |
144 | }%% | |
145 | ||
146 | /************************* Required for every parser *************************/ | |
147 | ||
148 | /* Parses a string buffer with crystal code. | |
149 | * | |
150 | * @param *buffer The string to parse. | |
151 | * @param length The length of the string to parse. | |
152 | * @param count Integer flag specifying whether or not to count lines. If yes, | |
153 | * uses the Ragel machine optimized for counting. Otherwise uses the Ragel | |
154 | * machine optimized for returning entity positions. | |
155 | * @param *callback Callback function. If count is set, callback is called for | |
156 | * every line of code, comment, or blank with 'lcode', 'lcomment', and | |
157 | * 'lblank' respectively. Otherwise callback is called for each entity found. | |
158 | */ | |
159 | void parse_crystal(char *buffer, int length, int count, | |
160 | void (*callback) (const char *lang, const char *entity, int s, | |
161 | int e, void *udata), | |
162 | void *userdata | |
163 | ) { | |
164 | init | |
165 | ||
166 | %% write init; | |
167 | cs = (count) ? crystal_en_crystal_line : crystal_en_crystal_entity; | |
168 | %% write exec; | |
169 | ||
170 | // if no newline at EOF; callback contents of last line | |
171 | if (count) { process_last_line(CRYSTAL_LANG) } | |
172 | } | |
173 | ||
174 | #endif | |
175 | ||
176 | /*****************************************************************************/ |
0 | // kotlin.rl written by Tuomas Tynkkynen <tuomas.tynkkynen@iki.fi> | |
1 | // Inspired by rust.rl, python.rl and haskell.rl | |
2 | ||
3 | /************************* Required for every parser *************************/ | |
4 | #ifndef OHCOUNT_KOTLIN_PARSER_H | |
5 | #define OHCOUNT_KOTLIN_PARSER_H | |
6 | ||
7 | #include "../parser_macros.h" | |
8 | ||
9 | // the name of the language | |
10 | const char *KOTLIN_LANG = LANG_KOTLIN; | |
11 | ||
12 | // the languages entities | |
13 | const char *kotlin_entities[] = { | |
14 | "space", "comment", "string", "number", | |
15 | "keyword", "identifier", "operator", "any" | |
16 | }; | |
17 | ||
18 | // constants associated with the entities | |
19 | enum { | |
20 | KOTLIN_SPACE = 0, KOTLIN_COMMENT, KOTLIN_STRING, KOTLIN_NUMBER, | |
21 | KOTLIN_KEYWORD, KOTLIN_IDENTIFIER, KOTLIN_OPERATOR, KOTLIN_ANY | |
22 | }; | |
23 | ||
24 | /*****************************************************************************/ | |
25 | ||
26 | %%{ | |
27 | machine kotlin; | |
28 | write data; | |
29 | include common "common.rl"; | |
30 | ||
31 | # Line counting machine | |
32 | ||
33 | action kotlin_ccallback { | |
34 | switch(entity) { | |
35 | case KOTLIN_SPACE: | |
36 | ls | |
37 | break; | |
38 | case KOTLIN_ANY: | |
39 | code | |
40 | break; | |
41 | case INTERNAL_NL: | |
42 | std_internal_newline(KOTLIN_LANG) | |
43 | break; | |
44 | case NEWLINE: | |
45 | std_newline(KOTLIN_LANG) | |
46 | } | |
47 | } | |
48 | ||
49 | action kotlin_comment_nc_res { kotlin_comment_nest_count = 0; } | |
50 | action kotlin_comment_nc_inc { kotlin_comment_nest_count++; } | |
51 | action kotlin_comment_nc_dec { kotlin_comment_nest_count--; } | |
52 | ||
53 | kotlin_line_comment = '//' @comment nonnewline*; | |
54 | kotlin_block_comment = | |
55 | '/*' >kotlin_comment_nc_res @comment ( | |
56 | newline %{ entity = INTERNAL_NL; } %kotlin_ccallback | |
57 | | | |
58 | ws | |
59 | | | |
60 | '/*' @kotlin_comment_nc_inc @comment | |
61 | | | |
62 | '*/' @kotlin_comment_nc_dec @comment | |
63 | | | |
64 | (nonnewline - ws) @comment | |
65 | )* :>> ('*/' when { kotlin_comment_nest_count == 0 }) @comment; | |
66 | kotlin_comment = kotlin_line_comment | kotlin_block_comment; | |
67 | ||
68 | kotlin_dq_str = | |
69 | '"' @code ([^"] | '"' [^"] @{ fhold; }) @{ fhold; } # make sure it's not """ | |
70 | ([^\r\n\f"\\] | '\\' nonnewline)* '"'; | |
71 | kotlin_raw_str = | |
72 | '"""' @code ( | |
73 | newline %{ entity = INTERNAL_NL; } %kotlin_ccallback | |
74 | | | |
75 | ws | |
76 | | | |
77 | [^\t ] @code | |
78 | )* '"""'; | |
79 | kotlin_string = kotlin_dq_str | kotlin_raw_str; | |
80 | ||
81 | kotlin_line := |* | |
82 | spaces ${ entity = KOTLIN_SPACE; } => kotlin_ccallback; | |
83 | kotlin_comment; | |
84 | kotlin_string; | |
85 | newline ${ entity = NEWLINE; } => kotlin_ccallback; | |
86 | ^space ${ entity = KOTLIN_ANY; } => kotlin_ccallback; | |
87 | *|; | |
88 | ||
89 | # Entity machine | |
90 | ||
91 | action kotlin_ecallback { | |
92 | callback(KOTLIN_LANG, kotlin_entities[entity], cint(ts), cint(te), userdata); | |
93 | } | |
94 | ||
95 | kotlin_line_comment_entity = '//' nonnewline*; | |
96 | kotlin_block_comment_entity = '/*' any* :>> '*/'; | |
97 | kotlin_comment_entity = kotlin_line_comment_entity | kotlin_block_comment_entity; | |
98 | ||
99 | kotlin_raw_string_entity = '"""' any* :>> '"""'; | |
100 | kotlin_string_entity = dq_str_with_escapes | kotlin_raw_string_entity; | |
101 | ||
102 | kotlin_float_suffix_ty = [fF]; | |
103 | kotlin_long_suffix = 'L'; | |
104 | kotlin_hex_suffix = kotlin_long_suffix | |
105 | | '.' [0-9A-Fa-f]* kotlin_float_suffix_ty?; | |
106 | ||
107 | kotlin_dec_lit = [0-9]+; | |
108 | kotlin_exponent = [Ee] [\-+]? kotlin_dec_lit; | |
109 | kotlin_float_suffix = (kotlin_exponent | '.' kotlin_dec_lit kotlin_exponent?)? | |
110 | kotlin_float_suffix_ty?; | |
111 | ||
112 | kotlin_num_suffix = kotlin_long_suffix | kotlin_float_suffix; | |
113 | ||
114 | kotlin_number_entity = [1-9] [0-9]* kotlin_num_suffix? | |
115 | | '0' ( [0-9]* kotlin_num_suffix? | |
116 | | 'b' [01]+ kotlin_long_suffix? | |
117 | | 'x' [0-9A-Fa-f]+ kotlin_hex_suffix?); | |
118 | ||
119 | kotlin_plain_identifier = (alpha | '_') (alnum | '_')*; | |
120 | kotlin_identifier_entity = kotlin_plain_identifier | '`' kotlin_plain_identifier '`'; | |
121 | ||
122 | kotlin_keyword_entity = | |
123 | 'as' | 'break' | 'class' | 'continue' | 'do' | 'else' | 'false' | 'for' | | |
124 | 'fun' | 'if' | 'in' | 'is' | 'null' | 'object' | 'package' | 'return' | | |
125 | 'super' | 'this' | 'This' | 'throw' | 'trait' | 'true' | 'try' | 'type' | | |
126 | 'val' | 'var' | 'when' | 'while'; | |
127 | ||
128 | kotlin_operator_entity = [+\-/*%<>!=^&|?~:;.,()\[\]{}]; | |
129 | ||
130 | kotlin_entity := |* | |
131 | space+ ${ entity = KOTLIN_SPACE; } => kotlin_ecallback; | |
132 | kotlin_comment_entity ${ entity = KOTLIN_COMMENT; } => kotlin_ecallback; | |
133 | kotlin_string_entity ${ entity = KOTLIN_STRING; } => kotlin_ecallback; | |
134 | kotlin_number_entity ${ entity = KOTLIN_NUMBER; } => kotlin_ecallback; | |
135 | kotlin_identifier_entity ${ entity = KOTLIN_IDENTIFIER; } => kotlin_ecallback; | |
136 | kotlin_keyword_entity ${ entity = KOTLIN_KEYWORD; } => kotlin_ecallback; | |
137 | kotlin_operator_entity ${ entity = KOTLIN_OPERATOR; } => kotlin_ecallback; | |
138 | ^(space | digit) ${ entity = KOTLIN_ANY; } => kotlin_ecallback; | |
139 | *|; | |
140 | }%% | |
141 | ||
142 | /************************* Required for every parser *************************/ | |
143 | ||
144 | /* Parses a string buffer with C/C++ code. | |
145 | * | |
146 | * @param *buffer The string to parse. | |
147 | * @param length The length of the string to parse. | |
148 | * @param count Integer flag specifying whether or not to count lines. If yes, | |
149 | * uses the Ragel machine optimized for counting. Otherwise uses the Ragel | |
150 | * machine optimized for returning entity positions. | |
151 | * @param *callback Callback function. If count is set, callback is called for | |
152 | * every line of code, comment, or blank with 'lcode', 'lcomment', and | |
153 | * 'lblank' respectively. Otherwise callback is called for each entity found. | |
154 | */ | |
155 | void parse_kotlin(char *buffer, int length, int count, | |
156 | void (*callback) (const char *lang, const char *entity, int s, | |
157 | int e, void *udata), | |
158 | void *userdata | |
159 | ) { | |
160 | init | |
161 | ||
162 | int kotlin_comment_nest_count = 0; | |
163 | ||
164 | %% write init; | |
165 | cs = (count) ? kotlin_en_kotlin_line : kotlin_en_kotlin_entity; | |
166 | %% write exec; | |
167 | ||
168 | // if no newline at EOF; callback contents of last line | |
169 | if (count) { process_last_line(KOTLIN_LANG) } | |
170 | } | |
171 | ||
172 | const char *ORIG_KOTLIN_LANG = LANG_KOTLIN; | |
173 | ||
174 | #endif | |
175 | ||
176 | /*****************************************************************************/ |
0 | // livecode.rl written by Monte Goulding. monte<att>goulding<dott>ws. | |
1 | ||
2 | /************************* Required for every parser *************************/ | |
3 | #ifndef OHCOUNT_LIVECODE_PARSER_H | |
4 | #define OHCOUNT_LIVECODE_PARSER_H | |
5 | ||
6 | #include "../parser_macros.h" | |
7 | ||
8 | // the name of the language | |
9 | const char *LIVECODE_LANG = LANG_LIVECODE; | |
10 | ||
11 | // the languages entities | |
12 | const char *livecode_entities[] = { | |
13 | "space", "comment", "string", "any", | |
14 | }; | |
15 | ||
16 | // constants associated with the entities | |
17 | enum { | |
18 | LIVECODE_SPACE = 0, LIVECODE_COMMENT, LIVECODE_STRING, LIVECODE_ANY | |
19 | }; | |
20 | ||
21 | /*****************************************************************************/ | |
22 | ||
23 | %%{ | |
24 | machine livecode; | |
25 | write data; | |
26 | include common "common.rl"; | |
27 | ||
28 | # Line counting machine | |
29 | ||
30 | action livecode_ccallback { | |
31 | switch(entity) { | |
32 | case LIVECODE_SPACE: | |
33 | ls | |
34 | break; | |
35 | case LIVECODE_ANY: | |
36 | code | |
37 | break; | |
38 | case INTERNAL_NL: | |
39 | std_internal_newline(LIVECODE_LANG) | |
40 | break; | |
41 | case NEWLINE: | |
42 | std_newline(LIVECODE_LANG) | |
43 | } | |
44 | } | |
45 | ||
46 | livecode_line_comment = ('--' | '#' | '//') @comment nonnewline*; | |
47 | livecode_block_comment = | |
48 | '/*' @comment ( | |
49 | newline %{ entity = INTERNAL_NL; } %livecode_ccallback | |
50 | | | |
51 | ws | |
52 | | | |
53 | (nonnewline - ws) @comment | |
54 | )* :>> '*/'; | |
55 | ||
56 | livecode_comment = livecode_line_comment | livecode_block_comment; | |
57 | ||
58 | livecode_string = '"' @code ([^\r\n\f"\\] | '\\' nonnewline)* '"'; | |
59 | ||
60 | livecode_line := |* | |
61 | spaces ${ entity = LIVECODE_SPACE; } => livecode_ccallback; | |
62 | livecode_comment; | |
63 | livecode_string; | |
64 | newline ${ entity = NEWLINE; } => livecode_ccallback; | |
65 | ^space ${ entity = LIVECODE_ANY; } => livecode_ccallback; | |
66 | *|; | |
67 | ||
68 | # Entity machine | |
69 | ||
70 | action livecode_ecallback { | |
71 | callback(LIVECODE_LANG, livecode_entities[entity], cint(ts), cint(te), userdata); | |
72 | } | |
73 | ||
74 | livecode_line_comment_entity = ('--' | '#' | '//') nonnewline*; | |
75 | livecode_block_comment_entity = '/*' any* :>> '*/'; | |
76 | livecode_comment_entity = livecode_line_comment_entity | livecode_block_comment_entity; | |
77 | ||
78 | livecode_entity := |* | |
79 | space+ ${ entity = LIVECODE_SPACE; } => livecode_ecallback; | |
80 | livecode_comment_entity ${ entity = LIVECODE_COMMENT; } => livecode_ecallback; | |
81 | # TODO: | |
82 | ^space; | |
83 | *|; | |
84 | }%% | |
85 | ||
86 | /************************* Required for every parser *************************/ | |
87 | ||
88 | /* Parses a string buffer with LiveCode code. | |
89 | * | |
90 | * @param *buffer The string to parse. | |
91 | * @param length The length of the string to parse. | |
92 | * @param count Integer flag specifying whether or not to count lines. If yes, | |
93 | * uses the Ragel machine optimized for counting. Otherwise uses the Ragel | |
94 | * machine optimized for returning entity positions. | |
95 | * @param *callback Callback function. If count is set, callback is called for | |
96 | * every line of code, comment, or blank with 'lcode', 'lcomment', and | |
97 | * 'lblank' respectively. Otherwise callback is called for each entity found. | |
98 | */ | |
99 | void parse_livecode(char *buffer, int length, int count, | |
100 | void (*callback) (const char *lang, const char *entity, int s, | |
101 | int e, void *udata), | |
102 | void *userdata | |
103 | ) { | |
104 | init | |
105 | ||
106 | %% write init; | |
107 | cs = (count) ? livecode_en_livecode_line : livecode_en_livecode_entity; | |
108 | %% write exec; | |
109 | ||
110 | // if no newline at EOF; callback contents of last line | |
111 | if (count) { process_last_line(LIVECODE_LANG) } | |
112 | } | |
113 | ||
114 | #endif | |
115 | ||
116 | /*****************************************************************************/ |
0 | // modelica.rl written by Martin Sjölund. martin.sjolund<att>liu<dott>se | |
1 | ||
2 | /************************* Required for every parser *************************/ | |
3 | #ifndef OHCOUNT_MODELICA_PARSER_H | |
4 | #define OHCOUNT_MODELICA_PARSER_H | |
5 | ||
6 | #include "../parser_macros.h" | |
7 | ||
8 | // the name of the language | |
9 | const char *MODELICA_LANG = LANG_MODELICA; | |
10 | ||
11 | // the languages entities | |
12 | const char *modelica_entities[] = { | |
13 | "space", "comment", "string", "any" | |
14 | }; | |
15 | ||
16 | // constants associated with the entities | |
17 | enum { | |
18 | MODELICA_SPACE = 0, MODELICA_COMMENT, MODELICA_STRING, MODELICA_ANY | |
19 | }; | |
20 | ||
21 | /*****************************************************************************/ | |
22 | ||
23 | %%{ | |
24 | machine modelica; | |
25 | write data; | |
26 | include common "common.rl"; | |
27 | ||
28 | # Line counting machine | |
29 | ||
30 | action modelica_ccallback { | |
31 | switch(entity) { | |
32 | case MODELICA_SPACE: | |
33 | ls | |
34 | break; | |
35 | case MODELICA_ANY: | |
36 | code | |
37 | break; | |
38 | case INTERNAL_NL: | |
39 | std_internal_newline(MODELICA_LANG) | |
40 | break; | |
41 | case NEWLINE: | |
42 | std_newline(MODELICA_LANG) | |
43 | } | |
44 | } | |
45 | ||
46 | modelica_line_comment = '//' @comment nonnewline*; | |
47 | ||
48 | modelica_block_comment = | |
49 | '/*' @comment ( | |
50 | newline %{ entity = INTERNAL_NL; } %modelica_ccallback | |
51 | | | |
52 | ws | |
53 | | | |
54 | (nonnewline - ws) @comment | |
55 | )* :>> '*/'; | |
56 | ||
57 | modelica_comment = modelica_line_comment | modelica_block_comment; | |
58 | identifier = '\'' (([^'] - ws + ' ')*|'\\\'') '\'' @code; | |
59 | string = '\"' @code | |
60 | (newline %{ entity = INTERNAL_NL; } %modelica_ccallback | |
61 | |ws | |
62 | |[^ \t\n"\\] @code | |
63 | |'\\\"' @code | |
64 | )* '\"' @code; | |
65 | ||
66 | modelica_line := |* | |
67 | spaces ${ entity = MODELICA_SPACE; } => modelica_ccallback; | |
68 | modelica_comment; | |
69 | newline ${ entity = NEWLINE; } => modelica_ccallback; | |
70 | identifier ${ entity = MODELICA_ANY; } => modelica_ccallback; | |
71 | string ${ entity = MODELICA_ANY; } => modelica_ccallback; | |
72 | ^space ${ entity = MODELICA_ANY; } => modelica_ccallback; | |
73 | *|; | |
74 | ||
75 | # Entity machine | |
76 | ||
77 | action modelica_ecallback { | |
78 | callback(MODELICA_LANG, modelica_entities[entity], cint(ts), cint(te), userdata); | |
79 | } | |
80 | ||
81 | modelica_eline_comment = '//' @comment nonnewline*; | |
82 | ||
83 | modelica_eblock_comment = | |
84 | '/*' @comment ( | |
85 | newline %{ entity = INTERNAL_NL; } %modelica_ccallback | |
86 | | | |
87 | ws | |
88 | | | |
89 | (nonnewline - ws) @comment | |
90 | )* :>> '*/'; | |
91 | ||
92 | modelica_ecomment = modelica_line_comment | modelica_block_comment; | |
93 | ||
94 | modelica_entity := |* | |
95 | space+ ${ entity = MODELICA_SPACE; } => modelica_ecallback; | |
96 | modelica_ecomment ${ entity = MODELICA_COMMENT; } => modelica_ecallback; | |
97 | identifier ${ entity = MODELICA_ANY; } => modelica_ecallback; | |
98 | string ${ entity = MODELICA_ANY; } => modelica_ecallback; | |
99 | ^space; | |
100 | *|; | |
101 | }%% | |
102 | ||
103 | /************************* Required for every parser *************************/ | |
104 | ||
105 | /* Parses a string buffer with Modelica code. | |
106 | * | |
107 | * @param *buffer The string to parse. | |
108 | * @param length The length of the string to parse. | |
109 | * @param count Integer flag specifying whether or not to count lines. If yes, | |
110 | * uses the Ragel machine optimized for counting. Otherwise uses the Ragel | |
111 | * machine optimized for returning entity positions. | |
112 | * @param *callback Callback function. If count is set, callback is called for | |
113 | * every line of code, comment, or blank with 'lcode', 'lcomment', and | |
114 | * 'lblank' respectively. Otherwise callback is called for each entity found. | |
115 | */ | |
116 | void parse_modelica(char *buffer, int length, int count, | |
117 | void (*callback) (const char *lang, const char *entity, int s, | |
118 | int e, void *udata), | |
119 | void *userdata | |
120 | ) { | |
121 | init | |
122 | %% write init; | |
123 | cs = (count) ? modelica_en_modelica_line : modelica_en_modelica_entity; | |
124 | %% write exec; | |
125 | ||
126 | // if no newline at EOF; callback contents of last line | |
127 | if (count) { process_last_line(MODELICA_LANG) } | |
128 | } | |
129 | ||
130 | #endif | |
131 | ||
132 | /*****************************************************************************/ |
0 | /************************* Required for every parser *************************/ | |
1 | #ifndef OHCOUNT_PS_PARSER_H | |
2 | #define OHCOUNT_PS_PARSER_H | |
3 | ||
4 | #include "../parser_macros.h" | |
5 | ||
6 | // the name of the language | |
7 | const char *POSTSCRIPT_LANG = LANG_POSTSCRIPT; | |
8 | ||
9 | // the languages entities | |
10 | const char *postscript_entities[] = { | |
11 | "space", "comment", "string", "any" | |
12 | }; | |
13 | ||
14 | // constants associated with the entities | |
15 | enum { | |
16 | POSTSCRIPT_SPACE = 0, POSTSCRIPT_COMMENT, POSTSCRIPT_STRING, POSTSCRIPT_ANY | |
17 | }; | |
18 | ||
19 | /*****************************************************************************/ | |
20 | ||
21 | %%{ | |
22 | machine postscript; | |
23 | write data; | |
24 | include common "common.rl"; | |
25 | ||
26 | # Line counting | |
27 | ||
28 | action postscript_ccallback { | |
29 | switch(entity) { | |
30 | case POSTSCRIPT_SPACE: | |
31 | ls | |
32 | break; | |
33 | case POSTSCRIPT_ANY: | |
34 | code | |
35 | break; | |
36 | case INTERNAL_NL: | |
37 | std_internal_newline(POSTSCRIPT_LANG) | |
38 | break; | |
39 | case NEWLINE: | |
40 | std_newline(POSTSCRIPT_LANG) | |
41 | } | |
42 | } | |
43 | ||
44 | postscript_comment = '%' @comment nonnewline*; | |
45 | ||
46 | postscript_string = '(' @code ([^\r\n\f])* ')'; | |
47 | ||
48 | postscript_line := |* | |
49 | spaces ${ entity = POSTSCRIPT_SPACE; } => postscript_ccallback; | |
50 | postscript_comment; | |
51 | postscript_string; | |
52 | newline ${ entity = NEWLINE; } => postscript_ccallback; | |
53 | ^space ${ entity = POSTSCRIPT_ANY; } => postscript_ccallback; | |
54 | *|; | |
55 | ||
56 | # Entity Machine | |
57 | ||
58 | action postscript_ecallback { | |
59 | callback(POSTSCRIPT_LANG, postscript_entities[entity], cint(ts), cint(te), | |
60 | userdata); | |
61 | } | |
62 | ||
63 | postscript_comment_entity = '%' nonnewline*; | |
64 | ||
65 | postscript_entity := |* | |
66 | space+ ${ entity = POSTSCRIPT_SPACE; } => postscript_ecallback; | |
67 | postscript_comment_entity ${ entity = POSTSCRIPT_COMMENT; } => postscript_ecallback; | |
68 | # TODO: | |
69 | ^space; | |
70 | *|; | |
71 | }%% | |
72 | ||
73 | /************************* Required for every parser *************************/ | |
74 | ||
75 | /* Parses a string buffer with PostScript 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_postscript(char *buffer, int length, int count, | |
87 | void (*callback) (const char *lang, const char *entity, int s, | |
88 | int e, void *udata), | |
89 | void *userdata | |
90 | ) { | |
91 | init | |
92 | ||
93 | %% write init; | |
94 | cs = (count) ? postscript_en_postscript_line : postscript_en_postscript_entity; | |
95 | %% write exec; | |
96 | ||
97 | // if no newline at EOF; callback contents of last line | |
98 | if (count) { process_last_line(POSTSCRIPT_LANG) } | |
99 | } | |
100 | ||
101 | #endif | |
102 | ||
103 | /*****************************************************************************/ |
0 | // unrealscript.rl derived from code written by Mitchell Foral. mitchell<att>caladbolg<dott>net. | |
1 | ||
2 | /************************* Required for every parser *************************/ | |
3 | #ifndef OHCOUNT_UNREALSCRIPT_PARSER_H | |
4 | #define OHCOUNT_UNREALSCRIPT_PARSER_H | |
5 | ||
6 | #include "../parser_macros.h" | |
7 | ||
8 | // the name of the language | |
9 | const char *UNREALSCRIPT_LANG = LANG_UNREALSCRIPT; | |
10 | ||
11 | // the languages entities | |
12 | const char *unrealscript_entities[] = { | |
13 | "space", "comment", "string", "any" | |
14 | }; | |
15 | ||
16 | // constants associated with the entities | |
17 | enum { | |
18 | UNREALSCRIPT_SPACE = 0, UNREALSCRIPT_COMMENT, UNREALSCRIPT_STRING, UNREALSCRIPT_ANY | |
19 | }; | |
20 | ||
21 | /*****************************************************************************/ | |
22 | ||
23 | %%{ | |
24 | machine unrealscript; | |
25 | write data; | |
26 | include common "common.rl"; | |
27 | ||
28 | # Line counting machine | |
29 | ||
30 | action unrealscript_ccallback { | |
31 | switch(entity) { | |
32 | case UNREALSCRIPT_SPACE: | |
33 | ls | |
34 | break; | |
35 | case UNREALSCRIPT_ANY: | |
36 | code | |
37 | break; | |
38 | case INTERNAL_NL: | |
39 | std_internal_newline(UNREALSCRIPT_LANG) | |
40 | break; | |
41 | case NEWLINE: | |
42 | std_newline(UNREALSCRIPT_LANG) | |
43 | } | |
44 | } | |
45 | ||
46 | unrealscript_line_comment = '//' @comment nonnewline*; | |
47 | unrealscript_block_comment = | |
48 | '/*' @comment ( | |
49 | newline %{ entity = INTERNAL_NL; } %unrealscript_ccallback | |
50 | | | |
51 | ws | |
52 | | | |
53 | (nonnewline - ws) @comment | |
54 | )* :>> '*/'; | |
55 | unrealscript_comment = unrealscript_line_comment | unrealscript_block_comment; | |
56 | ||
57 | unrealscript_sq_str = | |
58 | '\'' @code ( | |
59 | escaped_newline %{ entity = INTERNAL_NL; } %unrealscript_ccallback | |
60 | | | |
61 | ws | |
62 | | | |
63 | [^\t '\\] @code | |
64 | | | |
65 | '\\' nonnewline @code | |
66 | )* '\''; | |
67 | unrealscript_dq_str = | |
68 | '"' @code ( | |
69 | escaped_newline %{ entity = INTERNAL_NL; } %unrealscript_ccallback | |
70 | | | |
71 | ws | |
72 | | | |
73 | [^\t "\\] @code | |
74 | | | |
75 | '\\' nonnewline @code | |
76 | )* '"'; | |
77 | unrealscript_string = unrealscript_sq_str | unrealscript_dq_str; | |
78 | ||
79 | unrealscript_line := |* | |
80 | spaces ${ entity = UNREALSCRIPT_SPACE; } => unrealscript_ccallback; | |
81 | unrealscript_comment; | |
82 | unrealscript_string; | |
83 | newline ${ entity = NEWLINE; } => unrealscript_ccallback; | |
84 | ^space ${ entity = UNREALSCRIPT_ANY; } => unrealscript_ccallback; | |
85 | *|; | |
86 | ||
87 | # Entity machine | |
88 | ||
89 | action unrealscript_ecallback { | |
90 | callback(UNREALSCRIPT_LANG, unrealscript_entities[entity], cint(ts), cint(te), userdata); | |
91 | } | |
92 | ||
93 | unrealscript_line_comment_entity = '//' nonnewline*; | |
94 | unrealscript_block_comment_entity = '/*' any* :>> '*/'; | |
95 | unrealscript_comment_entity = unrealscript_line_comment_entity | unrealscript_block_comment_entity; | |
96 | ||
97 | unrealscript_entity := |* | |
98 | space+ ${ entity = UNREALSCRIPT_SPACE; } => unrealscript_ecallback; | |
99 | unrealscript_comment_entity ${ entity = UNREALSCRIPT_COMMENT; } => unrealscript_ecallback; | |
100 | # TODO: | |
101 | ^space; | |
102 | *|; | |
103 | }%% | |
104 | ||
105 | /************************* Required for every parser *************************/ | |
106 | ||
107 | /* Parses a string buffer with UnrealScript code. | |
108 | * | |
109 | * @param *buffer The string to parse. | |
110 | * @param length The length of the string to parse. | |
111 | * @param count Integer flag specifying whether or not to count lines. If yes, | |
112 | * uses the Ragel machine optimized for counting. Otherwise uses the Ragel | |
113 | * machine optimized for returning entity positions. | |
114 | * @param *callback Callback function. If count is set, callback is called for | |
115 | * every line of code, comment, or blank with 'lcode', 'lcomment', and | |
116 | * 'lblank' respectively. Otherwise callback is called for each entity found. | |
117 | */ | |
118 | void parse_unrealscript(char *buffer, int length, int count, | |
119 | void (*callback) (const char *lang, const char *entity, int s, | |
120 | int e, void *udata), | |
121 | void *userdata | |
122 | ) { | |
123 | init | |
124 | ||
125 | %% write init; | |
126 | cs = (count) ? unrealscript_en_unrealscript_line : unrealscript_en_unrealscript_entity; | |
127 | %% write exec; | |
128 | ||
129 | // if no newline at EOF; callback contents of last line | |
130 | if (count) { process_last_line(UNREALSCRIPT_LANG) } | |
131 | } | |
132 | ||
133 | #endif | |
134 | ||
135 | /*****************************************************************************/ |
0 | class foo extends Actor; | |
1 | ||
2 | /** An UnrealScript 3 styled comment. */ | |
3 | var bool bFoo; | |
4 | ||
5 | simulated function PostBeginPlay() | |
6 | { | |
7 | // Comment | |
8 | log(self@"Hello World! Foo is"@bFoo); // Another comment | |
9 | /* A | |
10 | block | |
11 | comment */ | |
12 | Super.PostBeginPlay(); | |
13 | } | |
14 | ||
15 | defaultproperties | |
16 | { | |
17 | bFoo = true | |
18 | } |
0 | crystal code abstract class Animal | |
1 | crystal code abstract def talk | |
2 | crystal code end | |
3 | crystal code end |
0 | crystal code @[Link(ldflags: "/home/alex/projects/fisbot/lib/ohcount/ohcount.so")] | |
1 | crystal blank | |
2 | crystal code lib OhcountC | |
3 | crystal code fun ohcount_sourcefile_new(filepath : LibC::Char*) : Int32* | |
4 | crystal code end |
0 | livecode comment # Comment | |
1 | livecode comment -- Comment | |
2 | livecode comment // Comment | |
3 | livecode blank | |
4 | livecode comment /* | |
5 | livecode blank | |
6 | livecode comment Block Comment | |
7 | livecode blank | |
8 | livecode comment */ | |
9 | livecode blank | |
10 | livecode code on mouseUp | |
11 | livecode code doSomething | |
12 | livecode code end mouseUp |
0 | forth comment \ Sample Forth code | |
1 | forth blank | |
2 | forth comment ( This is a comment | |
3 | forth comment spanning multiple lines ) | |
4 | forth blank | |
5 | forth code : somedefinition ; | |
6 | forth blank |
0 | kotlin comment // Line comment | |
1 | kotlin code fun sum(a : Double, b : Double) : Double { | |
2 | kotlin code return a + b | |
3 | kotlin code } | |
4 | kotlin blank | |
5 | kotlin comment /* | |
6 | kotlin comment * Block comment | |
7 | kotlin comment */ | |
8 | kotlin blank | |
9 | kotlin code fun hello(place : String) : Unit { | |
10 | kotlin code print("Hello, \"$place\"\n") | |
11 | kotlin code } | |
12 | kotlin blank | |
13 | kotlin comment /* | |
14 | kotlin comment * /* | |
15 | kotlin comment * * Block comments nest | |
16 | kotlin comment * */ | |
17 | kotlin comment */ | |
18 | kotlin blank | |
19 | kotlin code fun main() : Unit { | |
20 | kotlin code hello("""Very, very, very | |
21 | kotlin code // long place | |
22 | kotlin code somewhere""") | |
23 | kotlin code } |
0 | crystal comment # This is a comment. | |
1 | crystal blank | |
2 | crystal code macro create_foo(name, &block) | |
3 | crystal code {% name.id = "bar" %} | |
4 | crystal code {{block}} |
0 | modelica code within fooBar; | |
1 | modelica code package Examples | |
2 | modelica blank | |
3 | modelica code annotation (Icon(graphics={ | |
4 | modelica code Polygon( | |
5 | modelica code points={{-48,50},{52,-10},{-48,-70},{-48,50}}, | |
6 | modelica code lineColor={0,0,255}, | |
7 | modelica code pattern=LinePattern.None, | |
8 | modelica code fillColor={95,95,95}, | |
9 | modelica code fillPattern=FillPattern.Solid)}), Documentation(revisions="<html> | |
10 | modelica code <!--DISCLAIMER--> | |
11 | modelica code <p>Copyright 2015-2016 RTE (France), SmarTS Lab (Sweden), AIA (Spain) and DTU (Denmark)</p> | |
12 | modelica code </html>")); | |
13 | modelica code end Examples; |
0 | postscript comment %!PS | |
1 | postscript comment % Postscript Directive at the top. Just like its supposed to be. | |
2 | postscript code /Courier | |
3 | postscript blank | |
4 | postscript code 15 selectfont | |
5 | postscript code 72 500 moveto | |
6 | postscript blank | |
7 | postscript code (Hello world) show | |
8 | postscript code showpage |
0 | crystal comment #comment | |
1 | crystal comment # comment with "string" | |
2 | crystal blank | |
3 | crystal code class Rest | |
4 | crystal code def one | |
5 | crystal code two do |c| | |
6 | crystal code puts c | |
7 | crystal code end | |
8 | crystal code end | |
9 | crystal blank | |
10 | crystal code def two(&block : Int32 -> _) | |
11 | crystal code three { |x| yield x } # yield is faster than passing blocks. | |
12 | crystal code end | |
13 | crystal blank | |
14 | crystal code def three | |
15 | crystal code yield 3 | |
16 | crystal code end | |
17 | crystal code end | |
18 | crystal blank | |
19 | crystal code Rest.new.one |
0 | unrealscript code class foo extends Actor; | |
1 | unrealscript blank | |
2 | unrealscript comment /** An UnrealScript 3 styled comment. */ | |
3 | unrealscript code var bool bFoo; | |
4 | unrealscript blank | |
5 | unrealscript code simulated function PostBeginPlay() | |
6 | unrealscript code { | |
7 | unrealscript comment // Comment | |
8 | unrealscript code log(self@"Hello World! Foo is"@bFoo); // Another comment | |
9 | unrealscript comment /* A | |
10 | unrealscript comment block | |
11 | unrealscript comment comment */ | |
12 | unrealscript code Super.PostBeginPlay(); | |
13 | unrealscript code } | |
14 | unrealscript blank | |
15 | unrealscript code defaultproperties | |
16 | unrealscript code { | |
17 | unrealscript code bFoo = true | |
18 | unrealscript code } |
0 | @[Link(ldflags: "/home/alex/projects/fisbot/lib/ohcount/ohcount.so")] | |
1 | ||
2 | lib OhcountC | |
3 | fun ohcount_sourcefile_new(filepath : LibC::Char*) : Int32* | |
4 | end |
0 | # Comment | |
1 | -- Comment | |
2 | // Comment | |
3 | ||
4 | /* | |
5 | ||
6 | Block Comment | |
7 | ||
8 | */ | |
9 | ||
10 | on mouseUp | |
11 | doSomething | |
12 | end mouseUp |
0 | // Line comment | |
1 | fun sum(a : Double, b : Double) : Double { | |
2 | return a + b | |
3 | } | |
4 | ||
5 | /* | |
6 | * Block comment | |
7 | */ | |
8 | ||
9 | fun hello(place : String) : Unit { | |
10 | print("Hello, \"$place\"\n") | |
11 | } | |
12 | ||
13 | /* | |
14 | * /* | |
15 | * * Block comments nest | |
16 | * */ | |
17 | */ | |
18 | ||
19 | fun main() : Unit { | |
20 | hello("""Very, very, very | |
21 | // long place | |
22 | somewhere""") | |
23 | } |
0 | within fooBar; | |
1 | package Examples | |
2 | ||
3 | annotation (Icon(graphics={ | |
4 | Polygon( | |
5 | points={{-48,50},{52,-10},{-48,-70},{-48,50}}, | |
6 | lineColor={0,0,255}, | |
7 | pattern=LinePattern.None, | |
8 | fillColor={95,95,95}, | |
9 | fillPattern=FillPattern.Solid)}), Documentation(revisions="<html> | |
10 | <!--DISCLAIMER--> | |
11 | <p>Copyright 2015-2016 RTE (France), SmarTS Lab (Sweden), AIA (Spain) and DTU (Denmark)</p> | |
12 | </html>")); | |
13 | end Examples; |
0 | %!PS | |
1 | % Postscript Directive at the top. Just like its supposed to be. | |
2 | /Courier | |
3 | ||
4 | 15 selectfont | |
5 | 72 500 moveto | |
6 | ||
7 | (Hello world) show | |
8 | showpage |
0 | #comment | |
1 | # comment with "string" | |
2 | ||
3 | class Rest | |
4 | def one | |
5 | two do |c| | |
6 | puts c | |
7 | end | |
8 | end | |
9 | ||
10 | def two(&block : Int32 -> _) | |
11 | three { |x| yield x } # yield is faster than passing blocks. | |
12 | end | |
13 | ||
14 | def three | |
15 | yield 3 | |
16 | end | |
17 | end | |
18 | ||
19 | Rest.new.one |
0 | class foo extends Actor; | |
1 | ||
2 | /** An UnrealScript 3 styled comment. */ | |
3 | var bool bFoo; | |
4 | ||
5 | simulated function PostBeginPlay() | |
6 | { | |
7 | // Comment | |
8 | log(self@"Hello World! Foo is"@bFoo); // Another comment | |
9 | /* A | |
10 | block | |
11 | comment */ | |
12 | Super.PostBeginPlay(); | |
13 | } | |
14 | ||
15 | defaultproperties | |
16 | { | |
17 | bFoo = true | |
18 | } |
124 | 124 | ASSERT_DETECT(LANG_CPP, "uses_cpp_stdlib_headers.h"); |
125 | 125 | ASSERT_DETECT(LANG_CPP, "uses_cpp_keywords.h"); |
126 | 126 | ASSERT_DETECT(LANG_RUBY, "foo.rb"); |
127 | ASSERT_DETECT(LANG_CRYSTAL, "foo.cr"); | |
127 | 128 | ASSERT_DETECT(LANG_MAKE, "foo.mk"); |
128 | 129 | ASSERT_DETECT(LANG_MATHEMATICA, "foo.mt"); |
129 | 130 | ASSERT_DETECT(LANG_MATHEMATICA, "foo.wl"); |
130 | 131 | ASSERT_DETECT(LANG_MATHEMATICA, "foo.wlt"); |
132 | ASSERT_DETECT(LANG_MODELICA, "foo.mo"); | |
131 | 133 | ASSERT_DETECT(LANG_OBJECTIVE_C, "foo_objective_c.h"); |
132 | 134 | ASSERT_DETECT(LANG_PHP, "upper_case_php"); |
133 | 135 | ASSERT_DETECT(LANG_SMALLTALK, "example.st"); |
162 | 164 | ASSERT_DETECT(LANG_FSHARP, "fs1.fs"); |
163 | 165 | ASSERT_DETECT(LANG_GRACE, "grace1.grace"); |
164 | 166 | ASSERT_DETECT(LANG_GRACE, "grace2.grc"); |
167 | ASSERT_DETECT(LANG_FORTH, "forth.fs"); | |
165 | 168 | ASSERT_DETECT(LANG_AUTOCONF, "m4.m4"); |
166 | 169 | ASSERT_DETECT(LANG_NSIS, "foo.nsi"); |
167 | 170 | ASSERT_DETECT(LANG_NSIS, "foo.nsh"); |
168 | 171 | ASSERT_DETECT(LANG_COFFEESCRIPT, "foo.coffee"); |
169 | 172 | ASSERT_DETECT(LANG_QML, "foo.qml"); |
170 | 173 | ASSERT_DETECT(LANG_COQ, "coq.v"); |
174 | ASSERT_DETECT(LANG_UNREALSCRIPT, "foo.uc"); | |
171 | 175 | ASSERT_DETECT(LANG_AMPL, "foo.run"); |
176 | ASSERT_DETECT(LANG_LIVECODE, "foo.lc"); | |
177 | ASSERT_DETECT(LANG_LIVECODE, "script.utf8"); | |
178 | ASSERT_DETECT(LANG_POSTSCRIPT, "foo.ps"); | |
172 | 179 | ASSERT_NODETECT("empty.inc"); |
173 | 180 | } |
174 | 181 | |
242 | 249 | } |
243 | 250 | |
244 | 251 | void test_non_existent_file(){ |
245 | ASSERT_NODETECT("xxx_non_exists_xxxi.pp"); | |
252 | ASSERT_NODETECT("xxx_non_exists_xxxi.pp"); | |
246 | 253 | } |
247 | 254 | |
248 | 255 | void all_detector_tests() { |
92 | 92 | #include "parsers/test_clearsilver.h" |
93 | 93 | #include "parsers/test_clojure.h" |
94 | 94 | #include "parsers/test_coq.h" |
95 | #include "parsers/test_crystal.h" | |
95 | 96 | #include "parsers/test_cs_aspx.h" |
96 | 97 | #include "parsers/test_csharp.h" |
97 | 98 | #include "parsers/test_css.h" |
120 | 121 | #include "parsers/test_javascript.h" |
121 | 122 | #include "parsers/test_jsp.h" |
122 | 123 | #include "parsers/test_lisp.h" |
124 | #include "parsers/test_livecode.h" | |
123 | 125 | #include "parsers/test_logtalk.h" |
124 | 126 | #include "parsers/test_lua.h" |
125 | 127 | #include "parsers/test_make.h" |
136 | 138 | #include "parsers/test_pascal.h" |
137 | 139 | #include "parsers/test_perl.h" |
138 | 140 | #include "parsers/test_pike.h" |
141 | #include "parsers/test_postscript.h" | |
139 | 142 | #include "parsers/test_puppet.h" |
140 | 143 | #include "parsers/test_python.h" |
141 | 144 | #include "parsers/test_qml.h" |
154 | 157 | #include "parsers/test_stratego.h" |
155 | 158 | #include "parsers/test_tcl.h" |
156 | 159 | #include "parsers/test_tex.h" |
160 | #include "parsers/test_unrealscript.h" | |
157 | 161 | #include "parsers/test_typescript.h" |
158 | 162 | #include "parsers/test_vala.h" |
159 | 163 | #include "parsers/test_vb_aspx.h" |
279 | 283 | all_clearsilver_tests(); |
280 | 284 | all_clojure_tests(); |
281 | 285 | all_coq_tests(); |
286 | all_crystal_tests(); | |
282 | 287 | all_cs_aspx_tests(); |
283 | 288 | all_csharp_tests(); |
284 | 289 | all_css_tests(); |
306 | 311 | all_javascript_tests(); |
307 | 312 | all_jsp_tests(); |
308 | 313 | all_lisp_tests(); |
314 | all_livecode_tests(); | |
309 | 315 | all_logtalk_tests(); |
310 | 316 | all_lua_tests(); |
311 | 317 | all_make_tests(); |
322 | 328 | all_pascal_tests(); |
323 | 329 | all_perl_tests(); |
324 | 330 | all_pike_tests(); |
331 | all_postscript_tests(); | |
325 | 332 | all_python_tests(); |
326 | 333 | all_r_tests(); |
327 | 334 | all_racket_tests(); |
338 | 345 | all_stratego_tests(); |
339 | 346 | all_tcl_tests(); |
340 | 347 | all_tex_tests(); |
348 | all_unrealscript_tests(); | |
341 | 349 | all_vala_tests(); |
342 | 350 | all_vb_aspx_tests(); |
343 | 351 | all_vhdl_tests(); |
0 | ||
1 | void test_crystal_comments() { | |
2 | test_parser_verify_parse( | |
3 | test_parser_sourcefile("crystal", " #comment"), | |
4 | "crystal", "", "#comment", 0 | |
5 | ); | |
6 | } | |
7 | ||
8 | void test_crystal_comment_entities() { | |
9 | test_parser_verify_entity( | |
10 | test_parser_sourcefile("crystal", " #comment"), | |
11 | "comment", "#comment" | |
12 | ); | |
13 | test_parser_verify_entity( | |
14 | test_parser_sourcefile("crystal", "=begin\ncomment\n=end"), | |
15 | "comment", "=begin\ncomment\n=end" | |
16 | ); | |
17 | } | |
18 | ||
19 | void all_crystal_tests() { | |
20 | test_crystal_comments(); | |
21 | test_crystal_comment_entities(); | |
22 | } |
0 | ||
1 | void test_livecode_comments() { | |
2 | test_parser_verify_parse( | |
3 | test_parser_sourcefile("livecode", " --comment"), | |
4 | "livecode", "", "--comment", 0 | |
5 | ); | |
6 | } | |
7 | ||
8 | void test_livecode_empty_comments() { | |
9 | test_parser_verify_parse( | |
10 | test_parser_sourcefile("livecode", " --\n"), | |
11 | "livecode", "", "--\n", 0 | |
12 | ); | |
13 | } | |
14 | ||
15 | void test_livecode_block_comment() { | |
16 | test_parser_verify_parse( | |
17 | test_parser_sourcefile("livecode", " /*livecode*/"), | |
18 | "livecode", "", "/*livecode*/", 0 | |
19 | ); | |
20 | } | |
21 | ||
22 | void test_livecode_comment_entities() { | |
23 | test_parser_verify_entity( | |
24 | test_parser_sourcefile("livecode", " --comment"), | |
25 | "comment", "--comment" | |
26 | ); | |
27 | test_parser_verify_entity( | |
28 | test_parser_sourcefile("livecode", " #comment"), | |
29 | "comment", "#comment" | |
30 | ); | |
31 | test_parser_verify_entity( | |
32 | test_parser_sourcefile("livecode", " //comment"), | |
33 | "comment", "//comment" | |
34 | ); | |
35 | test_parser_verify_entity( | |
36 | test_parser_sourcefile("livecode", " /*comment*/"), | |
37 | "comment", "/*comment*/" | |
38 | ); | |
39 | } | |
40 | ||
41 | void all_livecode_tests() { | |
42 | test_livecode_comments(); | |
43 | test_livecode_empty_comments(); | |
44 | test_livecode_block_comment(); | |
45 | test_livecode_comment_entities(); | |
46 | } |
0 | ||
1 | void test_postscript_comment_entities(){ | |
2 | test_parser_verify_entity( | |
3 | test_parser_sourcefile("postscript", "%comment"), | |
4 | "comment", "%comment" | |
5 | ); | |
6 | } | |
7 | ||
8 | void all_postscript_tests(){ | |
9 | test_postscript_comment_entities(); | |
10 | } |
0 | ||
1 | void test_unrealscript_comments() { | |
2 | test_parser_verify_parse( | |
3 | test_parser_sourcefile("unrealscript", " //comment"), | |
4 | "unrealscript", "", "//comment", 0 | |
5 | ); | |
6 | } | |
7 | ||
8 | void test_unrealscript_comment_entities() { | |
9 | test_parser_verify_entity( | |
10 | test_parser_sourcefile("unrealscript", " //comment"), | |
11 | "comment", "//comment" | |
12 | ); | |
13 | test_parser_verify_entity( | |
14 | test_parser_sourcefile("unrealscript", " /*comment*/"), | |
15 | "comment", "/*comment*/" | |
16 | ); | |
17 | } | |
18 | ||
19 | void all_unrealscript_tests() { | |
20 | test_unrealscript_comments(); | |
21 | test_unrealscript_comment_entities(); | |
22 | } |