end
class Parser
-special ParserTable
+special TablesCapable
# Associated lexer
var _lexer: Lexer
_lexer = lexer
_stack = new Array[State]
_stack_pos = -1
- build_goto_table
- build_action_table
build_reduce_table
end
private fun go_to(index: Int): Int
do
var state = state
- var table = _goto_table[index]
var low = 1
- var high = table.length/2 - 1
+ var high = parser_goto(index, 0) - 1
while low <= high do
var middle = (low + high) / 2
- var subindex = middle * 2
+ var subindex = middle * 2 + 1 # +1 because parser_goto(index, 0) is the length
- if state < table[subindex] then
+ var goal = parser_goto(index, subindex)
+ if state < goal then
high = middle - 1
- else if state > table[subindex] then
+ else if state > goal then
low = middle + 1
else
- return table[subindex + 1]
+ return parser_goto(index, subindex+1)
end
end
- return table[1] # Default value
+ return parser_goto(index, 2) # Default value
end
# Push someting in the state stack
end
var index = token.parser_index
- var table = _action_table[state]
- var action_type = table[1]
- var action_value = table[2]
+ var action_type = parser_action(state, 2)
+ var action_value = parser_action(state, 3)
var low = 1
- var high = table.length/3 - 1
+ var high = parser_action(state, 0) - 1
while low <= high do
var middle = (low + high) / 2
- var subindex = middle * 3
+ var subindex = middle * 3 + 1 # +1 because parser_action(state, 0) is the length
- if index < table[subindex] then
+ var goal = parser_action(state, subindex)
+ if index < goal then
high = middle - 1
- else if index > table[subindex] then
+ else if index > goal then
low = middle + 1
else
- action_type = table[subindex + 1]
- action_value = table[subindex + 2]
- high = low -1 # break
+ action_type = parser_action(state, subindex+1)
+ action_value = parser_action(state, subindex+2)
+ break
end
end
var node = new Start(null, node2)
return node
end
- if false then break # FIXME remove once unreach loop exits are in c_src
end
- abort # FIXME remove once unreach loop exits are in c_src
end
var _reduce_table: Array[ReduceAction]
do
_reduce_table = new Array[ReduceAction].with_items(
$ foreach {rules/rule}
- new ReduceAction@index[-sep ','-]
+ new ReduceAction@index(@leftside)[-sep ','-]
$ end foreach
)
end
# Each reduca action has its own class, this one is the root of the hierarchy.
private abstract class ReduceAction
fun action(p: Parser) is abstract
+ fun concat(l1, l2 : Array[Object]): Array[Object]
+ do
+ if l1.is_empty then return l2
+ l1.append(l2)
+ return l1
+ end
end
$ foreach {rules/rule}
end
$ end
$ when {@cmd='ADDLIST'}
-# if ${translate(@fromlist,"ABCDEFGHIJKLMNOPQRSTUVWXYZ","abcdefghijklmnopqrstuvwxyz")} != null then
- if ${translate(@tolist,"ABCDEFGHIJKLMNOPQRSTUVWXYZ","abcdefghijklmnopqrstuvwxyz")}.is_empty then
- ${translate(@tolist,"ABCDEFGHIJKLMNOPQRSTUVWXYZ","abcdefghijklmnopqrstuvwxyz")} = ${translate(@fromlist,"ABCDEFGHIJKLMNOPQRSTUVWXYZ","abcdefghijklmnopqrstuvwxyz")}
- else
- ${translate(@tolist,"ABCDEFGHIJKLMNOPQRSTUVWXYZ","abcdefghijklmnopqrstuvwxyz")}.append(${translate(@fromlist,"ABCDEFGHIJKLMNOPQRSTUVWXYZ","abcdefghijklmnopqrstuvwxyz")})
- end
-# end
+ ${translate(@tolist,"ABCDEFGHIJKLMNOPQRSTUVWXYZ","abcdefghijklmnopqrstuvwxyz")} = concat(${translate(@tolist,"ABCDEFGHIJKLMNOPQRSTUVWXYZ","abcdefghijklmnopqrstuvwxyz")}, ${translate(@fromlist,"ABCDEFGHIJKLMNOPQRSTUVWXYZ","abcdefghijklmnopqrstuvwxyz")})
$ end
$ when {@cmd='MAKELIST'}
var ${translate(@result,"ABCDEFGHIJKLMNOPQRSTUVWXYZ","abcdefghijklmnopqrstuvwxyz")} = new Array[Object]
$ end
$ end choose
$ end foreach
- p.push(p.go_to(@leftside), node_list)
+ p.push(p.go_to(_goto), node_list)
end
-init do end
+ var _goto: Int
+ init(g: Int) do _goto = g
end
$ end foreach
$ end template
-$ template make_parser_tables()
-# Parser that build a full AST
-abstract class ParserTable
- var _action_table: Array[Array[Int]]
- private fun build_action_table
- do
- _action_table = once [
+$ template make_parser_table()
$ foreach {parser_data/action_table/row}
- action_table_row${position()}[-sep ','-]
+static int parser_action_row${position()}[] = {
+ ${count(action)},
+$ foreach {action}
+ @from, @action, @to[-sep ','-]
+$ end foreach
+};
$ end foreach
- ]
- end
+const int* const parser_action_table[] = {
$ foreach {parser_data/action_table/row}
- private fun action_table_row${position()}: Array[Int]
- do
- return [
-$ foreach {action}
- @from, @action, @to[-sep ','-]
-$ end foreach
- ]
- end
+ parser_action_row${position()}[-sep ','-]
$ end foreach
+};
- var _goto_table: Array[Array[Int]]
- private fun build_goto_table
- do
- _goto_table = once [
$ foreach {parser_data/goto_table/row}
- [
+static int parser_goto_row${position()}[] = {
+ ${count(goto)},
$ foreach {goto}
- @from, @to[-sep ','-]
+ @from, @to[-sep ','-]
$ end foreach
- ][-sep ','-]
+};
$ end foreach
- ]
- end
- init do end
-end
+const int* const parser_goto_table[] = {
+$ foreach {parser_data/goto_table/row}
+ parser_goto_row${position()}[-sep ','-]
+$ end foreach
+};
$ end template