Skip to content

RFC: Schema parser #45

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Jan 9, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 26 additions & 6 deletions GraphQLParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,36 +20,56 @@ namespace graphql {

// Given properly-configured yylex, run the parser and return the
// result.
static std::unique_ptr<ast::Node> doParse(const char **outError, yyscan_t scanner) {
static std::unique_ptr<ast::Node> doParse(const char **outError, yyscan_t scanner, bool enableSchema) {
Node *outAST;
yy::GraphQLParserImpl parser(&outAST, outError, scanner);
yy::GraphQLParserImpl parser(enableSchema, &outAST, outError, scanner);
int failure = parser.parse();
return !failure ? std::unique_ptr<ast::Node>(outAST) : nullptr;
}

std::unique_ptr<ast::Node> parseString(const char *text, const char **error) {
static std::unique_ptr<ast::Node> parseStringImpl(const char *text, const char **error, bool enableSchema) {
yyscan_t scanner;
struct LexerExtra extra;
yylex_init_extra(&extra, &scanner);
YY_BUFFER_STATE buffer = yy_scan_string(text, scanner);
yy_switch_to_buffer(buffer, scanner);

auto result = doParse(error, scanner);
auto result = doParse(error, scanner, enableSchema);
yylex_destroy(scanner);
return result;
}

std::unique_ptr<ast::Node> parseFile(FILE *file, const char **error) {
std::unique_ptr<ast::Node> parseString(const char *text, const char **error) {
return parseStringImpl(text, error, false);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: it's hard to guess what is the meaning of the boolean without reading a type signature of parseStringImpl, so it's usually a good practice to leave a comment /* enableSchema */ right next to a parameter.

}

std::unique_ptr<ast::Node> parseStringWithExperimentalSchemaSupport(
const char *text, const char **error) {
return parseStringImpl(text, error, true);
}

static std::unique_ptr<ast::Node> parseFileImpl(
FILE *file, const char **error, bool enableSchema) {
yyscan_t scanner;
struct LexerExtra extra;
yylex_init_extra(&extra, &scanner);
yyset_in(file, scanner);

auto result = doParse(error, scanner);
auto result = doParse(error, scanner, enableSchema);
yylex_destroy(scanner);

return result;
}

std::unique_ptr<ast::Node> parseFile(FILE *file, const char **error) {
return parseFileImpl(file, error, false);
}

std::unique_ptr<ast::Node> parseFileWithExperimentalSchemaSupport(
FILE *file, const char **error) {
return parseFileImpl(file, error, true);
}


}
}
14 changes: 14 additions & 0 deletions GraphQLParser.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,26 @@ namespace ast {
*/
std::unique_ptr<ast::Node> parseString(const char *text, const char **error);

/**
* Like parseString, but enables support for the experimental type
* definition syntax from https://github.com/facebook/graphql/pull/90 .
*/
std::unique_ptr<ast::Node> parseStringWithExperimentalSchemaSupport(
const char *text, const char **error);

/**
* Read and parse GraphQL source from the given file, returning an
* AST. Returns nullptr on error and, if error is not null, places an
* error string in error that must be freed with free(3).
*/
std::unique_ptr<ast::Node> parseFile(FILE *file, const char **error);

/**
* Like parseFile, but enables support for the experimental type
* definition syntax from https://github.com/facebook/graphql/pull/90 .
*/
std::unique_ptr<ast::Node> parseFileWithExperimentalSchemaSupport(
FILE *file, const char **error);

}
}
77 changes: 76 additions & 1 deletion ast/ast.ast
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,23 @@
# O for option in a union.
# Scalar type ontology: string, boolean

# Location tracking for Identifier is probably useful for error messages.
# Definitions other than OperationDefinition and FragmentDefinition
# are experimental additions for schema parsing. (We don't support
# nested unions in the AST mini-language, so I've flattened and elided
# TypeSystemDefinition and TypeDefinition.)
U Definition
O OperationDefinition
O FragmentDefinition
O SchemaDefinition
O ScalarTypeDefinition
O ObjectTypeDefinition
O InterfaceTypeDefinition
O UnionTypeDefinition
O EnumTypeDefinition
O InputObjectTypeDefinition
O TypeExtensionDefinition
O DirectiveDefinition


T Document
P Definition definitions
Expand Down Expand Up @@ -124,3 +137,65 @@ S Type type

T Name
S string value

T SchemaDefinition
P? Directive directives
P OperationTypeDefinition operationTypes

T OperationTypeDefinition
S OperationKind operation
S NamedType type

T ScalarTypeDefinition
S Name name
P? Directive directives

T ObjectTypeDefinition
S Name name
P? NamedType interfaces
P? Directive directives
P FieldDefinition fields

T FieldDefinition
S Name name
P? InputValueDefinition arguments
S Type type
P? Directive directives

T InputValueDefinition
S Name name
S Type type
S? Value defaultValue
P? Directive directives

T InterfaceTypeDefinition
S Name name
P? Directive directives
P FieldDefinition fields

T UnionTypeDefinition
S Name name
P? Directive directives
P NamedType types

T EnumTypeDefinition
S Name name
P? Directive directives
P EnumValueDefinition values

T EnumValueDefinition
S Name name
P? Directive directives

T InputObjectTypeDefinition
S Name name
P? Directive directives
P InputValueDefinition fields

T TypeExtensionDefinition
S ObjectTypeDefinition definition

T DirectiveDefinition
S Name name
P? InputValueDefinition arguments
P Name locations
11 changes: 11 additions & 0 deletions c/GraphQLParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,21 @@ struct GraphQLAstNode *graphql_parse_string(const char *text, const char **error
return (struct GraphQLAstNode *)facebook::graphql::parseString(text, error).release();
}

struct GraphQLAstNode *graphql_parse_string_with_experimental_schema_support(
const char *text, const char **error) {
return (struct GraphQLAstNode *)facebook::graphql::parseStringWithExperimentalSchemaSupport(
text, error).release();
}

struct GraphQLAstNode *graphql_parse_file(FILE *file, const char **error) {
return (struct GraphQLAstNode *)facebook::graphql::parseFile(file, error).release();
}

struct GraphQLAstNode *graphql_parse_file_with_experimental_schema_support(
FILE *file, const char **error) {
return (struct GraphQLAstNode *)facebook::graphql::parseFileWithExperimentalSchemaSupport(file, error).release();
}

void graphql_error_free(const char *error) {
std::free((void *)error);
}
10 changes: 8 additions & 2 deletions c/GraphQLParser.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,11 @@ struct GraphQLAstNode;
* error message is placed in error and must be freed with
* graphql_error_free().
*/
struct GraphQLAstNode *graphql_parse_string(const char *text,
const char **error);
struct GraphQLAstNode *graphql_parse_string(
const char *text, const char **error);

struct GraphQLAstNode *graphql_parse_string_with_experimental_schema_support(
const char *text, const char **error);

/**
* Read and parse GraphQL source from the given file, returning an
Expand All @@ -40,6 +43,9 @@ struct GraphQLAstNode *graphql_parse_string(const char *text,
*/
struct GraphQLAstNode *graphql_parse_file(FILE *file, const char **error);

struct GraphQLAstNode *graphql_parse_file_with_experimental_schema_support(
FILE *file, const char **error);

/**
* Frees an error.
*/
Expand Down
Loading