-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathjs_parser_single.rb
112 lines (105 loc) · 3.36 KB
/
js_parser_single.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
#!ruby
# coding: utf-8
#
# js_parser.rb
#
# Created by Erik Österlund on 1/14/10.
# Copyright 2010 Växjö Universitet. All rights reserved.
#
require 'table_generator'
require 'js_compiler_single'
module LALR
class InterpreterGenerator
def generate_parser_single
sm = symbol_to_index
token_to_num = {}
@tokens.size.times do |i|
token_to_num[@tokens[i]] = i + 1 # Start symbol is 0
end
result = <<-end.here_with_pipe
|
|ruleLength = [#{@rules.map{|rule|rule.productions.size.to_s}.join(",")}];
|ruleSym = [#{@rules.map{|rule|sm[rule.name]}.join(",")}];
|goto = [#{
@gotos.size.times.map do |i|
"{" + @gotos[i].each.map do |k, v|
"#{sm[k]}:#{v}"
end.join(",") + "}"
end.join(",")
}];
|shift = [#{
@actions.size.times.map do |i|
"{" + @actions[i].select do |k, v|
v.action == :shift
end.map do |k, v|
"#{k.is_a?(EOF) ? 0 : (k.is_a?(Epsilon) ? "e" : token_to_num[k])}:#{v.number}"
end.join(",") + "}"
end.join(",")
}];
|reduce = [#{
@actions.size.times.map do |i|
"{" + @actions[i].select do |k, v|
v.action == :reduce
end.map do |k, v|
"#{k.is_a?(EOF) ? 0 : (k.is_a?(Epsilon) ? "e" : token_to_num[k])}:#{v.number}"
end.join(",") + "}"
end.join(",")
}];
|accept = {#{
@actions.size.times.select do |i|
@actions[i].select{|k, v| v.action == :accept}.size > 0
end.map do |i|
"#{i}:{" + @actions[i].select{|k, v| v.action == :accept}.map do |k, v|
"#{k.is_a?(EOF) ? 0 : (k.is_a?(Epsilon) ? "e" : token_to_num[k])}:true"
end.join(",") + "}"
end.join(",")
}};
|
|function #{@name}_parser()
|{
|}
|#{@name}_parser.prototype.se = function(index)
|{
|throw index;
|}
|
|#{@name}_parser.prototype.parse = function(tokens)
|{
|var index = 0;
|tok = tokens[index++];
|var symbol = null;
|var o = [];
|var s = [0];
|var si = 0;
|var temp;
|var state = s[si];
|while(true){
|if (symbol != null)
|{
|state = s[++si] = goto[state][symbol];
|symbol = null;
|} else if(temp = shift[state][tok])
|{
|s[++si] = state = temp;tok = tokens[index++];
|} else if(temp = reduce[state][tok]) {
|o[o.length] = temp;
|state = s[si -= ruleLength[temp]];
|symbol = ruleSym[temp];
|} else if(accept[state] && accept[state][tok]) {
|o.push(0);
|return o;
|} else if(temp = shift[state]["e"]) {
|s[++si] = state = temp;
|} else {
|if (index == 1)
|return o;
|this.se(index);
|return;
|}
|}
|}
end
result + generate_compiler_single
end
end
end