mirror of
https://github.com/zap-proto/c.git
synced 2026-10-30 15:05:52 +00:00
C had no front end for the schema language at all. The compiler directory holds a code generator plugin, which is handed a request by another tool and never sees schema text, so a .zap file could not be read here in either form -- indentation or braces. zapgen reads it. Whitespace-significant source is rewritten into the brace form BEFORE the parser, exactly as the Go reference does it: a near identity that only adds the two tokens the brace grammar requires where the indented form leaves them out. A file already in braces comes back byte for byte, so one grammar reads both styles and neither is a dialect of the other. The identifier grammar is not restated. Its Unicode ranges are taken from Go's own tables by gen/table, so a name this parser accepts is a name the Go parser accepts, and a Go release that moves Unicode moves both. The generated header gives each struct a view over the message bytes and one reader per field at a fixed offset. Reading is in place and total: a field past the end reads zero, a pointer into the head or out of the message reads null. zap_view.h is the one place that says so. Checked against the Go front end on every .zap in the estate plus 55 adversarial cases and 15000 random ones: the brace form each writes is byte-identical, the layout each reads is field-for-field the same, and they accept and refuse the same files for the same stated reason. A message built by the Go runtime reads back through these bindings with every field equal.
34 lines
1.1 KiB
C
34 lines
1.1 KiB
C
/* SPDX-License-Identifier: BSD-3-Clause-Eco */
|
|
/*
|
|
* parse.h - read a .zap file into the shape it names.
|
|
*
|
|
* Whitespace-significant source is desugared into the canonical brace form
|
|
* first (see desugar.h); pure-brace source passes through that step
|
|
* byte for byte, so the brace grammar below never sees the difference.
|
|
*/
|
|
|
|
#ifndef ZAPGEN_PARSE_H
|
|
#define ZAPGEN_PARSE_H
|
|
|
|
#include "arena.h"
|
|
#include "schema.h"
|
|
|
|
#define ERRLEN 512
|
|
|
|
/* parse reads src (len bytes) as the contents of the file named name.
|
|
* Returns a zap_file on success, or NULL with err set. The result owns an
|
|
* arena; release it with file_free. */
|
|
struct zap_file *parse(const char *name, const char *src, size_t len,
|
|
char err[ERRLEN]);
|
|
|
|
void file_free(struct zap_file *f);
|
|
|
|
/* type_text parses one type expression on its own, in the arena a, with
|
|
* aliases resolved against the file f (which may be NULL). It is the one
|
|
* place a type is read, so a field's width is never sized by a second
|
|
* reading of the same text. */
|
|
int type_text(struct arena *a, const struct zap_file *f, const char *expr,
|
|
struct zap_type *out, char err[ERRLEN]);
|
|
|
|
#endif
|