LRLA(1)パーサジェネーレータのDSLのアイディア
ふと思いついたので。
自分で実装する気はさらさらないけどね!
lhsとかrhsとかが邪魔だ。
Raccでこう書くところを、
program : { result = create_statement_list() } | stmt_list stmt_list : stmt { result = create_statement_list() result.add(val[0]) } | stmt_list stmt { result.add(val[1]) } stmt : expr | while_stmt | break_stmt | continue_stmt while_stmt : WHILE '(' expr ')' block { result = create_while_statement(val[2], val[4]) } break_stmt : BREAK { result = create_break_statement() } continue_stmt : CONTINUE { result = create_continue_statement() } block : '{' stmt_list '}' { result = val[1] } expr : '(' expr ')' { result = val[1] } | primary primary : INTEGER | STRING
こんな感じで…
rule{ lhs :program do rhs do create_statement_list() end rhs :stmt_list end lhs :stmt_list do rhs :stmt do |statement| list = create_statement_list() list.add(statement) list end rhs :stmt_list, :stmt do |list, statement| list.add(statement) list end end lhs :stmt do rhs :expr rhs :while_stmt rhs :break_stmt rhs :continue_stmt end lhs :while_stmt do rhs :WHILE, '(', :expr, ')', :block do |*val| cond, body = val[2], val[4] create_while_statement(cond, body) end end lhs :break_stmt do rhs :BREAK do create_break_statement() end end lhs :continue_stmt do rhs :CONTINUE do create_continue_statement() end end lhs :block do rhs '{', :stmt_list, '}' do |lb, body, rb| body end end lhs :expr do rhs '(', :expr, ')' do |lp, expr, rp| expr end rhs :primary end lhs :primary do rhs :INTEGER rhs :STRING end }