Class: Aspen::Parser
Instance Attribute Summary
#position, #tokens
Instance Method Summary
collapse
#expect, #first, #initialize, #last, #need, #next_token, parse, parse_code, #peek
Instance Method Details
#parse ⇒ Object
Also known as:
parse_narrative
narrative = statements;
statements = { statement }
statement = | CUSTOM_STATEMENT | list_statement | vanilla_statement
list_statement = node, edge, [ list_label ], START_LIST, list_items, END_LIST
list_label = OPEN_PARENS, LABEL, CLOSE_PARENS
list_items = { list_item }
list_item = BULLET, CONTENT, [ list_item_label ]
list_item_label = OPEN_PARENS, LABEL, CLOSE_PARENS
vanilla_statement = node | node, edge, node, { END_STATEMENT }
node = node_short_form | node_grouped_form | node_cypher_form
node_short_form = OPEN_PARENS, CONTENT, CLOSE_PARENS
node_grouped_form = OPEN_PARENS, { CONTENT, [ COMMA ] }, CLOSE_PARENS
node_cypher_form = OPEN_PARENS, LABEL, OPEN_BRACES, { IDENTIFIER, literal, [ COMMA ] }, CLOSE_BRACES
literal = STRING | NUMBER
edge = OPEN_BRACKETS, CONTENT, CLOSE_BRACKETS
28
29
30
|
# File 'lib/aspen/parser.rb', line 28
def parse
Aspen::AST::Nodes::Narrative.new(parse_statements)
end
|
53
54
55
56
57
|
# File 'lib/aspen/parser.rb', line 53
def
if = expect(:COMMENT)
Aspen::AST::Nodes::.new(.first.last)
end
end
|
#parse_custom_statement ⇒ Object
59
60
61
62
63
64
65
|
# File 'lib/aspen/parser.rb', line 59
def parse_custom_statement
if content = expect(:CUSTOM_GRAMMAR_STATEMENT)
Aspen::AST::Nodes::CustomStatement.new(content.first.last)
end
end
|
#parse_edge ⇒ Object
170
171
172
173
174
|
# File 'lib/aspen/parser.rb', line 170
def parse_edge
if (_, content, _ = expect(:OPEN_BRACKETS, :CONTENT, :CLOSE_BRACKETS))
Aspen::AST::Nodes::Edge.new(content.last)
end
end
|
#parse_list_item ⇒ Object
100
101
102
103
104
105
106
107
108
109
|
# File 'lib/aspen/parser.rb', line 100
def parse_list_item
node = nil
if (_, content = expect(:BULLET, :CONTENT))
node = Aspen::AST::Nodes::Node.new(attribute: content.last)
end
if (label = parse_list_item_label)
node.label = label
end
return node
end
|
#parse_list_item_label ⇒ Object
111
112
113
114
115
116
|
# File 'lib/aspen/parser.rb', line 111
def parse_list_item_label
if (_, item_label, _ = expect(:OPEN_PARENS, :CONTENT, :CLOSE_PARENS))
return item_label.last
end
end
|
#parse_list_items ⇒ Object
90
91
92
93
94
95
96
97
98
|
# File 'lib/aspen/parser.rb', line 90
def parse_list_items
if need(:START_LIST)
results = []
while target = parse_list_item
results << target
end
results
end
end
|
#parse_list_label ⇒ Object
83
84
85
86
87
88
|
# File 'lib/aspen/parser.rb', line 83
def parse_list_label
if (_, plural_label, _ = expect(:OPEN_PARENS, :CONTENT, :CLOSE_PARENS))
return plural_label.last.singularize
end
end
|
#parse_list_statement ⇒ Object
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
|
# File 'lib/aspen/parser.rb', line 67
def parse_list_statement
if expect(:PREPARE_START_LIST)
origin = parse_node
edge = parse_edge
label = parse_list_label
targets = parse_list_items
expect(:END_LIST)
targets.map do |target|
target.label = label if target.label.content.inner_content.nil?
Aspen::AST::Nodes::Statement.new(origin: origin, edge: edge, target: target)
end
end
end
|
#parse_literal ⇒ Object
166
167
168
|
# File 'lib/aspen/parser.rb', line 166
def parse_literal
raise NotImplementedError, "#parse_literal not yet implemented"
end
|
#parse_node ⇒ Object
135
136
137
138
|
# File 'lib/aspen/parser.rb', line 135
def parse_node
parse_node_grouped_form || parse_node_short_form
end
|
This complicates things greatly. Can we skip this for now, by rewriting the tests to get rid of this case, and come back to it?
160
161
162
163
164
|
# File 'lib/aspen/parser.rb', line 160
def parse_node_cypher_form
if (_, label, _, content, _ = expect(:OPEN_PARENS, :CONTENT, :SEPARATOR, :CONTENT, :CLOSE_PARENS))
Aspen::AST::Nodes::Node.new(content: content.last, label: label.last)
end
end
|
140
141
142
143
144
145
146
147
|
# File 'lib/aspen/parser.rb', line 140
def parse_node_grouped_form
if (_, label, sep, content, _ = expect(:OPEN_PARENS, :LABEL, :SEPARATOR, :CONTENT, :CLOSE_PARENS))
Aspen::AST::Nodes::Node.new(
attribute: content.last,
label: label.last
)
end
end
|
119
120
121
|
# File 'lib/aspen/parser.rb', line 119
def parse_node_labeled_form
raise NotImplementedError, "#parse_node_labeled_form not yet implemented"
end
|
149
150
151
152
153
154
155
156
|
# File 'lib/aspen/parser.rb', line 149
def parse_node_short_form
_, content, _ = need(:OPEN_PARENS, :CONTENT, :CLOSE_PARENS)
Aspen::AST::Nodes::Node.new(
attribute: content.last,
label: nil
)
end
|
#parse_statement ⇒ Object
46
47
48
49
50
51
|
# File 'lib/aspen/parser.rb', line 46
def parse_statement
||
parse_custom_statement ||
parse_list_statement ||
parse_vanilla_statement
end
|
#parse_statements ⇒ Object
34
35
36
37
38
39
40
41
42
43
44
|
# File 'lib/aspen/parser.rb', line 34
def parse_statements
results = []
while result = parse_statement
results.push(*result)
break if tokens[position].nil?
end
results
end
|
#parse_vanilla_statement ⇒ Object
123
124
125
126
127
128
129
130
131
132
133
|
# File 'lib/aspen/parser.rb', line 123
def parse_vanilla_statement
origin = parse_node
edge = parse_edge
target = parse_node
advance if peek && peek.first == :END_STATEMENT
Aspen::AST::Nodes::Statement.new(origin: origin, edge: edge, target: target)
end
|