haml-more 0.4.0.a

Sign up to get free protection for your applications and to get access to all the features.
Files changed (225) hide show
  1. data/README.md +79 -0
  2. data/lib/haml/more/coffee_script.rb +137 -0
  3. data/lib/haml/more/content_for.rb +25 -0
  4. data/lib/haml/more.rb +45 -0
  5. data/lib/haml-more.rb +1 -0
  6. data/lib/sass/more.rb +16 -0
  7. data/lib/sass-more.rb +1 -0
  8. data/spec/sass/more_spec.rb +21 -0
  9. data/vendor/coffee-script/Cakefile +57 -0
  10. data/vendor/coffee-script/LICENSE +22 -0
  11. data/vendor/coffee-script/README +41 -0
  12. data/vendor/coffee-script/Rakefile +20 -0
  13. data/vendor/coffee-script/bin/cake +7 -0
  14. data/vendor/coffee-script/bin/coffee +7 -0
  15. data/vendor/coffee-script/documentation/coffee/aliases.coffee +9 -0
  16. data/vendor/coffee-script/documentation/coffee/arguments.coffee +4 -0
  17. data/vendor/coffee-script/documentation/coffee/array_comprehensions.coffee +7 -0
  18. data/vendor/coffee-script/documentation/coffee/assignment.coffee +2 -0
  19. data/vendor/coffee-script/documentation/coffee/cake_tasks.coffee +5 -0
  20. data/vendor/coffee-script/documentation/coffee/comparisons.coffee +5 -0
  21. data/vendor/coffee-script/documentation/coffee/conditionals.coffee +9 -0
  22. data/vendor/coffee-script/documentation/coffee/embedded.coffee +5 -0
  23. data/vendor/coffee-script/documentation/coffee/existence.coffee +8 -0
  24. data/vendor/coffee-script/documentation/coffee/expressions.coffee +9 -0
  25. data/vendor/coffee-script/documentation/coffee/expressions_assignment.coffee +1 -0
  26. data/vendor/coffee-script/documentation/coffee/expressions_comprehension.coffee +3 -0
  27. data/vendor/coffee-script/documentation/coffee/expressions_try.coffee +6 -0
  28. data/vendor/coffee-script/documentation/coffee/fat_arrow.coffee +6 -0
  29. data/vendor/coffee-script/documentation/coffee/functions.coffee +2 -0
  30. data/vendor/coffee-script/documentation/coffee/heredocs.coffee +5 -0
  31. data/vendor/coffee-script/documentation/coffee/multiple_return_values.coffee +5 -0
  32. data/vendor/coffee-script/documentation/coffee/object_comprehensions.coffee +4 -0
  33. data/vendor/coffee-script/documentation/coffee/object_extraction.coffee +13 -0
  34. data/vendor/coffee-script/documentation/coffee/objects_and_arrays.coffee +13 -0
  35. data/vendor/coffee-script/documentation/coffee/overview.coffee +29 -0
  36. data/vendor/coffee-script/documentation/coffee/parallel_assignment.coffee +4 -0
  37. data/vendor/coffee-script/documentation/coffee/range_comprehensions.coffee +6 -0
  38. data/vendor/coffee-script/documentation/coffee/scope.coffee +5 -0
  39. data/vendor/coffee-script/documentation/coffee/slices.coffee +6 -0
  40. data/vendor/coffee-script/documentation/coffee/soaks.coffee +1 -0
  41. data/vendor/coffee-script/documentation/coffee/splats.coffee +25 -0
  42. data/vendor/coffee-script/documentation/coffee/splices.coffee +5 -0
  43. data/vendor/coffee-script/documentation/coffee/strings.coffee +8 -0
  44. data/vendor/coffee-script/documentation/coffee/super.coffee +34 -0
  45. data/vendor/coffee-script/documentation/coffee/switch.coffee +10 -0
  46. data/vendor/coffee-script/documentation/coffee/try.coffee +7 -0
  47. data/vendor/coffee-script/documentation/coffee/while.coffee +10 -0
  48. data/vendor/coffee-script/documentation/css/docs.css +213 -0
  49. data/vendor/coffee-script/documentation/css/idle.css +63 -0
  50. data/vendor/coffee-script/documentation/css/logo.png +0 -0
  51. data/vendor/coffee-script/documentation/index.html.erb +967 -0
  52. data/vendor/coffee-script/documentation/js/aliases.js +14 -0
  53. data/vendor/coffee-script/documentation/js/arguments.js +8 -0
  54. data/vendor/coffee-script/documentation/js/array_comprehensions.js +26 -0
  55. data/vendor/coffee-script/documentation/js/assignment.js +5 -0
  56. data/vendor/coffee-script/documentation/js/cake_tasks.js +14 -0
  57. data/vendor/coffee-script/documentation/js/comparisons.js +5 -0
  58. data/vendor/coffee-script/documentation/js/conditionals.js +12 -0
  59. data/vendor/coffee-script/documentation/js/embedded.js +6 -0
  60. data/vendor/coffee-script/documentation/js/existence.js +7 -0
  61. data/vendor/coffee-script/documentation/js/expressions.js +13 -0
  62. data/vendor/coffee-script/documentation/js/expressions_assignment.js +4 -0
  63. data/vendor/coffee-script/documentation/js/expressions_comprehension.js +12 -0
  64. data/vendor/coffee-script/documentation/js/expressions_try.js +9 -0
  65. data/vendor/coffee-script/documentation/js/fat_arrow.js +15 -0
  66. data/vendor/coffee-script/documentation/js/functions.js +9 -0
  67. data/vendor/coffee-script/documentation/js/heredocs.js +4 -0
  68. data/vendor/coffee-script/documentation/js/intro.js +7 -0
  69. data/vendor/coffee-script/documentation/js/multiple_return_values.js +11 -0
  70. data/vendor/coffee-script/documentation/js/object_comprehensions.js +17 -0
  71. data/vendor/coffee-script/documentation/js/object_extraction.js +17 -0
  72. data/vendor/coffee-script/documentation/js/objects_and_arrays.js +10 -0
  73. data/vendor/coffee-script/documentation/js/overview.js +43 -0
  74. data/vendor/coffee-script/documentation/js/parallel_assignment.js +8 -0
  75. data/vendor/coffee-script/documentation/js/punctuation.js +8 -0
  76. data/vendor/coffee-script/documentation/js/range_comprehensions.js +21 -0
  77. data/vendor/coffee-script/documentation/js/scope.js +10 -0
  78. data/vendor/coffee-script/documentation/js/slices.js +6 -0
  79. data/vendor/coffee-script/documentation/js/soaks.js +4 -0
  80. data/vendor/coffee-script/documentation/js/splats.js +16 -0
  81. data/vendor/coffee-script/documentation/js/splices.js +5 -0
  82. data/vendor/coffee-script/documentation/js/strings.js +9 -0
  83. data/vendor/coffee-script/documentation/js/super.js +37 -0
  84. data/vendor/coffee-script/documentation/js/switch.js +18 -0
  85. data/vendor/coffee-script/documentation/js/try.js +10 -0
  86. data/vendor/coffee-script/documentation/js/while.js +22 -0
  87. data/vendor/coffee-script/documentation/underscore.html +627 -0
  88. data/vendor/coffee-script/examples/beautiful_code/binary_search.coffee +16 -0
  89. data/vendor/coffee-script/examples/beautiful_code/quicksort_runtime.coffee +13 -0
  90. data/vendor/coffee-script/examples/beautiful_code/regular_expression_matcher.coffee +34 -0
  91. data/vendor/coffee-script/examples/blocks.coffee +57 -0
  92. data/vendor/coffee-script/examples/code.coffee +173 -0
  93. data/vendor/coffee-script/examples/computer_science/README +4 -0
  94. data/vendor/coffee-script/examples/computer_science/binary_search.coffee +25 -0
  95. data/vendor/coffee-script/examples/computer_science/bubble_sort.coffee +11 -0
  96. data/vendor/coffee-script/examples/computer_science/linked_list.coffee +106 -0
  97. data/vendor/coffee-script/examples/computer_science/luhn_algorithm.coffee +36 -0
  98. data/vendor/coffee-script/examples/computer_science/merge_sort.coffee +19 -0
  99. data/vendor/coffee-script/examples/computer_science/selection_sort.coffee +23 -0
  100. data/vendor/coffee-script/examples/poignant.coffee +186 -0
  101. data/vendor/coffee-script/examples/potion.coffee +205 -0
  102. data/vendor/coffee-script/examples/underscore.coffee +603 -0
  103. data/vendor/coffee-script/examples/web_server.coffee +12 -0
  104. data/vendor/coffee-script/extras/CoffeeScript.tmbundle/Preferences/CoffeeScript.tmPreferences +24 -0
  105. data/vendor/coffee-script/extras/CoffeeScript.tmbundle/Syntaxes/CoffeeScript.tmLanguage +361 -0
  106. data/vendor/coffee-script/extras/CoffeeScript.tmbundle/info.plist +10 -0
  107. data/vendor/coffee-script/extras/EXTRAS +20 -0
  108. data/vendor/coffee-script/extras/coffee.vim +117 -0
  109. data/vendor/coffee-script/index.html +1847 -0
  110. data/vendor/coffee-script/lib/bin/cake +7 -0
  111. data/vendor/coffee-script/lib/bin/coffee +7 -0
  112. data/vendor/coffee-script/lib/cake.js +80 -0
  113. data/vendor/coffee-script/lib/coffee-script.js +61 -0
  114. data/vendor/coffee-script/lib/command_line.js +201 -0
  115. data/vendor/coffee-script/lib/grammar.js +564 -0
  116. data/vendor/coffee-script/lib/lexer.js +405 -0
  117. data/vendor/coffee-script/lib/narwhal.js +44 -0
  118. data/vendor/coffee-script/lib/nodes.js +1328 -0
  119. data/vendor/coffee-script/lib/optparse.js +117 -0
  120. data/vendor/coffee-script/lib/parser.js +536 -0
  121. data/vendor/coffee-script/lib/repl.js +32 -0
  122. data/vendor/coffee-script/lib/rewriter.js +383 -0
  123. data/vendor/coffee-script/lib/scope.js +114 -0
  124. data/vendor/coffee-script/package.json +7 -0
  125. data/vendor/coffee-script/src/cake.coffee +45 -0
  126. data/vendor/coffee-script/src/coffee-script.coffee +45 -0
  127. data/vendor/coffee-script/src/command_line.coffee +130 -0
  128. data/vendor/coffee-script/src/grammar.coffee +456 -0
  129. data/vendor/coffee-script/src/lexer.coffee +327 -0
  130. data/vendor/coffee-script/src/narwhal.coffee +42 -0
  131. data/vendor/coffee-script/src/nodes.coffee +1045 -0
  132. data/vendor/coffee-script/src/optparse.coffee +79 -0
  133. data/vendor/coffee-script/src/repl.coffee +23 -0
  134. data/vendor/coffee-script/src/rewriter.coffee +253 -0
  135. data/vendor/coffee-script/src/scope.coffee +75 -0
  136. data/vendor/coffee-script/test/test_arguments.coffee +34 -0
  137. data/vendor/coffee-script/test/test_array_comprehension.coffee +42 -0
  138. data/vendor/coffee-script/test/test_assignment.coffee +26 -0
  139. data/vendor/coffee-script/test/test_blocks.coffee +4 -0
  140. data/vendor/coffee-script/test/test_calling_super.coffee +42 -0
  141. data/vendor/coffee-script/test/test_chained_calls.coffee +25 -0
  142. data/vendor/coffee-script/test/test_destructuring_assignment.coffee +62 -0
  143. data/vendor/coffee-script/test/test_everything.coffee +29 -0
  144. data/vendor/coffee-script/test/test_exceptions.coffee +2 -0
  145. data/vendor/coffee-script/test/test_existence.coffee +81 -0
  146. data/vendor/coffee-script/test/test_expressions.coffee +30 -0
  147. data/vendor/coffee-script/test/test_fancy_if_statement.coffee +26 -0
  148. data/vendor/coffee-script/test/test_functions.coffee +80 -0
  149. data/vendor/coffee-script/test/test_funky_comments.coffee +25 -0
  150. data/vendor/coffee-script/test/test_heredocs.coffee +46 -0
  151. data/vendor/coffee-script/test/test_lexical_scope.coffee +10 -0
  152. data/vendor/coffee-script/test/test_literals.coffee +56 -0
  153. data/vendor/coffee-script/test/test_nested_comprehensions.coffee +11 -0
  154. data/vendor/coffee-script/test/test_newline_escaping.coffee +6 -0
  155. data/vendor/coffee-script/test/test_operations.coffee +18 -0
  156. data/vendor/coffee-script/test/test_range_comprehension.coffee +20 -0
  157. data/vendor/coffee-script/test/test_ranges_and_slices.coffee +16 -0
  158. data/vendor/coffee-script/test/test_splats.coffee +47 -0
  159. data/vendor/coffee-script/test/test_splices.coffee +5 -0
  160. data/vendor/coffee-script/test/test_switch.coffee +64 -0
  161. data/vendor/coffee-script/test/test_while.coffee +30 -0
  162. data/vendor/coffee-script/vendor/jison/Jakefile +31 -0
  163. data/vendor/coffee-script/vendor/jison/README.md +347 -0
  164. data/vendor/coffee-script/vendor/jison/bin/jison +3 -0
  165. data/vendor/coffee-script/vendor/jison/bin/json2jison +3 -0
  166. data/vendor/coffee-script/vendor/jison/examples/ansic.jison +415 -0
  167. data/vendor/coffee-script/vendor/jison/examples/basic.json +8 -0
  168. data/vendor/coffee-script/vendor/jison/examples/basic2.json +9 -0
  169. data/vendor/coffee-script/vendor/jison/examples/basic2_lex.json +16 -0
  170. data/vendor/coffee-script/vendor/jison/examples/basic_lex.json +15 -0
  171. data/vendor/coffee-script/vendor/jison/examples/calculator.jison +38 -0
  172. data/vendor/coffee-script/vendor/jison/examples/calculator.jisonlex +14 -0
  173. data/vendor/coffee-script/vendor/jison/examples/calculator.json +42 -0
  174. data/vendor/coffee-script/vendor/jison/examples/classy.json +105 -0
  175. data/vendor/coffee-script/vendor/jison/examples/classy_ast.json +126 -0
  176. data/vendor/coffee-script/vendor/jison/examples/dism.json +25 -0
  177. data/vendor/coffee-script/vendor/jison/examples/dism_lr0.json +26 -0
  178. data/vendor/coffee-script/vendor/jison/examples/json.js +80 -0
  179. data/vendor/coffee-script/vendor/jison/examples/json_ast.js +83 -0
  180. data/vendor/coffee-script/vendor/jison/examples/precedence.json +26 -0
  181. data/vendor/coffee-script/vendor/jison/examples/reduce_conflict.json +13 -0
  182. data/vendor/coffee-script/vendor/jison/lib/jison/bnf.js +43 -0
  183. data/vendor/coffee-script/vendor/jison/lib/jison/jisonlex.js +18 -0
  184. data/vendor/coffee-script/vendor/jison/lib/jison/json2jison.js +146 -0
  185. data/vendor/coffee-script/vendor/jison/lib/jison/lexer.js +224 -0
  186. data/vendor/coffee-script/vendor/jison/lib/jison/util/bnf-parser.js +383 -0
  187. data/vendor/coffee-script/vendor/jison/lib/jison/util/lex-parser.js +407 -0
  188. data/vendor/coffee-script/vendor/jison/lib/jison/util/set.js +94 -0
  189. data/vendor/coffee-script/vendor/jison/lib/jison/util/typal.js +90 -0
  190. data/vendor/coffee-script/vendor/jison/lib/jison.js +1414 -0
  191. data/vendor/coffee-script/vendor/jison/package.json +14 -0
  192. data/vendor/coffee-script/vendor/jison/src/bnf.jison +110 -0
  193. data/vendor/coffee-script/vendor/jison/src/bnf.jisonlex +25 -0
  194. data/vendor/coffee-script/vendor/jison/src/bnf.lex.json +24 -0
  195. data/vendor/coffee-script/vendor/jison/src/jisonlex.jison +129 -0
  196. data/vendor/coffee-script/vendor/jison/src/jisonlex.jisonlex +31 -0
  197. data/vendor/coffee-script/vendor/jison/src/jisonlex.lex.json +30 -0
  198. data/vendor/coffee-script/vendor/jison/tests/all-tests.js +8 -0
  199. data/vendor/coffee-script/vendor/jison/tests/grammar/bnf.js +91 -0
  200. data/vendor/coffee-script/vendor/jison/tests/grammar/bnf_parse.js +65 -0
  201. data/vendor/coffee-script/vendor/jison/tests/grammar/grammar-tests.js +10 -0
  202. data/vendor/coffee-script/vendor/jison/tests/grammar/json2jison.js +24 -0
  203. data/vendor/coffee-script/vendor/jison/tests/grammar/lex/ansic.jisonlex +115 -0
  204. data/vendor/coffee-script/vendor/jison/tests/grammar/lex/bnf.jisonlex +25 -0
  205. data/vendor/coffee-script/vendor/jison/tests/grammar/lex/bnf.lex.json +24 -0
  206. data/vendor/coffee-script/vendor/jison/tests/grammar/lex/lex_grammar.jisonlex +31 -0
  207. data/vendor/coffee-script/vendor/jison/tests/grammar/lex/lex_grammar.lex.json +30 -0
  208. data/vendor/coffee-script/vendor/jison/tests/grammar/lex.jison +119 -0
  209. data/vendor/coffee-script/vendor/jison/tests/grammar/lex.js +58 -0
  210. data/vendor/coffee-script/vendor/jison/tests/grammar/lex_parse.js +117 -0
  211. data/vendor/coffee-script/vendor/jison/tests/lexer/lexer-tests.js +6 -0
  212. data/vendor/coffee-script/vendor/jison/tests/lexer/regexplexer.js +417 -0
  213. data/vendor/coffee-script/vendor/jison/tests/parser/actions.js +311 -0
  214. data/vendor/coffee-script/vendor/jison/tests/parser/api.js +236 -0
  215. data/vendor/coffee-script/vendor/jison/tests/parser/generator.js +196 -0
  216. data/vendor/coffee-script/vendor/jison/tests/parser/lalr.js +183 -0
  217. data/vendor/coffee-script/vendor/jison/tests/parser/lr0.js +72 -0
  218. data/vendor/coffee-script/vendor/jison/tests/parser/lr1.js +119 -0
  219. data/vendor/coffee-script/vendor/jison/tests/parser/parser-tests.js +14 -0
  220. data/vendor/coffee-script/vendor/jison/tests/parser/precedence.js +237 -0
  221. data/vendor/coffee-script/vendor/jison/tests/parser/slr.js +52 -0
  222. data/vendor/coffee-script/vendor/jison/tests/parser/tables.js +126 -0
  223. data/vendor/coffee-script/vendor/jison/tests/performance.js +110 -0
  224. data/vendor/coffee-script/vendor/jison/tests/setup.js +3 -0
  225. metadata +324 -0
