Skip to content
Stephen Dolan edited this page May 5, 2013 · 33 revisions

This wiki exists to document the guts of jq, for the benefit of anyone who wants to contribute to the project.

If you want to learn to use jq, you should head to the website

Still here? Right, grab a shovel.

First and foremost, you should learn how the Docs and Tests work. Then, figure out how to

  • add a new [builtin](Built-in functions)
  • use jv, jq's internal JSON representation
  • understand how the interpreter works, and why
  • understand the compiler

If you have a shiny new jq feature to add, it is almost certainly better to add it as a builtin function than to add it as new syntax. Builtins have names and you can search the docs for them, syntax is generally difficult to make intuitive.

Plus, if you are adding a new builtin, you don't need to understand how the parser/compiler/interpreter fits together. If you can write your builtin in jq it's a one-line change (plus docs and tests). If it requires new functionality written in C, you'll need to figure out how to use jv first.

Source layout

Here's a rough map of the source (warning: this may go out of date quite quickly):

parser.h, parser.y, lexer.l

The parser for jq programs. Uses Flex and Bison.

jv_.c, jv_.h

The JSON library. The general API is in jv.h, while jv_aux.h has some higher-level operations which are implemented in terms of the ones in jv.h. For instance, jv.h contains jv_object_get and jv_array_get which look up references into objects (hashes) and array, while jv_aux.h contains jv_get which handles both arrays and objects, calling the appropriate function for each.

jv_parse.c and jv_print.c contain the JSON parser and printer, which jq uses to parse input and render output (these are different from the parser in parser.y, which is used to parse jq filters).

compile.h, bytecode.h, execute.h and others

The compiler lives in compile.c/compile.h. These functions are called by the parser to build an internal representation, which gets compiled into bytecode. The bytecode is passed to the interpreter, which lives in execute.h.

The interpreter has a supporting cast that handle various runtime aspects of jq, including forkable_stack.h (the guts of jq's stack, used to implement backtracking) and builtin.h (which defines built-in functions).

main.c

Handles command-line arguments and not much else.

Clone this wiki locally