llparse
Version:
Compile incremental parsers to C code
82 lines (69 loc) • 2.28 kB
text/typescript
import * as frontend from 'llparse-frontend';
import source = frontend.source;
export interface IHeaderBuilderOptions {
readonly prefix: string;
readonly headerGuard?: string;
readonly properties: ReadonlyArray<source.Property>;
readonly spans: ReadonlyArray<frontend.SpanField>;
}
export class HeaderBuilder {
public build(options: IHeaderBuilderOptions): string {
let res = '';
const PREFIX = options.prefix.toUpperCase().replace(/[^a-z]/gi, '_');
const DEFINE = options.headerGuard === undefined ?
`INCLUDE_${PREFIX}_H_` :
options.headerGuard;
res += `#ifndef ${DEFINE}\n`;
res += `#define ${DEFINE}\n`;
res += '#ifdef __cplusplus\n';
res += 'extern "C" {\n';
res += '#endif\n';
res += '\n';
res += '#include <stdint.h>\n';
res += '\n';
// Structure
res += `typedef struct ${options.prefix}_s ${options.prefix}_t;\n`;
res += `struct ${options.prefix}_s {\n`;
res += ' int32_t _index;\n';
for (const [ index, field ] of options.spans.entries()) {
res += ` void* _span_pos${index};\n`;
if (field.callbacks.length > 1) {
res += ` void* _span_cb${index};\n`;
}
}
res += ' int32_t error;\n';
res += ' const char* reason;\n';
res += ' const char* error_pos;\n';
res += ' void* data;\n';
res += ' void* _current;\n';
for (const prop of options.properties) {
let ty: string;
if (prop.ty === 'i8') {
ty = 'uint8_t';
} else if (prop.ty === 'i16') {
ty = 'uint16_t';
} else if (prop.ty === 'i32') {
ty = 'uint32_t';
} else if (prop.ty === 'i64') {
ty = 'uint64_t';
} else if (prop.ty === 'ptr') {
ty = 'void*';
} else {
throw new Error(
`Unknown state property type: "${prop.ty}"`);
}
res += ` ${ty} ${prop.name};\n`;
}
res += '};\n';
res += '\n';
res += `int ${options.prefix}_init(${options.prefix}_t* s);\n`;
res += `int ${options.prefix}_execute(${options.prefix}_t* s, ` +
'const char* p, const char* endp);\n';
res += '\n';
res += '#ifdef __cplusplus\n';
res += '} /* extern "C" */\n';
res += '#endif\n';
res += `#endif /* ${DEFINE} */\n`;
return res;
}
}