@@ -101,7 +101,11 @@ function generateCCode(ast) {
101101 }
102102 function makeFunctionBuilder ( varName , retType , argType ) {
103103 function n1 ( i , args ) { return varName + i + '(' + args . join ( ', ' ) + ')' ; }
104- function n2 ( v , i ) { return retType + ' ' + n1 ( i , v . params . map ( function ( p ) { return argType + ' ' + p ; } ) ) ; }
104+ function n2 ( v , i ) {
105+ var p = v . params . map ( function ( p ) { return argType + ' ' + p ; } ) ;
106+ p . unshift ( 'struct Context* context' ) ;
107+ return retType + ' ' + n1 ( i , p ) ;
108+ }
105109 var storage = [ ] ;
106110 return {
107111 add : function ( namespace , params , code , args ) {
@@ -112,6 +116,7 @@ function generateCCode(ast) {
112116 && f . body === code ;
113117 } ) ;
114118
119+ args . unshift ( 'ctx' ) ;
115120 return n1 ( index < 0 ? storage . push ( { namespace : namespace , params : params , body : code } ) - 1 : index , args ) ;
116121 } ,
117122
@@ -285,23 +290,73 @@ function generateCCode(ast) {
285290 ] ;
286291 var builder = new CodeBuilder ( code ) ;
287292 builder . pushAll ( literals . vars ( ) ) ;
288- builder . push ( '/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~*/' ) ;
293+ builder . push ( '/*~~~~~~~~~~~~~~~~~~~~ CHAR CLASSES ~~~~~~~~~~~~~~~~~~~~~*/' ) ;
289294 builder . pushAll ( charClasses . vars ( ) ) ;
290- builder . push ( '/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~*/' ) ;
295+ builder . push ( '/*~~~~~~~~~~~~~~~~ EXPECTED DEFINITIONS ~~~~~~~~~~~~~~~~~*/' ) ;
291296 builder . pushAll ( expected . vars ( ) ) ;
292- builder . push ( '/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~*/' ) ;
297+ builder . push ( '/*~~~~~~~~~~~~~~ RULE FORWARD DECLARATIONS ~~~~~~~~~~~~~~*/' ) ;
293298 builder . pushAll ( node . rules . map ( function ( r ) { return rDef ( r ) + ';' ; } ) ) ;
294- builder . push ( '/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~*/' ) ;
299+ builder . push ( '/*~~~~~~~~~~~~~~~~~~~~~ PREDICATES ~~~~~~~~~~~~~~~~~~~~~~*/' ) ;
295300 builder . pushAll ( predicates . defines ( ) ) ;
296- builder . push ( '/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~*/' ) ;
301+ builder . push ( '/*~~~~~~~~~~~~~~~~~~~~~~~ ACTIONS ~~~~~~~~~~~~~~~~~~~~~~~*/' ) ;
297302 builder . pushAll ( actions . defines ( ) ) ;
298- builder . push ( '/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~*/' ) ;
303+ builder . push ( '/*~~~~~~~~~~~~~~~~~~~~~~~~ RULES ~~~~~~~~~~~~~~~~~~~~~~~~*/' ) ;
299304 builder . pushAll ( rules ) ;
300305 builder . push ( '/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/' ) ;
301- builder . indent ( 'PARSER_API struct Result* parse(struct Range* input) {' ) ;
306+ builder . indent ( 'PARSER_API struct Result* parse(struct Range* input, struct Range* startRule, void* options ) {' ) ;
302307 // Создаем таблицу для поиска правил разбора по имени.
303308 builder . pushAll ( createLookupTable ( node . rules . map ( function ( r ) { return r . name ; } ) ) ) ;
309+ builder . push (
310+ 'struct Context ctx = {' ,
311+ ' { 0, 0 },' ,
312+ ' { 0, 1, 1 },' ,
313+ ' { 0, { 0, 1, 1 }, 0, 0 },' ,
314+ ' 0' ,
315+ '};' ,
316+ 'ctx.input.begin = input->begin;' ,
317+ 'ctx.input.end = input->end;' ,
318+ 'ctx.options = options;' ,
319+ 'if (startRule) {' ,
320+ ' const struct ParseFunc* func = findRule(funcs, sizeof(funcs) / sizeof(funcs[0]), startRule);' ,
321+ ' if (func == 0) { return 0; }' ,
322+ ' return (*func->func)(&ctx);' ,
323+ '}' ,
324+ 'return ' + ( node . rules . length > 0 ? ( r ( node . rules [ 0 ] . name ) + '(&ctx)' ) : '0' ) + ';'
325+ ) ;
304326 builder . dedent ( '}' ) ;
327+ builder . push (
328+ 'PARSER_API struct Result* parse2(const char* input, unsigned int len, struct Range* startRule, void* options) {' ,
329+ ' struct Range r;' ,
330+ ' r.begin = input;' ,
331+ ' r.end = input + len;' ,
332+ ' return parse(&r, startRule, options);' ,
333+ '}'
334+ ) ;
335+ builder . push (
336+ 'PARSER_API struct Result* parse3(struct Range* input, const char* startRule, unsigned int len, void* options) {' ,
337+ ' if (startRule) {' ,
338+ ' struct Range s;' ,
339+ ' s.begin = startRule;' ,
340+ ' s.end = startRule + len;' ,
341+ ' return parse(input, &s, options);' ,
342+ ' }' ,
343+ ' return parse(input, 0, options);' ,
344+ '}'
345+ ) ;
346+ builder . push (
347+ 'PARSER_API struct Result* parse4(const char* input, unsigned int inputLen, const char* startRule, unsigned int startRuleLen, void* options) {' ,
348+ ' struct Range r;' ,
349+ ' r.begin = input;' ,
350+ ' r.end = input + inputLen;' ,
351+ ' if (startRule) {' ,
352+ ' struct Range s;' ,
353+ ' s.begin = startRule;' ,
354+ ' s.end = startRule + startRuleLen;' ,
355+ ' return parse(&r, &s, options);' ,
356+ ' }' ,
357+ ' return parse(&r, 0, options);' ,
358+ '}'
359+ ) ;
305360
306361 code . push (
307362 '#undef length' ,
0 commit comments