test page for metacircular PEG compiler-compiler
debug output
input grammar
sp <- ' ' / '\n' / '\t'. _ <- sp _ / . rule <- n: name _ '<-'_ body: choice '.'_ -> (["function parse_", n, "(input, pos) {\n", ' var state = { pos: pos };\n', ' var stack = [];\n', body, ' return state;\n', "}\n"].join('')) . sentence <- _ r: rule g: sentence -> (r + "\n" + g) / _ r: rule -> (r + "\n" + 'function parse_char(input, pos) {\n' + ' if (pos >= input.length) return null;\n' + ' return { pos: pos + 1, val: input.charAt(pos) };\n' + '}\n' + 'function literal(input, pos, string) {\n' + ' if (input.substr(pos, string.length) === string) {\n' + ' return { pos: pos + string.length, val: string };\n' + ' } else return null;\n' + '}\n' + "if (typeof exports !== 'undefined')\n" + " exports.parse_sentence = parse_sentence;\n" ). meta <- '!' / '\'' / '<-' / '/' / '.' / '(' / ')' / ':' / '->'. name <- c: namechar n: name -> (c + n) / namechar. namechar <- !meta !sp char. term <- labeled / nonterminal / string / negation / parenthesized. nonterminal <- n: name _ -> ([' state = parse_', n, '(input, state.pos);\n'].join('')) . labeled <- label: name _ ':'_ value: term -> ([value, ' if (state) var ', label, ' = state.val;\n'].join('')) . sequence <- foo: term bar: sequence -> ([foo, ' if (state) {\n', bar, ' }\n'].join('')) / result_expression / -> (''). string <- '\'' s: stringcontents '\''_ -> ([" state = literal(input, state.pos, '", s, "');\n"].join('')) . stringcontents <- !'\\' !'\'' c: char s: stringcontents -> (c + s) / b: '\\' c: char s: stringcontents -> (b + c + s) / -> (''). choice <- a: sequence '/'_ b: choice -> ([' stack.push(state);\n', a, ' if (!state) {\n', ' state = stack.pop();\n', b, ' } else stack.pop();\n'].join('')) / sequence. negation <- '!'_ t: term -> ([' stack.push(state);\n', t, ' if (state) {\n', ' stack.pop();\n', ' state = null;\n', ' } else state = stack.pop();\n'].join('')) . result_expression <- '->'_ result: expr _ -> ([' if (state) state.val = ', result, ';\n'].join('')) . expr <- '('_ e: exprcontents ')' -> ('(' + e + ')'). exprcontents <- c: (!'(' !')' char / expr) e: exprcontents -> (c + e) / -> (''). parenthesized <- '('_ body: choice ')'_ -> (body).
output compiler, first stage
go
output compiler, second stage
go
output compiler, third stage
go