@@ -0,0 +1,1414 @@
1
+ // Jison, an LR(0), SLR(1), LARL(1), LR(1) Parser Generator
2
+ // Zachary Carter <zach@carter.name>
3
+ // MIT X Licensed
4
+
5
+ if (typeof exports === 'undefined') {
6
+ exports = {};
7
+ } else {
8
+ // assume we're in commonjs land
9
+ //var system = require("system");
10
+ var typal = require('./jison/util/typal').typal;
11
+ var Set = require('./jison/util/set').Set;
12
+ var RegExpLexer = require('./jison/lexer').RegExpLexer;
13
+ }
14
+
15
+ var Jison = exports.Jison = exports;
16
+
17
+ // detect print
18
+ if (typeof puts !== 'undefined') {
19
+ Jison.print = function print () { puts([].join.call(arguments, ' ')); };
20
+ } else if (typeof print !== 'undefined') {
21
+ Jison.print = print;
22
+ } else {
23
+ Jison.print = function print () {};
24
+ }
25
+
26
+ Jison.Parser = (function () {
27
+
28
+ // iterator utility
29
+ function each (obj, func) {
30
+ if (obj.forEach) {
31
+ obj.forEach(func);
32
+ } else {
33
+ var p;
34
+ for (p in obj) {
35
+ if (obj.hasOwnProperty(p)) {
36
+ func.call(obj, obj[p], p, obj);
37
+ }
38
+ }
39
+ }
40
+ }
41
+
42
+ var Nonterminal = typal.construct({
43
+ constructor: function Nonterminal (symbol) {
44
+ this.symbol = symbol;
45
+ this.productions = new Set();
46
+ this.first = [];
47
+ this.follows = [];
48
+ this.nullable = false;
49
+ },
50
+ toString: function Nonterminal_toString () {
51
+ var str = this.symbol+"\n";
52
+ str += (this.nullable ? 'nullable' : 'not nullable');
53
+ str += "\nFirsts: "+this.first.join(', ');
54
+ str += "\nFollows: "+this.first.join(', ');
55
+ str += "\nProductions:\n "+this.productions.join('\n ');
56
+
57
+ return str;
58
+ }
59
+ });
60
+
61
+ var Production = typal.construct({
62
+ constructor: function Production (symbol, handle, id) {
63
+ this.symbol = symbol;
64
+ this.handle = handle;
65
+ this.nullable = false;
66
+ this.id = id;
67
+ this.first = [];
68
+ this.precedence = 0;
69
+ },
70
+ toString: function Production_toString () {
71
+ return this.symbol+" -> "+this.handle.join(' ');
72
+ }
73
+ });
74
+
75
+ var generator = typal.beget();
76
+
77
+ generator.constructor = function Jison_Generator (grammar, opt) {
78
+ if (typeof grammar === 'string') {
79
+ grammar = require("jison/bnf").parse(grammar);
80
+ }
81
+
82
+ var options = typal.mix.call({}, grammar.options, opt);
83
+ this.terms = {};
84
+ this.operators = {};
85
+ this.productions = [];
86
+ this.conflicts = 0;
87
+ this.resolutions = [];
88
+ this.options = options;
89
+ this.yy = {}; // accessed as yy free variable in the parser/lexer actions
90
+
91
+ // source included in semantic action execution scope
92
+ if (grammar.actionInclude) {
93
+ if (typeof grammar.actionInclude === 'function') {
94
+ grammar.actionInclude = String(grammar.actionInclude).replace(/^\s*function \(\) \{/, '').replace(/\}\s*$/, '');
95
+ }
96
+ this.actionInclude = grammar.actionInclude;
97
+ }
98
+
99
+ this.DEBUG = options.debug || false;
100
+ if (this.DEBUG) this.mix(generatorDebug); // mixin debug methods
101
+
102
+ this.processGrammar(grammar);
103
+
104
+ if (grammar.lex) {
105
+ this.lexer = new RegExpLexer(grammar.lex, null, this.terminals_);
106
+ }
107
+ };
108
+
109
+ generator.processGrammar = function processGrammarDef (grammar) {
110
+ var bnf = grammar.bnf,
111
+ tokens = grammar.tokens,
112
+ nonterminals = this.nonterminals = {},
113
+ productions = this.productions,
114
+ self = this;
115
+
116
+ if (tokens) {
117
+ if (typeof tokens === 'string') {
118
+ tokens = tokens.trim().split(' ');
119
+ } else {
120
+ tokens = tokens.slice(0);
121
+ }
122
+ }
123
+
124
+ var symbols = this.symbols = [];
125
+
126
+ // calculate precedence of operators
127
+ var operators = this.operators = processOperators(grammar.operators);
128
+
129
+ // build productions from cfg
130
+ this.buildProductions(grammar.bnf, productions, nonterminals, symbols, operators);
131
+
132
+ if (tokens && this.terminals.length !== tokens.length) {
133
+ self.trace("Warning: declared tokens differ from tokens found in rules.");
134
+ self.trace(this.terminals);
135
+ self.trace(tokens);
136
+ }
137
+
138
+ // augment the grammar
139
+ this.augmentGrammar(grammar);
140
+ };
141
+
142
+ generator.augmentGrammar = function augmentGrammar (grammar) {
143
+ // use specified start symbol, or default to first user defined production
144
+ this.startSymbol = grammar.start || grammar.startSymbol || this.productions[0].symbol;
145
+ if (!this.nonterminals[this.startSymbol]) {
146
+ throw new Error("Grammar error: startSymbol must be a non-terminal found in your grammar.");
147
+ }
148
+ this.EOF = "$end";
149
+
150
+ // augment the grammar
151
+ var acceptProduction = new Production('$accept', [this.startSymbol, '$end'], 0);
152
+ this.productions.unshift(acceptProduction);
153
+
154
+ // prepend parser tokens
155
+ this.symbols.unshift("$accept","$end");
156
+ this.symbols_["$accept"] = 0;
157
+ this.symbols_["$end"] = 1;
158
+ this.terminals.unshift("$end");
159
+
160
+ this.nonterminals["$accept"] = new Nonterminal("$accept");
161
+ this.nonterminals["$accept"].productions.push(acceptProduction);
162
+
163
+ // add follow $ to start symbol
164
+ this.nonterminals[this.startSymbol].follows.push(this.EOF);
165
+ };
166
+
167
+ // set precedence and associativity of operators
168
+ function processOperators (ops) {
169
+ if (!ops) return {};
170
+ var operators = {};
171
+ for (var i=0,k,prec;prec=ops[i]; i++) {
172
+ for (k=1;k < prec.length;k++) {
173
+ operators[prec[k]] = {precedence: i+1, assoc: prec[0]};
174
+ }
175
+ }
176
+ return operators;
177
+ }
178
+
179
+
180
+ generator.buildProductions = function buildProductions(bnf, productions, nonterminals, symbols, operators) {
181
+ var actions = [this.actionInclude || "", "var $$ = arguments[5],$0=arguments[5].length;",'switch(arguments[4]) {'],
182
+ prods, symbol;
183
+ var productions_ = [0];
184
+ var symbolId = 1;
185
+ var symbols_ = {};
186
+
187
+ function addSymbol (s) {
188
+ if (s && !symbols_[s]) {
189
+ symbols_[s] = ++symbolId;
190
+ symbols.push(s);
191
+ }
192
+ }
193
+
194
+ for (symbol in bnf) {
195
+ if (!bnf.hasOwnProperty(symbol)) continue;
196
+
197
+ addSymbol(symbol);
198
+ nonterminals[symbol] = new Nonterminal(symbol);
199
+
200
+ if (typeof bnf[symbol] === 'string') {
201
+ prods = bnf[symbol].split(/\s*\|\s*/g);
202
+ } else {
203
+ prods = bnf[symbol].slice(0);
204
+ }
205
+
206
+ prods.forEach(function buildProds_forEach (handle) {
207
+ var r, rhs, i;
208
+ if (handle.constructor === Array) {
209
+ if (typeof handle[0] === 'string')
210
+ rhs = handle[0].trim().split(' ');
211
+ else
212
+ rhs = handle[0].slice(0);
213
+
214
+ for (i=0; i<rhs.length; i++) if (!symbols_[rhs[i]]) {
215
+ addSymbol(rhs[i]);
216
+ }
217
+
218
+ if (typeof handle[1] === 'string' || handle.length == 3) {
219
+ // semantic action specified
220
+ var action = 'case '+(productions.length+1)+':'+handle[1]+'\nbreak;';
221
+
222
+ // replace named semantic values ($nonterminal)
223
+ if (action.match(/\$[a-zA-Z][a-zA-Z0-9_]*/)) {
224
+ var count = {},
225
+ names = {};
226
+ for (i=0;i<rhs.length;i++) {
227
+ if (names[rhs[i]]) {
228
+ names[rhs[i]+(++count[rhs[i]])] = i+1;
229
+ } else {
230
+ names[rhs[i]] = i+1;
231
+ names[rhs[i]+"1"] = i+1;
232
+ count[rhs[i]] = 1;
233
+ }
234
+ }
235
+ action = action.replace(/\$([a-zA-Z][a-zA-Z0-9_]*)/g, function (str, pl) {
236
+ return names[pl] ? '$'+names[pl] : pl;
237
+ });
238
+ }
239
+ action = action.replace(/\$(?:0|\$)/g, "this.$")
240
+ .replace(/\$(\d+)/g, "$$$[\$0-"+rhs.length+"+$1-1]");
241
+ actions.push(action);
242
+
243
+ r = new Production(symbol, rhs, productions.length+1);
244
+ // precedence specified also
245
+ if (handle[2]) {
246
+ r.precedence = operators[handle[2].prec].precedence;
247
+ }
248
+ } else {
249
+ // only precedence specified
250
+ r = new Production(symbol, rhs, productions.length+1);
251
+ r.precedence = operators[handle[1].prec].precedence;
252
+ }
253
+ } else {
254
+ rhs = handle.trim().split(' ');
255
+ for (i=0; i<rhs.length; i++) if (!symbols_[rhs[i]]) {
256
+ addSymbol(rhs[i]);
257
+ }
258
+ r = new Production(symbol, rhs, productions.length+1);
259
+ }
260
+ if (r.precedence === 0) {
261
+ // set precedence
262
+ for (i=r.handle.length-1; i>=0; i--) {
263
+ if (!(r.handle[i] in nonterminals) && r.handle[i] in operators) {
264
+ r.precedence = operators[r.handle[i]].precedence;
265
+ }
266
+ }
267
+ }
268
+
269
+ productions.push(r);
270
+ productions_.push([symbols_[r.symbol], r.handle[0] === '' ? 0 : r.handle.length]);
271
+ nonterminals[symbol].productions.push(r);
272
+ });
273
+ }
274
+
275
+ var sym, terms = [], terms_ = {};
276
+ each(symbols_, function (id, sym) {
277
+ if (!nonterminals[sym]) {
278
+ terms.push(sym);
279
+ terms_[id] = sym;
280
+ }
281
+ });
282
+
283
+ this.terminals = terms;
284
+ this.terminals_ = terms_;
285
+ this.symbols_ = symbols_;
286
+
287
+ this.productions_ = productions_;
288
+ actions.push('}');
289
+ this.performAction = Function("yytext","yyleng","yylineno","yy", actions.join("\n"));
290
+ };
291
+
292
+ generator.createParser = function createParser () {
293
+ throw 'Calling abstract method.';
294
+ };
295
+
296
+ // noop. implemented in debug mixin
297
+ generator.trace = function trace () { };
298
+
299
+ generator.warn = function warn () {
300
+ Jison.print.apply(null,arguments);
301
+ };
302
+
303
+ generator.error = function error (msg) {
304
+ throw msg;
305
+ };
306
+
307
+ // Generator debug mixin
308
+
309
+ var generatorDebug = {
310
+ trace: function trace () {
311
+ Jison.print.apply(null, arguments);
312
+ },
313
+ beforeprocessGrammar: function () {
314
+ this.trace("Processing grammar.");
315
+ },
316
+ afteraugmentGrammar: function () {
317
+ var trace = this.trace;
318
+ each(this.symbols, function (sym, i) {
319
+ trace(sym+"("+i+")");
320
+ });
321
+ }
322
+ };
323
+
324
+
325
+
326
+ /*
327
+ * Mixin for common behaviors of lookahead parsers
328
+ * */
329
+ var lookaheadMixin = {};
330
+
331
+ lookaheadMixin.computeLookaheads = function computeLookaheads () {
332
+ if (this.DEBUG) this.mix(lookaheadDebug); // mixin debug methods
333
+
334
+ this.computeLookaheads = function () {};
335
+ this.nullableSets();
336
+ this.firstSets();
337
+ this.followSets();
338
+ };
339
+
340
+ // calculate follow sets typald on first and nullable
341
+ lookaheadMixin.followSets = function followSets () {
342
+ var productions = this.productions,
343
+ nonterminals = this.nonterminals,
344
+ self = this,
345
+ cont = true;
346
+
347
+ // loop until no further changes have been made
348
+ while(cont) {
349
+ cont = false;
350
+
351
+ productions.forEach(function Follow_prod_forEach (production, k) {
352
+ //self.trace(production.symbol,nonterminals[production.symbol].follows);
353
+ // q is used in Simple LALR algorithm determine follows in context
354
+ var q;
355
+ var ctx = !!self.go_;
356
+
357
+ var set = [],oldcount;
358
+ for (var i=0,t;t=production.handle[i];++i) {
359
+ if (!nonterminals[t]) continue;
360
+
361
+ // for Simple LALR algorithm, self.go_ checks if
362
+ if (ctx)
363
+ q = self.go_(production.symbol, production.handle.slice(0, i));
364
+ var bool = !ctx || q === parseInt(self.nterms_[t]);
365
+
366
+ if (i === production.handle.length+1 && bool) {
367
+ set = nonterminals[production.symbol].follows
368
+ } else {
369
+ var part = production.handle.slice(i+1);
370
+
371
+ set = self.first(part);
372
+ if (self.nullable(part) && bool) {
373
+ set.push.apply(set, nonterminals[production.symbol].follows);
374
+ }
375
+ }
376
+ oldcount = nonterminals[t].follows.length;
377
+ Set.union(nonterminals[t].follows, set);
378
+ if (oldcount !== nonterminals[t].follows.length) {
379
+ cont = true;
380
+ }
381
+ }
382
+ });
383
+ }
384
+ };
385
+
386
+ // return the FIRST set of a symbol or series of symbols
387
+ lookaheadMixin.first = function first (symbol) {
388
+ // epsilon
389
+ if (symbol === '') {
390
+ return [];
391
+ // RHS
392
+ } else if (symbol instanceof Array) {
393
+ var firsts = [];
394
+ for (var i=0,t;t=symbol[i];++i) {
395
+ this.first(t).forEach(function first_forEach (e) {
396
+ if (firsts.indexOf(e)===-1)
397
+ firsts.push(e);
398
+ });
399
+ if (!this.nullable(t))
400
+ break;
401
+ }
402
+ return firsts;
403
+ // terminal
404
+ } else if (!this.nonterminals[symbol]) {
405
+ return [symbol];
406
+ // nonterminal
407
+ } else {
408
+ return this.nonterminals[symbol].first;
409
+ }
410
+ };
411
+
412
+ // fixed-point calculation of FIRST sets
413
+ lookaheadMixin.firstSets = function firstSets () {
414
+ var productions = this.productions,
415
+ nonterminals = this.nonterminals,
416
+ self = this,
417
+ cont = true,
418
+ symbol,firsts;
419
+
420
+ // loop until no further changes have been made
421
+ while(cont) {
422
+ cont = false;
423
+
424
+ productions.forEach(function FirstSets_forEach (production, k) {
425
+ var firsts = self.first(production.handle);
426
+ if (firsts.length !== production.first.length) {
427
+ production.first = firsts;
428
+ cont=true;
429
+ }
430
+ });
431
+
432
+ for (symbol in nonterminals) {
433
+ firsts = [];
434
+ nonterminals[symbol].productions.forEach(function (production) {
435
+ Set.union(firsts, production.first);
436
+ });
437
+ if (firsts.length !== nonterminals[symbol].first.length) {
438
+ nonterminals[symbol].first = firsts;
439
+ cont=true;
440
+ }
441
+ }
442
+ }
443
+ };
444
+
445
+ // fixed-point calculation of NULLABLE
446
+ lookaheadMixin.nullableSets = function nullableSets () {
447
+ var firsts = this.firsts = {},
448
+ nonterminals = this.nonterminals,
449
+ self = this,
450
+ cont = true;
451
+
452
+ // loop until no further changes have been made
453
+ while(cont) {
454
+ cont = false;
455
+
456
+ // check if each production is nullable
457
+ this.productions.forEach(function (production, k) {
458
+ if (!production.nullable) {
459
+ for (var i=0,n=0,t;t=production.handle[i];++i) {
460
+ if (self.nullable(t)) n++;
461
+ }
462
+ if (n===i) { // production is nullable if all tokens are nullable
463
+ production.nullable = cont = true;
464
+ }
465
+ }
466
+ });
467
+
468
+ //check if each symbol is nullable
469
+ for (var symbol in nonterminals) {
470
+ if (!this.nullable(symbol)) {
471
+ for (var i=0,production;production=nonterminals[symbol].productions.item(i);i++) {
472
+ if (production.nullable)
473
+ nonterminals[symbol].nullable = cont = true;
474
+ }
475
+ }
476
+ }
477
+ }
478
+ };
479
+
480
+ // check if a token or series of tokens is nullable
481
+ lookaheadMixin.nullable = function nullable (symbol) {
482
+ // epsilon
483
+ if (symbol === '') {
484
+ return true
485
+ // RHS
486
+ } else if (symbol instanceof Array) {
487
+ for (var i=0,t;t=symbol[i];++i) {
488
+ if (!this.nullable(t))
489
+ return false;
490
+ }
491
+ return true;
492
+ // terminal
493
+ } else if (!this.nonterminals[symbol]) {
494
+ return false;
495
+ // nonterminal
496
+ } else {
497
+ return this.nonterminals[symbol].nullable;
498
+ }
499
+ };
500
+
501
+
502
+ // lookahead debug mixin
503
+ var lookaheadDebug = {
504
+ beforenullableSets: function () {
505
+ this.trace("Computing Nullable sets.");
506
+ },
507
+ beforefirstSets: function () {
508
+ this.trace("Computing First sets.");
509
+ },
510
+ beforefollowSets: function () {
511
+ this.trace("Computing Follow sets.");
512
+ },
513
+ afterfollowSets: function () {
514
+ var trace = this.trace;
515
+ each(this.nonterminals, function (nt, t) {
516
+ trace(nt, '\n');
517
+ });
518
+ }
519
+ };
520
+
521
+ /*
522
+ * Mixin for common LR parser behavior
523
+ * */
524
+ var lrGeneratorMixin = {};
525
+
526
+ lrGeneratorMixin.buildTable = function buildTable () {
527
+ if (this.DEBUG) this.mix(lrGeneratorDebug); // mixin debug methods
528
+
529
+ this.states = this.canonicalCollection();
530
+ this.table = this.parseTable(this.states);
531
+ };
532
+
533
+ lrGeneratorMixin.Item = typal.construct({
534
+ constructor: function Item(production, dot, f, predecessor) {
535
+ this.production = production;
536
+ this.dotPosition = dot || 0;
537
+ this.follows = f || [];
538
+ this.predecessor = predecessor;
539
+ this.id = parseInt(production.id+'a'+this.dotPosition, 36);
540
+ this.markedSymbol = this.production.handle[this.dotPosition];
541
+ },
542
+ remainingHandle: function () {
543
+ return this.production.handle.slice(this.dotPosition+1);
544
+ },
545
+ eq: function (e) {
546
+ return e.id === this.id;
547
+ },
548
+ toString: function () {
549
+ var temp = this.production.handle.slice(0);
550
+ temp[this.dotPosition] = '.'+(temp[this.dotPosition]||'');
551
+ return '['+this.production.symbol+" -> "+temp.join(' ')
552
+ +(this.follows.length === 0 ? "" : ", "+this.follows.join('/'))
553
+ +']';
554
+ }
555
+ });
556
+
557
+ lrGeneratorMixin.ItemSet = Set.prototype.construct({
558
+ afterconstructor: function () {
559
+ this.reductions = [];
560
+ this.goes = {};
561
+ this.edges = {};
562
+ this.shifts = false;
563
+ this.inadequate = false;
564
+ this.hash_ = {};
565
+ for (var i=this._items.length-1;i >=0;i--) {
566
+ this.hash_[this._items[i].id] = true; //i;
567
+ }
568
+ },
569
+ concat: function concat (set) {
570
+ var a = set._items || set;
571
+ for (var i=a.length-1;i >=0;i--) {
572
+ this.hash_[a[i].id] = true; //i;
573
+ }
574
+ this._items.push.apply(this._items, a);
575
+ return this;
576
+ },
577
+ push: function (item) {
578
+ this.hash_[item.id] = true;
579
+ return this._items.push(item);
580
+ },
581
+ contains: function (item) {
582
+ return this.hash_[item.id];
583
+ },
584
+ toValue: function toValue () {
585
+ var v = this.items_.sort().join('|');
586
+ return (this.toValue = function toValue_inner() {return v;})();
587
+ }
588
+ });
589
+
590
+ lrGeneratorMixin.closureOperation = function closureOperation (itemSet /*, closureSet*/) {
591
+ var closureSet = new this.ItemSet();
592
+ var self = this;
593
+
594
+ var set = itemSet,
595
+ itemQueue, syms = {};
596
+
597
+ do {
598
+ itemQueue = new Set();
599
+ closureSet.concat(set);
600
+ set.forEach(function CO_set_forEach (item) {
601
+ var symbol = item.markedSymbol;
602
+
603
+ // if token is a non-terminal, recursively add closures
604
+ if (symbol && self.nonterminals[symbol]) {
605
+ if(!syms[symbol]) {
606
+ self.nonterminals[symbol].productions.forEach(function CO_nt_forEach (production) {
607
+ var newItem = new self.Item(production, 0);
608
+ if(!closureSet.contains(newItem))
609
+ itemQueue.push(newItem);
610
+ });
611
+ syms[symbol] = true;
612
+ }
613
+ } else if (!symbol) {
614
+ // reduction
615
+ closureSet.reductions.push(item);
616
+ closureSet.inadequate = closureSet.reductions.length > 1 || closureSet.shifts;
617
+ } else {
618
+ // shift
619
+ closureSet.shifts = true;
620
+ closureSet.inadequate = closureSet.reductions.length > 0;
621
+ }
622
+ });
623
+
624
+ set = itemQueue;
625
+
626
+ } while (!itemQueue.isEmpty());
627
+
628
+ return closureSet;
629
+ };
630
+
631
+ lrGeneratorMixin.gotoOperation = function gotoOperation (itemSet, symbol) {
632
+ var gotoSet = new this.ItemSet(),
633
+ EOF = this.EOF,
634
+ self = this;
635
+
636
+ itemSet.forEach(function goto_forEach(item, n) {
637
+ if (item.markedSymbol === symbol && symbol !== EOF) {
638
+ gotoSet.push(new self.Item(item.production, item.dotPosition+1, item.follows, n));
639
+ }
640
+ });
641
+
642
+ return gotoSet.isEmpty() ? gotoSet : this.closureOperation(gotoSet);
643
+ };
644
+
645
+ /* Create unique set of item sets
646
+ * */
647
+ lrGeneratorMixin.canonicalCollection = function canonicalCollection () {
648
+ var item1 = new this.Item(this.productions[0], 0, new Set(this.EOF));
649
+ var firstState = this.closureOperation(new this.ItemSet(item1)),
650
+ states = new Set(firstState),
651
+ marked = 0,
652
+ self = this,
653
+ itemSet;
654
+
655
+ while (marked !== states.size()) {
656
+ itemSet = states.item(marked); marked++;
657
+ itemSet.forEach(function CC_itemSet_forEach(item) {
658
+ if(item.markedSymbol)
659
+ self.canonicalCollectionInsert(item.markedSymbol, itemSet, states, marked-1);
660
+ });
661
+ }
662
+
663
+ return states;
664
+ };
665
+
666
+ // Pushes a unique state into the que. Some parsing algorithms may perform additional operations
667
+ lrGeneratorMixin.canonicalCollectionInsert = function canonicalCollectionInsert (symbol, itemSet, states, stateNum) {
668
+ var g = this.gotoOperation(itemSet, symbol);
669
+ if (!g.predecessors)
670
+ g.predecessors = {};
671
+ // add g to que if not empty or duplicate
672
+ if (!g.isEmpty()) {
673
+ var i = states.indexOf(g);
674
+ if (i === -1) {
675
+ itemSet.edges[symbol] = states.size(); // store goto transition for table
676
+ states.push(g);
677
+ g.predecessors[symbol] = [stateNum];
678
+ } else {
679
+ itemSet.edges[symbol] = i; // store goto transition for table
680
+ states.item(i).predecessors[symbol].push(stateNum);
681
+ }
682
+ }
683
+ };
684
+
685
+ lrGeneratorMixin.parseTable = function parseTable (itemSets) {
686
+ var states = [],
687
+ nonterminals = this.nonterminals,
688
+ operators = this.operators,
689
+ self = this,
690
+ s = 1, // shift
691
+ r = 2, // reduce
692
+ a = 3; // accept
693
+
694
+ // for each item set
695
+ itemSets.forEach(function (itemSet, k) {
696
+ var state = states[k] = {};
697
+ var action, stackSymbol;
698
+
699
+ // set shift and goto actions
700
+ for (stackSymbol in itemSet.edges) {
701
+ itemSet.forEach(function (item, j) {
702
+ // find shift and goto actions
703
+ if (item.markedSymbol == stackSymbol) {
704
+ var gotoState = itemSet.edges[stackSymbol];
705
+ if (nonterminals[stackSymbol]) {
706
+ // store state to go to after a reduce
707
+ //self.trace(k, stackSymbol, 'g'+gotoState);
708
+ state[self.symbols_[stackSymbol]] = gotoState;
709
+ } else {
710
+ //self.trace(k, stackSymbol, 's'+gotoState);
711
+ state[self.symbols_[stackSymbol]] = [[s,gotoState]];
712
+ }
713
+ }
714
+ });
715
+ }
716
+
717
+ // set accept action
718
+ itemSet.forEach(function (item, j) {
719
+ if (item.markedSymbol == self.EOF) {
720
+ // accept
721
+ state[self.symbols_[self.EOF]] = [[a]];
722
+ //self.trace(k, self.EOF, state[self.EOF]);
723
+ }
724
+ });
725
+
726
+ var allterms = self.lookAheads ? false : self.terminals;
727
+
728
+ // set reductions and resolve potential conflicts
729
+ itemSet.reductions.forEach(function (item, j) {
730
+ // if parser uses lookahead, only enumerate those terminals
731
+ var terminals = allterms || self.lookAheads(itemSet, item);
732
+
733
+ terminals.forEach(function (stackSymbol) {
734
+ action = state[self.symbols_[stackSymbol]] || [];
735
+ var op = operators[stackSymbol];
736
+ // Reading a terminal and current position is at the end of a production, try to reduce
737
+ if (action.length) {
738
+ var sol = resolveConflict(item.production, op, [r,item.production.id], action[0]);
739
+ self.resolutions.push([k,stackSymbol,sol]);
740
+ if (sol.bydefault) {
741
+ self.conflicts++;
742
+ if (!self.DEBUG) {
743
+ self.warn('Conflict in grammar (state:',k, ', token:',stackSymbol, ")\n ", printAction(sol.r, self), "\n ", printAction(sol.s, self));
744
+ }
745
+ if (self.options.noDefaultResolve) {
746
+ action.push(sol.r);
747
+ }
748
+ } else {
749
+ action = [sol.action];
750
+ }
751
+ } else {
752
+ action.push([r,item.production.id]);
753
+ }
754
+ if (action && action.length) {
755
+ state[self.symbols_[stackSymbol]] = action;
756
+ }
757
+ });
758
+ });
759
+
760
+ });
761
+
762
+ return states;
763
+ };
764
+
765
+ // resolves shift-reduce and reduce-reduce conflicts
766
+ function resolveConflict (production, op, reduce, shift) {
767
+ var sln = {production: production, operator: op, r: reduce, s: shift},
768
+ s = 1, // shift
769
+ r = 2, // reduce
770
+ a = 3; // accept
771
+
772
+ if (shift[0] === r) {
773
+ sln.msg = "Resolve R/R conflict (use first production declared in grammar.)";
774
+ sln.action = shift[1] < reduce[1] ? shift : reduce;
775
+ sln.bydefault = true;
776
+ //print(production, reduce[0]);
777
+ return sln;
778
+ }
779
+
780
+ if (production.precedence === 0 || !op) {
781
+ sln.msg = "Resolve S/R conflict (shift by default.)";
782
+ sln.bydefault = true;
783
+ sln.action = shift;
784
+ } else if (production.precedence < op.precedence ) {
785
+ sln.msg = "Resolve S/R conflict (shift for higher precedent operator.)";
786
+ sln.action = shift;
787
+ } else if (production.precedence === op.precedence) {
788
+ if (op.assoc === "right" ) {
789
+ sln.msg = "Resolve S/R conflict (shift for right associative operator.)";
790
+ sln.action = shift;
791
+ } else if (op.assoc === "left" ) {
792
+ sln.msg = "Resolve S/R conflict (reduce for left associative operator.)";
793
+ sln.action = reduce;
794
+ } else if (op.assoc === "nonassoc" ) {
795
+ sln.msg = "Resolve S/R conflict (no action for non-associative operator.)";
796
+ sln.action = undefined;
797
+ }
798
+ } else {
799
+ sln.msg = "Resolve conflict (reduce for higher precedent production.)";
800
+ sln.action = reduce;
801
+ }
802
+
803
+ return sln;
804
+ }
805
+
806
+ lrGeneratorMixin.generate = function parser_generate (opt) {
807
+ opt = typal.mix.call({}, this.options, opt);
808
+ var code = "";
809
+ switch (opt.moduleType) {
810
+ case "js":
811
+ code = this.generateModule(opt);
812
+ break;
813
+ case "commonjs":
814
+ default:
815
+ code = this.generateCommonJSModule(opt);
816
+ }
817
+
818
+ return code;
819
+ };
820
+
821
+ lrGeneratorMixin.generateCommonJSModule = function generateCommonJSModule (opt) {
822
+ opt = typal.mix.call({}, this.options, opt);
823
+ var moduleName = opt.moduleName || "parser";
824
+ var out = this.generateModule(opt);
825
+ out += "\nif (typeof require !== 'undefined') {";
826
+ out += "\nexports.parser = "+moduleName+";";
827
+ out += "\nexports.parse = function () { return "+moduleName+".parse.apply("+moduleName+", arguments); }";
828
+ out += "\nexports.main = "+ String(opt.moduleMain || commonjsMain);
829
+ out += "\nif (require.main === module) {\n\texports.main(require(\"system\").args);\n}";
830
+ out += "\n}";
831
+
832
+ return out;
833
+ };
834
+
835
+ lrGeneratorMixin.generateModule = function generateModule (opt) {
836
+ opt = typal.mix.call({}, this.options, opt);
837
+ var moduleName = opt.moduleName || "parser";
838
+ var out = "/* Jison generated parser */\n";
839
+ out += (moduleName.match(/\./) ? moduleName : "var "+moduleName)+" = (function(){";
840
+ out += "\nvar parser = "+this.generateModule_();
841
+ if (this.lexer && this.lexer.generateModule) {
842
+ out += this.lexer.generateModule();
843
+ out += "\nparser.lexer = lexer;";
844
+ }
845
+ out += "\nreturn parser;\n})();";
846
+
847
+ return out;
848
+ };
849
+
850
+ lrGeneratorMixin.generateModule_ = function generateModule_ () {
851
+ var out = "{";
852
+ out += [
853
+ "trace: " + String(this.trace),
854
+ "yy: {}",
855
+ "symbols_: " + JSON.stringify(this.symbols_),
856
+ "terminals_: " + JSON.stringify(this.terminals_),
857
+ "productions_: " + JSON.stringify(this.productions_),
858
+ "performAction: " + String(this.performAction),
859
+ "table: " + JSON.stringify(this.table),
860
+ "parseError: " + String(this.parseError || parser.parseError),
861
+ "parse: " + String(parser.parse)
862
+ ].join(",\n");
863
+ out += "};";
864
+
865
+ return out;
866
+ };
867
+
868
+ // default main method for generated commonjs modules
869
+ function commonjsMain (args) {
870
+ var cwd = require("file").path(require("file").cwd());
871
+ if (!args[1])
872
+ throw new Error('Usage: '+args[0]+' FILE');
873
+ var source = cwd.join(args[1]).read({charset: "utf-8"});
874
+ this.parse(source);
875
+ }
876
+
877
+ // debug mixin for LR parser generators
878
+
879
+ function printAction (a, gen) {
880
+ var s = a[0] == 1 ? 'shift '+gen.symbols[a[1]] :
881
+ a[0] == 2 ? 'reduce by '+gen.productions[a[1]] :
882
+ 'accept' ;
883
+
884
+ return s;
885
+ }
886
+
887
+ var lrGeneratorDebug = {
888
+ beforeparseTable: function () {
889
+ this.trace("Building parse table.");
890
+ },
891
+ afterparseTable: function () {
892
+ var self = this;
893
+ if (this.conflicts > 0) {
894
+ this.resolutions.forEach(function (r, i) {
895
+ if (r[2].bydefault) {
896
+ self.warn('Conflict at state:',r[0], ', Token:',r[1], "\n ", printAction(r[2].r, self), "\n ", printAction(r[2].s, self));
897
+ }
898
+ });
899
+ this.trace("\n"+this.conflicts+" Conflict(s) found in grammar.");
900
+ }
901
+ this.trace("Done.");
902
+ },
903
+ aftercanonicalCollection: function (states) {
904
+ var trace = this.trace;
905
+ trace("\nItem sets\n------");
906
+
907
+ states.forEach(function (state, i) {
908
+ trace("\nitem set",i,"\n"+state.join("\n"), '\ntransitions -> ', JSON.stringify(state.edges));
909
+ });
910
+ }
911
+ };
912
+
913
+ var parser = typal.beget();
914
+
915
+ lrGeneratorMixin.createParser = function createParser () {
916
+ var p = parser.beget();
917
+
918
+ p.init({
919
+ table: this.table,
920
+ productions_: this.productions_,
921
+ symbols_: this.symbols_,
922
+ terminals_: this.terminals_,
923
+ performAction: this.performAction
924
+ });
925
+
926
+ // for debugging
927
+ p.productions = this.productions;
928
+
929
+ // backwards compatability
930
+ p.generate = this.generate;
931
+ p.lexer = this.lexer;
932
+ p.generateModule = this.generateModule;
933
+ p.generateCommonJSModule = this.generateCommonJSModule;
934
+ p.generateModule_ = this.generateModule_;
935
+
936
+ return p;
937
+ };
938
+
939
+ parser.yy = {};
940
+ parser.trace = generator.trace;
941
+ parser.warn = generator.warn;
942
+ parser.error = generator.error;
943
+
944
+ parser.parseError = lrGeneratorMixin.parseError = function parseError (str, hash) {
945
+ throw new Error(str);
946
+ };
947
+
948
+ parser.parse = function parse (input) {
949
+ var self = this,
950
+ stack = [0],
951
+ vstack = [null], // semantic value stack
952
+ table = this.table,
953
+ yytext = '',
954
+ yylineno = 0,
955
+ yyleng = 0,
956
+ shifts = 0,
957
+ reductions = 0;
958
+
959
+ this.lexer.setInput(input);
960
+ this.lexer.yy = this.yy;
961
+
962
+ var parseError = this.yy.parseError = this.yy.parseError || this.parseError;
963
+
964
+ function lex() {
965
+ var token;
966
+ token = self.lexer.lex() || 1; // $end = 1
967
+ // if token isn't its numeric value, convert
968
+ if (typeof token !== 'number') {
969
+ token = self.symbols_[token];
970
+ }
971
+ return token;
972
+ };
973
+
974
+ var symbol, state, action, a, r, yyval={},p,len,ip=0,newState, expected;
975
+ symbol = lex();
976
+ while (true) {
977
+ // set first input
978
+ state = stack[stack.length-1];
979
+ // read action for current state and first input
980
+ action = table[state] && table[state][symbol];
981
+
982
+ if (typeof action == 'undefined' || !action.length || !action[0]) {
983
+ expected = [];
984
+ for (p in table[state]) if (this.terminals_[p] && p != 1) {
985
+ expected.push("'"+this.terminals_[p]+"'");
986
+ }
987
+ if (this.lexer.showPosition) {
988
+ parseError('Parse error on line '+(yylineno+1)+":\n"+this.lexer.showPosition()+'\nExpecting '+expected.join(', '),
989
+ {text: this.lexer.match, token: this.terminals_[symbol], line: this.lexer.yylineno, expected: expected});
990
+ } else {
991
+ parseError('Parse error on line '+(yylineno+1)+": Unexpected '"+this.terminals_[symbol]+"'",
992
+ {text: this.lexer.match, token: this.terminals_[symbol], line: this.lexer.yylineno, expected: expected});
993
+ }
994
+ }
995
+
996
+ this.trace('action:',action);
997
+
998
+ // this shouldn't happen, unless resolve defaults are off
999
+ if (action.length > 1) {
1000
+ throw new Error('Parse Error: multiple actions possible at state: '+state+', token: '+symbol);
1001
+ }
1002
+
1003
+ a = action[0];
1004
+
1005
+ switch (a[0]) {
1006
+
1007
+ case 1: // shift
1008
+ shifts++;
1009
+
1010
+ stack.push(symbol);++ip;
1011
+ yyleng = this.lexer.yyleng;
1012
+ yytext = this.lexer.yytext;
1013
+ yylineno = this.lexer.yylineno;
1014
+ symbol = lex();
1015
+ vstack.push(null); // semantic values or junk only, no terminals
1016
+ stack.push(a[1]); // push state
1017
+ break;
1018
+
1019
+ case 2: // reduce
1020
+ reductions++;
1021
+
1022
+ len = this.productions_[a[1]][1];
1023
+
1024
+ // perform semantic action
1025
+ yyval.$ = vstack[vstack.length-len]; // default to $$ = $1
1026
+ r = this.performAction.call(yyval, yytext, yyleng, yylineno, this.yy, a[1], vstack);
1027
+
1028
+ if (typeof r !== 'undefined') {
1029
+ return r;
1030
+ }
1031
+
1032
+ // pop off stack
1033
+ if (len) {
1034
+ stack = stack.slice(0,-1*len*2);
1035
+ vstack = vstack.slice(0, -1*len);
1036
+ }
1037
+
1038
+ stack.push(this.productions_[a[1]][0]); // push nonterminal (reduce)
1039
+ vstack.push(yyval.$);
1040
+ // goto new state = table[STATE][NONTERMINAL]
1041
+ newState = table[stack[stack.length-2]][stack[stack.length-1]];
1042
+ stack.push(newState);
1043
+ break;
1044
+
1045
+ case 3: // accept
1046
+
1047
+ this.reductionCount = reductions;
1048
+ this.shiftCount = shifts;
1049
+ return true;
1050
+ }
1051
+
1052
+ }
1053
+
1054
+ return true;
1055
+ };
1056
+
1057
+ parser.init = function parser_init (dict) {
1058
+ this.table = dict.table;
1059
+ this.performAction = dict.performAction;
1060
+ this.productions_ = dict.productions_;
1061
+ this.symbols_ = dict.symbols_;
1062
+ this.terminals_ = dict.terminals_;
1063
+ };
1064
+
1065
+ /*
1066
+ * LR(0) Parser
1067
+ * */
1068
+
1069
+ var lr0 = generator.beget(lookaheadMixin, lrGeneratorMixin, {
1070
+ type: "LR(0)",
1071
+ afterconstructor: function lr0_afterconstructor () {
1072
+ this.buildTable();
1073
+ }
1074
+ });
1075
+
1076
+ var LR0Generator = exports.LR0Generator = lr0.construct();
1077
+
1078
+ /*
1079
+ * Simple LALR(1)
1080
+ * */
1081
+
1082
+ var lalr = generator.beget(lookaheadMixin, lrGeneratorMixin, {
1083
+ type: "LALR(1)",
1084
+
1085
+ afterconstructor: function (grammar, options) {
1086
+ if (this.DEBUG) this.mix(lrGeneratorDebug, lalrGeneratorDebug); // mixin debug methods
1087
+
1088
+ options = options || {};
1089
+ this.states = this.canonicalCollection();
1090
+ this.terms_ = {};
1091
+
1092
+ var newg = this.newg = typal.beget(lookaheadMixin,{
1093
+ oldg: this,
1094
+ trace: this.trace,
1095
+ nterms_: {},
1096
+ DEBUG: false,
1097
+ go_: function (r, B) {
1098
+ r = r.split(":")[0]; // grab state #
1099
+ B = B.map(function (b) { return b.slice(b.indexOf(":")+1)});
1100
+ return this.oldg.go(r, B);
1101
+ }
1102
+ });
1103
+ newg.nonterminals = {};
1104
+ newg.productions = [];
1105
+
1106
+ this.inadequateStates = [];
1107
+
1108
+ // if true, only lookaheads in inadequate states are computed (faster, larger table)
1109
+ // if false, lookaheads for all reductions will be computed (slower, smaller table)
1110
+ this.onDemandLookahead = options.onDemandLookahead || false;
1111
+
1112
+ this.buildNewGrammar();
1113
+ newg.computeLookaheads();
1114
+ this.unionLookaheads();
1115
+
1116
+ this.table = this.parseTable(this.states);
1117
+ },
1118
+
1119
+ lookAheads: function LALR_lookaheads (state, item) {
1120
+ return (!!this.onDemandLookahead && !state.inadequate) ? this.terminals : item.follows;
1121
+ },
1122
+ go: function LALR_go (p, w) {
1123
+ var q = parseInt(p);
1124
+ for (var i=0;i<w.length;i++) {
1125
+ q = this.states.item(q).edges[w[i]] || q;
1126
+ }
1127
+ return q;
1128
+ },
1129
+ goPath: function LALR_goPath (p, w) {
1130
+ var q = parseInt(p),t,
1131
+ path = [];
1132
+ for (var i=0;i<w.length;i++) {
1133
+ t = w[i] ? q+":"+w[i] : '';
1134
+ if (t) this.newg.nterms_[t] = q;
1135
+ path.push(t);
1136
+ q = this.states.item(q).edges[w[i]] || q;
1137
+ this.terms_[t] = w[i];
1138
+ }
1139
+ return {path: path, endState: q};
1140
+ },
1141
+ // every disjoint reduction of a nonterminal becomes a produciton in G'
1142
+ buildNewGrammar: function LALR_buildNewGrammar () {
1143
+ var self = this,
1144
+ newg = this.newg;
1145
+
1146
+ this.states.forEach(function (state, i) {
1147
+ state.forEach(function (item) {
1148
+ if (item.dotPosition === 0) {
1149
+ // new symbols are a combination of state and transition symbol
1150
+ var symbol = i+":"+item.production.symbol;
1151
+ self.terms_[symbol] = item.production.symbol;
1152
+ newg.nterms_[symbol] = i;
1153
+ if (!newg.nonterminals[symbol])
1154
+ newg.nonterminals[symbol] = new Nonterminal(symbol);
1155
+ var pathInfo = self.goPath(i, item.production.handle);
1156
+ var p = new Production(symbol, pathInfo.path, newg.productions.length);
1157
+ newg.productions.push(p);
1158
+ newg.nonterminals[symbol].productions.push(p);
1159
+
1160
+ // store the transition that get's 'backed up to' after reduction on path
1161
+ var handle = item.production.handle.join(' ');
1162
+ var goes = self.states.item(pathInfo.endState).goes;
1163
+ if (!goes[handle])
1164
+ goes[handle] = [];
1165
+ goes[handle].push(symbol);
1166
+
1167
+ //self.trace('new production:',p);
1168
+ }
1169
+ });
1170
+ if (state.inadequate)
1171
+ self.inadequateStates.push(i);
1172
+ });
1173
+ },
1174
+ unionLookaheads: function LALR_unionLookaheads () {
1175
+ var self = this,
1176
+ newg = this.newg,
1177
+ states = !!this.onDemandLookahead ? this.inadequateStates : this.states;
1178
+
1179
+ states.forEach(function union_states_forEach (i) {
1180
+ var state = typeof i === 'number' ? self.states.item(i) : i,
1181
+ follows = [];
1182
+ if (state.reductions.length)
1183
+ state.reductions.forEach(function union_reduction_forEach (item) {
1184
+ var follows = {};
1185
+ for (var k=0;k<item.follows.length;k++) {
1186
+ follows[item.follows[k]] = true;
1187
+ }
1188
+ state.goes[item.production.handle.join(' ')].forEach(function reduction_goes_forEach (symbol) {
1189
+ newg.nonterminals[symbol].follows.forEach(function goes_follows_forEach (symbol) {
1190
+ var terminal = self.terms_[symbol];
1191
+ if (!follows[terminal]) {
1192
+ follows[terminal]=true;
1193
+ item.follows.push(terminal);
1194
+ }
1195
+ });
1196
+ });
1197
+ //self.trace('unioned item', item);
1198
+ });
1199
+ });
1200
+ }
1201
+ });
1202
+
1203
+ var LALRGenerator = exports.LALRGenerator = lalr.construct();
1204
+
1205
+ // LALR generator debug mixin
1206
+
1207
+ var lalrGeneratorDebug = {
1208
+ trace: function trace () {
1209
+ Jison.print.apply(null, arguments);
1210
+ },
1211
+ beforebuildNewGrammar: function () {
1212
+ this.trace(this.states.size()+" states.");
1213
+ this.trace("Building lookahead grammar.");
1214
+ },
1215
+ beforeunionLookaheads: function () {
1216
+ this.trace("Computing lookaheads.");
1217
+ }
1218
+ };
1219
+
1220
+ /*
1221
+ * Lookahead parser definitions
1222
+ *
1223
+ * Define base type
1224
+ * */
1225
+ var lrLookaheadGenerator = generator.beget(lookaheadMixin, lrGeneratorMixin, {
1226
+ afterconstructor: function lr_aftercontructor () {
1227
+ this.computeLookaheads();
1228
+ this.buildTable();
1229
+ }
1230
+ });
1231
+
1232
+ /*
1233
+ * SLR Parser
1234
+ * */
1235
+ var SLRGenerator = exports.SLRGenerator = lrLookaheadGenerator.construct({
1236
+ type: "SLR(1)",
1237
+
1238
+ lookAheads: function SLR_lookAhead (state, item) {
1239
+ return this.nonterminals[item.production.symbol].follows;
1240
+ }
1241
+ });
1242
+
1243
+
1244
+ /*
1245
+ * LR(1) Parser
1246
+ * */
1247
+ var lr1 = lrLookaheadGenerator.beget({
1248
+ type: "Canonical LR(1)",
1249
+
1250
+ lookAheads: function LR_lookAheads (state, item) {
1251
+ return item.follows;
1252
+ },
1253
+ Item: lrGeneratorMixin.Item.prototype.construct({
1254
+ afterconstructor: function () {
1255
+ this.id = this.production.id+'a'+this.dotPosition+'a'+this.follows.sort().join(',');
1256
+ },
1257
+ eq: function (e) {
1258
+ return e.id === this.id;
1259
+ }
1260
+ }),
1261
+
1262
+ closureOperation: function LR_ClosureOperation (itemSet /*, closureSet*/) {
1263
+ var closureSet = new this.ItemSet();
1264
+ var self = this;
1265
+
1266
+ var set = itemSet,
1267
+ itemQueue, syms = {};
1268
+
1269
+ do {
1270
+ itemQueue = new Set();
1271
+ closureSet.concat(set);
1272
+ set.forEach(function (item) {
1273
+ var symbol = item.markedSymbol;
1274
+ var b;
1275
+
1276
+ // if token is a nonterminal, recursively add closures
1277
+ if (symbol && self.nonterminals[symbol]) {
1278
+ b = self.first(item.remainingHandle());
1279
+ if (b.length === 0) b = item.follows;
1280
+ self.nonterminals[symbol].productions.forEach(function (production) {
1281
+ var newItem = new self.Item(production, 0, b);
1282
+ if(!closureSet.contains(newItem) && !itemQueue.contains(newItem)) {
1283
+ itemQueue.push(newItem);
1284
+ }
1285
+ });
1286
+ } else if (!symbol) {
1287
+ // reduction
1288
+ closureSet.reductions.push(item);
1289
+ }
1290
+ });
1291
+
1292
+ set = itemQueue;
1293
+ } while (!itemQueue.isEmpty());
1294
+
1295
+ return closureSet;
1296
+ }
1297
+ });
1298
+
1299
+ var LR1Generator = exports.LR1Generator = lr1.construct();
1300
+
1301
+ /*
1302
+ * LL Parser
1303
+ * */
1304
+ var ll = generator.beget(lookaheadMixin, {
1305
+ type: "LL(1)",
1306
+
1307
+ afterconstructor: function ll_aftercontructor () {
1308
+ this.computeLookaheads();
1309
+ this.table = this.parseTable(this.productions);
1310
+ },
1311
+ parseTable: function llParseTable (productions) {
1312
+ var table = {},
1313
+ self = this;
1314
+ productions.forEach(function (production, i) {
1315
+ var row = table[production.symbol] || {};
1316
+ var tokens = production.first;
1317
+ if (self.nullable(production.handle)) {
1318
+ Set.union(tokens, self.nonterminals[production.symbol].follows);
1319
+ }
1320
+ tokens.forEach(function (token) {
1321
+ if (row[token]) {
1322
+ row[token].push(i);
1323
+ self.conflicts++;
1324
+ } else {
1325
+ row[token] = [i];
1326
+ }
1327
+ });
1328
+ table[production.symbol] = row;
1329
+ });
1330
+
1331
+ return table;
1332
+ }
1333
+ });
1334
+
1335
+ var LLGenerator = exports.LLGenerator = ll.construct();
1336
+
1337
+ Jison.Generator = function Jison_Generator (g, options) {
1338
+ var opt = typal.mix.call({}, g.options, options);
1339
+ switch (opt.type) {
1340
+ case 'lr0':
1341
+ return new LR0Generator(g, opt);
1342
+ case 'slr':
1343
+ return new SLRGenerator(g, opt);
1344
+ case 'lr':
1345
+ return new LR1Generator(g, opt);
1346
+ case 'll':
1347
+ return new LLGenerator(g, opt);
1348
+ case 'lalr':
1349
+ default:
1350
+ return new LALRGenerator(g, opt);
1351
+ }
1352
+ }
1353
+
1354
+ return function Parser (g, options) {
1355
+ var opt = typal.mix.call({}, g.options, options);
1356
+ var gen;
1357
+ switch (opt.type) {
1358
+ case 'lr0':
1359
+ gen = new LR0Generator(g, opt);
1360
+ case 'slr':
1361
+ gen = new SLRGenerator(g, opt);
1362
+ case 'lr':
1363
+ gen = new LR1Generator(g, opt);
1364
+ case 'll':
1365
+ gen = new LLGenerator(g, opt);
1366
+ case 'lalr':
1367
+ default:
1368
+ gen = new LALRGenerator(g, opt);
1369
+ }
1370
+ return gen.createParser();
1371
+ }
1372
+
1373
+ })();
1374
+
1375
+ exports.main = function main (args) {
1376
+ //var parser = new require("args").Parser();
1377
+ var fs = require("file");
1378
+ gfile = fs.path(fs.cwd()).join(args[1]);
1379
+
1380
+ // try to parse as JSON, else use BNF parser
1381
+ if (gfile.extension() === '.json') {
1382
+ var grammar = JSON.parse(gfile.read({charset: "utf-8"}));
1383
+ } else if (gfile.extension() === '.jison') {
1384
+ var grammar = require("jison/bnf").parse(gfile.read({charset: "utf-8"}));
1385
+ }
1386
+
1387
+ var opt = grammar.options || {};
1388
+
1389
+ // lexer file
1390
+ if (args[2]) {
1391
+ var lfile = fs.path(fs.cwd()).join(args[2]);
1392
+
1393
+ // try to parse as JSON, else use BNF parser
1394
+ if (lfile.extension() === '.json') {
1395
+ grammar.lex = JSON.parse(lfile.read({charset: "utf-8"}));
1396
+ } else if (lfile.extension() === '.jisonlex') {
1397
+ grammar.lex = require("jison/jisonlex").parse(lfile.read({charset: "utf-8"}));
1398
+ }
1399
+ }
1400
+
1401
+ if (!opt.moduleName)
1402
+ opt.moduleName = gfile.basename().replace(new RegExp(gfile.extension()+"$"), "");
1403
+ if (!opt.moduleType)
1404
+ opt.moduleType = "commonjs";
1405
+
1406
+ var generator = new Jison.Generator(grammar, opt);
1407
+ fname = fs.path(fs.cwd()).join(opt.moduleName + ".js"),
1408
+ source = generator.generate(opt),
1409
+ stream = fname.open("w");
1410
+
1411
+ stream.print(source);
1412
+ stream.close();
1413
+ };
1414
+