PageRenderTime 63ms CodeModel.GetById 30ms RepoModel.GetById 0ms app.codeStats 0ms

/libparser/reserved.pl

https://github.com/motok5/gtags
Perl | 259 lines | 191 code | 8 blank | 60 comment | 32 complexity | a42a344320f6912a8f591448a8e41781 MD5 | raw file
  1. #!/usr/bin/perl
  2. #
  3. # Copyright (c) 2003, 2004 Tama Communications Corporation
  4. #
  5. # This file is part of GNU GLOBAL.
  6. #
  7. # This program is free software: you can redistribute it and/or modify
  8. # it under the terms of the GNU General Public License as published by
  9. # the Free Software Foundation, either version 3 of the License, or
  10. # (at your option) any later version.
  11. #
  12. # This program is distributed in the hope that it will be useful,
  13. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. # GNU General Public License for more details.
  16. #
  17. # You should have received a copy of the GNU General Public License
  18. # along with this program. If not, see <http://www.gnu.org/licenses/>.
  19. #
  20. # This command does one of the followings:
  21. #
  22. # [1] Generate option string for gperf(1).
  23. # [2] Generate regular expression which means reserved words for htags(1).
  24. # [3] Generate gperf(1) source from keyword file.
  25. #
  26. # Both output is stdout.
  27. #
  28. $com = $0;
  29. $com =~ s/.*\///;
  30. #
  31. # Allocation of ID
  32. #
  33. # 1001 - 2000: Reserved variable (PHP)
  34. # 2001 -; Reserved word (wide sense)
  35. # 2001 - 3000: reserved word
  36. # 3001 - 4000: # macro
  37. # 4001 - 5000: yacc word
  38. #
  39. $START_VARIABLE = 1001;
  40. $START_WORD = 2001;
  41. $START_SHARP = 3001;
  42. $START_YACC = 4001;
  43. sub usage {
  44. print STDERR "usage: $com --prefix=prefix --option\n";
  45. print STDERR " $com --prefix=prefix --perl keyword_file\n";
  46. print STDERR " $com --prefix=prefix keyword_file\n";
  47. exit(1);
  48. }
  49. $slot_name = 'name';
  50. $option = 0;
  51. $perl = 0;
  52. $prefix = '';
  53. $keyword_file = '';
  54. while ($ARGV[0] =~ /^-/) {
  55. $opt = shift;
  56. if ($opt =~ /^--prefix=(.*)$/) {
  57. $prefix = $1;
  58. } elsif ($opt =~ /^--option$/) {
  59. $option = 1;
  60. } elsif ($opt =~ /^--perl$/) {
  61. $perl = 1;
  62. } else {
  63. usage();
  64. }
  65. }
  66. $keyword_file = $ARGV[0];
  67. if (!$prefix) {
  68. usage();
  69. }
  70. #
  71. # [1] Generate option string for gperf(1).
  72. #
  73. if ($option) {
  74. print "--language=ANSI-C\n";
  75. print "--struct-type\n";
  76. print "--slot-name=${slot_name}\n";
  77. print "--hash-fn-name=${prefix}_hash\n";
  78. print "--lookup-fn-name=${prefix}_lookup\n";
  79. exit(0);
  80. }
  81. if (!$keyword_file) {
  82. usage();
  83. }
  84. #
  85. # [2] Generate regular expression which means reserved words for htags(1).
  86. #
  87. if ($perl) {
  88. local(@array);
  89. open(IP, $keyword_file) || die("$com: cannot open file '$keyword_file'.\n");
  90. while(<IP>) {
  91. chop;
  92. next if (/^$/ || /^;/);
  93. ($id, $type) = split;
  94. if ($prefix eq 'sharp') {
  95. if ($type eq 'sharp' && $id ne '##') {
  96. $id =~ s/#//g;
  97. push(@array, $id);
  98. }
  99. } else {
  100. if ($type eq 'word') {
  101. @id = split(/,/, $id);
  102. for ($i = 0; $i < @id; $i++) {
  103. push(@array, $id[$i]);
  104. }
  105. }
  106. }
  107. }
  108. close(IP);
  109. #
  110. # Sort by the length to match pattern to a longer name.
  111. #
  112. sub compare { length($b) <=> length($a); }
  113. @array = sort compare @array;
  114. print "# This part is generated automatically by $com from '$keyword_file'.\n";
  115. if ($prefix eq 'sharp') {
  116. print "\$'sharp_macros = \"(";
  117. } else {
  118. print "\$'${prefix}_reserved_words = \"(";
  119. }
  120. print join('|', @array);
  121. print ")\";\n";
  122. print "# end of generated part.\n";
  123. close(IP);
  124. exit(0);
  125. }
  126. #
  127. # [3] Generate gperf(1) source from keyword file.
  128. #
  129. $PRE = $pre = $prefix;
  130. $PRE =~ tr/a-z/A-Z/;
  131. $pre =~ tr/A-Z/a-z/;
  132. local(%yacctab) = ('%%', 'SEP', '%{', 'BEGIN', '%}', 'END');
  133. #
  134. # Macro definitions.
  135. #
  136. $n_variable = $START_VARIABLE;
  137. $n_word = $START_WORD;
  138. $n_sharp = $START_SHARP;
  139. $n_yacc = $START_YACC;
  140. open(IP, $keyword_file) || die("$com: cannot open file '$keyword_file'.\n");
  141. print "%{\n";
  142. print "#include \"strmake.h\"\n";
  143. print "#define START_VARIABLE\t$n_variable\n";
  144. print "#define START_WORD\t$n_word\n";
  145. print "#define START_SHARP\t$n_sharp\n";
  146. print "#define START_YACC\t$n_yacc\n";
  147. print "#define IS_RESERVED_WORD(a) ((a) >= START_WORD)\n";
  148. print "#define IS_RESERVED_VARIABLE(a) ((a) >= START_VARIABLE && (a) < START_WORD)\n";
  149. print "#define IS_RESERVED_SHARP(a) ((a) >= START_SHARP && (a) < START_YACC)\n";
  150. print "#define IS_RESERVED_YACC(a) ((a) >= START_YACC)\n";
  151. print "\n";
  152. while(<IP>) {
  153. chop;
  154. next if (/^$/ || /^;/);
  155. ($id, $type) = split;
  156. @id = split(/,/, $id);
  157. $upper = $id[0];
  158. $upper =~ tr/a-z/A-Z/;
  159. if ($type eq 'word') {
  160. $upper =~ s/::/WCOLON/;
  161. print "#define ${PRE}_${upper}\t${n_word}\n";
  162. $n_word++;
  163. } elsif ($type eq 'variable') {
  164. print "#define ${PRE}_${upper}\t${n_variable}\n";
  165. $n_variable++;
  166. } elsif ($type eq 'sharp') {
  167. $upper =~ s/##/SHARP/;
  168. $upper =~ s/#//g;
  169. print "#define SHARP_${upper}\t${n_sharp}\n";
  170. $n_sharp++;
  171. } elsif ($type eq 'yacc') {
  172. $upper =~ s/(%%|%{|%})/$yacctab{$1}/ge;
  173. $upper =~ s/%//g;
  174. $upper =~ s/-/_/g;
  175. print "#define YACC_${upper}\t${n_yacc}\n";
  176. $n_yacc++;
  177. }
  178. }
  179. close(IP);
  180. print "%}\n";
  181. #
  182. # Structure definition.
  183. #
  184. print "struct keyword { char *${slot_name}; int token; }\n";
  185. print "%%\n";
  186. #
  187. # Keyword definitions.
  188. #
  189. open(IP, $keyword_file) || die("$com: cannot open file '$keyword_file'.\n");
  190. while(<IP>) {
  191. chop;
  192. next if (/^$/ || /^;/);
  193. ($id, $type) = split;
  194. @id = split(/,/, $id);
  195. $upper = $id[0];
  196. $upper =~ tr/a-z/A-Z/;
  197. for ($i = 0; $i < @id; $i++) {
  198. $name = $id[$i];
  199. if ($type eq 'word') {
  200. $upper =~ s/::/WCOLON/;
  201. print "$name, ${PRE}_${upper}\n";
  202. } elsif ($type eq 'variable') {
  203. print "\"${name}\", ${PRE}_${upper}\n";
  204. } elsif ($type eq 'sharp') {
  205. $upper =~ s/##/SHARP/;
  206. $upper =~ s/#//g;
  207. print "\"${name}\", SHARP_${upper}\n";
  208. } elsif ($type eq 'yacc') {
  209. $upper =~ s/(%%|%{|%})/$yacctab{$1}/ge;
  210. $upper =~ s/%//g;
  211. $upper =~ s/-/_/g;
  212. print "\"${name}\", YACC_${upper}\n";
  213. }
  214. }
  215. }
  216. close(IP);
  217. print "%%\n";
  218. #
  219. # Generate reserved_xxxx() procedures.
  220. #
  221. sub generate_procedure {
  222. local($type) = @_;
  223. local($TYPE) = $type;
  224. $TYPE =~ tr/a-z/A-Z/;
  225. print "int\n";
  226. print "${prefix}_reserved_${type}(const char *str, int len)\n";
  227. print "{\n";
  228. print "\tstruct keyword *keyword;\n";
  229. print "\n";
  230. if ($type eq 'sharp') {
  231. print "\t/* Delete blanks. Ex. ' # define ' => '#define' */\n";
  232. print "\tstr = strtrim(str, TRIM_ALL, &len);\n";
  233. print "\n";
  234. }
  235. print "\tkeyword = ${pre}_lookup(str, len);\n";
  236. print "\treturn (keyword && IS_RESERVED_${TYPE}(keyword->token)) ? keyword->token : 0;\n";
  237. print "}\n";
  238. }
  239. if ($n_word > $START_WORD) {
  240. generate_procedure('word');
  241. }
  242. if ($n_variable > $START_VARIABLE) {
  243. generate_procedure('variable');
  244. }
  245. if ($n_sharp > $START_SHARP) {
  246. generate_procedure('sharp');
  247. }
  248. if ($n_yacc > $START_YACC) {
  249. generate_procedure('yacc');
  250. }
  251. exit 0;