haml-more 0.4.0.a

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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
+