# Grammar Summary

This page is the "Grammar Summary" section of the Voxlang language reference. It is generated from LANGUAGE.md in the Voxlang compiler's own repository, so it says what the specification says and nothing more.

A URL is the heading, lowercased, with punctuation dropped and spaces turned into hyphens. Each "##" section of the spec is a page under /docs/, and every heading inside it is a fragment on that page, so "File I/O" is /docs/file-io/ and "Reading a whole file" inside it is /docs/file-io/#reading-a-whole-file.

As data: https://vox-lang.dev/docs/index.json lists every section and every heading with its URL, https://vox-lang.dev/docs/search.json carries one entry per heading with its first sentence and keywords, and https://vox-lang.dev/docs/anchors.json maps every slug to the page it lives on. Search is also a JSON endpoint: https://vox-lang.dev/docs/search?q=<words> returns ranked results as JSON, no page load.

Source: LANGUAGE.md at bf2cba0, 2026-08-22. https://github.com/Vox-lang/vox/blob/bf2cba037976586c30d22a48e7b7246d347f54a1/LANGUAGE.md

[Reference](https://vox-lang.dev/docs/) > Grammar Summary

```ebnf
program     ::= statement*
statement   ::= print_stmt | var_decl | assignment | if_stmt | while_stmt
              | for_stmt | func_def | thing_def | member_def | increment | decrement
              | break | continue | append_stmt

var_decl    ::= ("a" | "an") type "called" name "is" expr "."
              | ("Set" | "Create") "the"? type? "called"? name "to" expr "."

assignment  ::= "the" name "is" expr "."

append_stmt ::= "append" expr "to" name "."
              | "append" "each" name "from" expr ("treating" expr "as" expr)? "to" name "."

func_def    ::= "To" identifier (("with" | "of") params)? "." "Return" "a" type "," expr "."
params      ::= param ("and" param)*
param       ::= "a" type "called" name

func_call   ::= identifier ("of" | "with" | "to" | "on") args
args        ::= arg_clause ("and" arg_clause)*
arg_clause  ::= loop_expansion | expr

thing_def   ::= "A" "thing" "called" name "has" thing_entry ("," thing_entry)* "."
thing_entry ::= field_decl | member_decl
field_decl  ::= "a" type "called" name ("is" literal)?
member_decl ::= "a" "function" "called" name

member_def  ::= "To" "do" "the" name "'s" name (("," ("with" | "of"))? params)? "."
                body "Return" "a" name "," expr "."

if_stmt     ::= ("If" | "When") condition "then" "," block
                ("but if" condition "then" "," block)*
                ("otherwise" | "else")? ","? block? "."

while_stmt  ::= "While" condition "," block "."

for_stmt    ::= "For each" name "from" expr "to" expr "," block "."
              | "For each" name "in" expr "," block "."

print_stmt  ::= "Print" expr ("," "but if" condition "print" expr)* "."
              | "Print" "each" name "from" expr ("treating" expr "as" expr)?
                ("," "but if" condition "print" expr)* "."
              | "Print" identifier "of" "each" name "from" expr ("treating" expr "as" expr)?
                ("," "but if" condition "print" expr)* "."

loop_expansion ::= "each" name "from" expr ("treating" expr "as" expr)?

condition   ::= expr
expr        ::= or_expr
or_expr     ::= and_expr ("or" and_expr)*
and_expr    ::= not_expr ("and" not_expr)*
not_expr    ::= "not" not_expr | comparison
comparison  ::= additive (comp_op additive)?
additive    ::= multiplicative ((add | subtract) multiplicative)*
multiplicative ::= primary ((multiply | times | divide | modulo) primary)*
primary     ::= literal | identifier | func_call | "(" expr ")"

type        ::= "number" | "float" | "text" | "boolean" | "list"
              | "map" | "buffer" | "file" | "time" | "timer" | "value"
              | <user-defined thing name>   ; defined by `thing_def`
name        ::= identifier
identifier  ::= bare | quoted          ; see Naming Rules for the lexical rule
literal     ::= string | number | "true" | "false" | "nothing"
string      ::= '"' ... '"'            ; a string literal is data, never a name
```
