Provided by: peg_0.1.15-1_amd64 bug

NAME

       peg, leg - parser generators

SYNOPSIS

       peg [-hvV -ooutput] [filename ...]
       leg [-hvV -ooutput] [filename ...]

DESCRIPTION

       peg and leg are tools for generating recursive-descent parsers: programs that perform pattern matching on
       text.   They  process a Parsing Expression Grammar (PEG) [Ford 2004] to produce a program that recognises
       legal sentences of that grammar.  peg processes PEGs written using the original syntax described by Ford;
       leg processes PEGs written using slightly different syntax and conventions that are intended to  make  it
       an  attractive  replacement  for parsers built with lex(1) and yacc(1).  Unlike lex and yacc, peg and leg
       support unlimited backtracking, provide ordered choice as a means for  disambiguation,  and  can  combine
       scanning (lexical analysis) and parsing (syntactic analysis) into a single activity.

       peg  reads the specified filenames, or standard input if no filenames are given, for a grammar describing
       the parser to generate.  peg then generates a C source file that defines a function  yyparse().   This  C
       source file can be included in, or compiled and then linked with, a client program.  Each time the client
       program  calls yyparse() the parser consumes input text according to the parsing rules, starting from the
       first rule in the grammar.  yyparse() returns non-zero if the input could  be  parsed  according  to  the
       grammar; it returns zero if the input could not be parsed.

       The  prefix 'yy' or 'YY' is prepended to all externally-visible symbols in the generated parser.  This is
       intended to reduce the risk  of  namespace  pollution  in  client  programs.   (The  choice  of  'yy'  is
       historical; see lex(1) and yacc(1), for example.)

OPTIONS

       peg and leg provide the following options:

       -h     prints a summary of available options and then exits.

       -ooutput
              writes the generated parser to the file output instead of the standard output.

       -v     writes verbose information to standard error while working.

       -V     writes version information to standard error then exits.

A SIMPLE EXAMPLE

       The  following  peg  input specifies a grammar with a single rule (called 'start') that is satisfied when
       the input contains the string "username".

           start <- "username"

       (The quotation marks are not part of the matched text; they serve to indicate  a  literal  string  to  be
       matched.)   In  other  words,  yyparse()  in the generated C source will return non-zero only if the next
       eight characters read from the input spell the word "username".  If the  input  contains  anything  else,
       yyparse()  returns  zero  and no input will have been consumed.  (Subsequent calls to yyparse() will also
       return zero, since the parser is effectively blocked looking  for  the  string  "username".)   To  ensure
       progress  we  can  add  an alternative clause to the 'start' rule that will match any single character if
       "username" is not found.

           start <- "username"
                  / .

       yyparse() now always returns non-zero (except at the very end of the input).  To do something  useful  we
       can add actions to the rules.  These actions are performed after a complete match is found (starting from
       the  first  rule)  and  are  chosen according to the 'path' taken through the grammar to match the input.
       (Linguists would call this path a 'phrase marker'.)

           start <- "username"    { printf("%s\n", getlogin()); }
                  / < . >         { putchar(yytext[0]); }

       The first line instructs the parser to print the user's login name whenever it  sees  "username"  in  the
       input.  If that match fails, the second line tells the parser to echo the next character on the input the
       standard  output.   Our  parser  is  now  performing  useful  work: it will copy the input to the output,
       replacing all occurrences of "username" with the user's account name.

       Note the angle brackets ('<' and '>') that were added to the second alternative.  These have no effect on
       the meaning of the rule, but serve to delimit the text made available to  the  following  action  in  the
       variable yytext.

       If the above grammar is placed in the file username.peg, running the command

           peg -o username.c username.peg

       will  save  the  corresponding  parser  in the file username.c.  To create a complete program this parser
       could be included by a C program as follows.

           #include <stdio.h>      /* printf(), putchar() */
           #include <unistd.h>     /* getlogin() */

           #include "username.c"   /* yyparse() */

           int main()
           {
             while (yyparse())     /* repeat until EOF */
               ;
             return 0;
           }

PEG GRAMMARS

       A grammar consists of a set of named rules.

           name <- pattern

       The pattern contains one or more of the following elements.

       name   The element stands for the entire pattern in the rule with the given name.

       "characters"
              A character or string enclosed in double quotes is matched literally.  The ANSI C escape sequences
              are recognised within the characters.

       'characters'
              A character or string enclosed in single quotes is matched literally, as above.

       [characters]
              A set of characters enclosed in square brackets matches any single character from  the  set,  with
              escape  characters  recognised  as  above.   If the set begins with an uparrow (^) then the set is
              negated (the element matches any character not in the set).  Any pair of characters separated with
              a dash (-) represents the range of characters from the first to the second, inclusive.   A  single
              alphabetic character or underscore is matched by the following set.

                  [a-zA-Z_]

              Similarly, the following matches  any single non-digit character.

                  [^0-9]

       .      A  dot  matches  any  character.   Note that the only time this fails is at the end of file, where
              there is no character to match.

       ( pattern )
              Parentheses are used for grouping (modifying the precedence of the operators described below).

       { action }
              Curly braces surround actions.  The action is arbitrary C source code to be executed at the end of
              matching.  Any braces within the action must be properly nested.  Any input text that was  matched
              before  the action and delimited by angle brackets (see below) is made available within the action
              as the contents of the character array yytext.  The length of (number of characters in) yytext  is
              available in the variable yyleng.  (These variable names are historical; see lex(1).)

       <      An  opening  angle  bracket  always  matches  (consuming  no input) and causes the parser to begin
              accumulating matched text.  This text will be made available to actions in the variable yytext.

       >      A closing angle bracket always matches  (consuming  no  input)  and  causes  the  parser  to  stop
              accumulating text for yytext.

       The above elements can be made optional and/or repeatable with the following suffixes:

       element ?
              The  element is optional.  If present on the input, it is consumed and the match succeeds.  If not
              present on the input, no text is consumed and the match succeeds anyway.

       element +
              The element is repeatable.  If present on the input,  one  or  more  occurrences  of  element  are
              consumed and the match succeeds.  If no occurrences of element are present on the input, the match
              fails.

       element *
              The  element  is  optional  and  repeatable.   If present on the input, one or more occurrences of
              element are consumed and the match succeeds.  If no occurrences of  element  are  present  on  the
              input, the match succeeds anyway.

       The  above  elements  and  suffixes can be converted into predicates (that match arbitrary input text and
       subsequently succeed or fail without consuming that input) with the following prefixes:

       & element
              The predicate succeeds only if element can be matched.  Input text scanned while matching  element
              is not consumed from the input and remains available for subsequent matching.

       ! element
              The  predicate  succeeds  only  if  element  cannot be matched.  Input text scanned while matching
              element is not consumed from the input and remains available for subsequent matching.   A  popular
              idiom is

                  !.

              which matches the end of file, after the last character of the input has already been consumed.

       A special form of the '&' predicate is provided:

       &{ expression }
              In this predicate the simple C expression (not statement) is evaluated immediately when the parser
              reaches  the  predicate.   If  the  expression yields non-zero (true) the 'match' succeeds and the
              parser continues with the next element in the pattern.  If the expression yields zero (false)  the
              'match' fails and the parser backs up to look for an alternative parse of the input.

       Several  elements (with or without prefixes and suffixes) can be combined into a sequence by writing them
       one after the other.  The entire sequence matches only if each individual element within it matches, from
       left to right.

       Sequences can be separated into disjoint alternatives by the alternation operator '/'.

       sequence-1 / sequence-2 / ... / sequence-N
              Each sequence is tried in turn until one of them matches, at which time matching for  the  overall
              pattern succeeds.  If none of the sequences matches then the match of the overall pattern fails.

       Finally, the pound sign (#) introduces a comment (discarded) that continues until the end of the line.

       To  summarise  the above, the parser tries to match the input text against a pattern containing literals,
       names (representing other rules), and various operators (written as prefixes, suffixes, juxtaposition for
       sequencing and and infix alternation operator) that modify  how  the  elements  within  the  pattern  are
       matched.  Matches are made from left to right, 'descending' into named sub-rules as they are encountered.
       If  the  matching  process  fails,  the  parser 'back tracks' ('rewinding' the input appropriately in the
       process) to find the nearest alternative 'path' through the grammar.  In other words the parser  performs
       a  depth-first,  left-to-right  search  for  the  first successfully-matching path through the rules.  If
       found, the actions along the successful path are executed (in the order they were encountered).

       Note that predicates are evaluated immediately during the search  for  a  successful  match,  since  they
       contribute  to  the  success  or  failure  of  the  search.  Actions, however, are evaluated only after a
       successful match has been found.

PEG GRAMMAR FOR PEG GRAMMARS

       The grammar for peg grammars is  shown  below.   This  will  both  illustrate  and  formalise  the  above
       description.

           Grammar         <- Spacing Definition+ EndOfFile

           Definition      <- Identifier LEFTARROW Expression
           Expression      <- Sequence ( SLASH Sequence )*
           Sequence        <- Prefix*
           Prefix          <- AND Action
                            / ( AND | NOT )? Suffix
           Suffix          <- Primary ( QUERY / STAR / PLUS )?
           Primary         <- Identifier !LEFTARROW
                            / OPEN Expression CLOSE
                            / Literal
                            / Class
                            / DOT
                            / Action
                            / BEGIN
                            / END

           Identifier      <- < IdentStart IdentCont* > Spacing
           IdentStart      <- [a-zA-Z_]
           IdentCont       <- IdentStart / [0-9]
           Literal         <- ['] < ( !['] Char  )* > ['] Spacing
                            / ["] < ( !["] Char  )* > ["] Spacing
           Class           <- '[' < ( !']' Range )* > ']' Spacing
           Range           <- Char '-' Char / Char
           Char            <- '\\' [abefnrtv'"\[\]\\]
                            / '\\' [0-3][0-7][0-7]
                            / '\\' [0-7][0-7]?
                            / '\\' '-'
                            / !'\\' .
           LEFTARROW       <- '<-' Spacing
           SLASH           <- '/' Spacing
           AND             <- '&' Spacing
           NOT             <- '!' Spacing
           QUERY           <- '?' Spacing
           STAR            <- '*' Spacing
           PLUS            <- '+' Spacing
           OPEN            <- '(' Spacing
           CLOSE           <- ')' Spacing
           DOT             <- '.' Spacing
           Spacing         <- ( Space / Comment )*
           Comment         <- '#' ( !EndOfLine . )* EndOfLine
           Space           <- ' ' / '\t' / EndOfLine
           EndOfLine       <- '\r\n' / '\n' / '\r'
           EndOfFile       <- !.
           Action          <- '{' < [^}]* > '}' Spacing
           BEGIN           <- '<' Spacing
           END             <- '>' Spacing

LEG GRAMMARS

       leg  is  a  variant  of  peg  that  adds some features of lex(1) and yacc(1).  It differs from peg in the
       following ways.

       %{ text... %}
              A declaration section can appear anywhere that a rule definition is expected.   The  text  between
              the  delimiters  '%{'  and  '%}' is copied verbatim to the generated C parser code before the code
              that implements the parser itself.

       name = pattern
              The 'assignment' operator replaces the left arrow operator '<-'.

       rule-name
              Hyphens can appear as letters in the names of rules.  Each hyphen is converted into an  underscore
              in the generated C source code.  A single single hyphen '-' is a legal rule name.

                  -       = [ \t\n\r]*
                  number  = [0-9]+                 -
                  name    = [a-zA-Z_][a-zA_Z_0-9]* -
                  l-paren = '('                    -
                  r-paren = ')'                    -

              This  example  shows  how  ignored  whitespace  can  be  obvious  when reading the grammar and yet
              unobtrusive when placed liberally at the end of every rule associated with a lexical element.

       seq-1 | seq-2
              The alternation operator is vertical bar '|' rather than forward slash '/'.  The peg rule

                  name <- sequence-1
                        / sequence-2
                        / sequence-3

              is therefore written

                  name = sequence-1
                       | sequence-2
                       | sequence-3
                       ;

              in leg (with the final semicolon being optional, as described next).

       exp ~ { action }
              A postfix operator ~{ action } can be placed after any expression and will behave  like  a  normal
              action  (arbitrary  C  code) except that it is invoked only when exp fails.  It binds less tightly
              than any other operator except alternation and sequencing, and is intended to make error  handling
              and  recovery  code  easier  to write.  Note that yytext and yyleng are not available inside these
              actions, but the pointer variable yy is available to give the  code  access  to  any  user-defined
              members  of the parser state (see "CUSTOMISING THE PARSER" below).  Note also that exp is always a
              single expression; to invoke an error action for any failure within a sequence,  parentheses  must
              be used to group the sequence into a single expression.

                  rule = e1 e2 e3 ~{ error("e[12] ok; e3 has failed"); }
                       | ...

                  rule = (e1 e2 e3) ~{ error("one of e[123] has failed"); }
                       | ...

       pattern ;
              A semicolon punctuator can optionally terminate a pattern.

       %% text...
              A  double  percent  '%%' terminates the rules (and declarations) section of the grammar.  All text
              following '%%' is copied verbatim to the generated C parser code after the  parser  implementation
              code.

       $$ = value
              A sub-rule can return a semantic value from an action by assigning it to the pseudo-variable '$$'.
              All  semantic  values must have the same type (which defaults to 'int').  This type can be changed
              by defining YYSTYPE in a declaration section.

       identifier:name
              The semantic value returned (by assigning to '$$') from the sub-rule name is associated  with  the
              identifier and can be referred to in subsequent actions.

       The desk calculator example below illustrates the use of '$$' and ':'.

LEG EXAMPLE: A DESK CALCULATOR

       The  extensions  in  leg  described  above  allow  useful parsers and evaluators (including declarations,
       grammar rules, and supporting C functions such as 'main') to be kept within a  single  source  file.   To
       illustrate  this  we  show  a  simple desk calculator supporting the four common arithmetic operators and
       named variables.  The intermediate results of arithmetic evaluation will be accumulated  on  an  implicit
       stack by returning them as semantic values from sub-rules.

           %{
           #include <stdio.h>     /* printf() */
           #include <stdlib.h>    /* atoi() */
           int vars[26];
           %}

           Stmt    = - e:Expr EOL                  { printf("%d\n", e); }
                   | ( !EOL . )* EOL               { printf("error\n"); }

           Expr    = i:ID ASSIGN s:Sum             { $$ = vars[i] = s; }
                   | s:Sum                         { $$ = s; }

           Sum     = l:Product
                           ( PLUS  r:Product       { l += r; }
                           | MINUS r:Product       { l -= r; }
                           )*                      { $$ = l; }

           Product = l:Value
                           ( TIMES  r:Value        { l *= r; }
                           | DIVIDE r:Value        { l /= r; }
                           )*                      { $$ = l; }

           Value   = i:NUMBER                      { $$ = atoi(yytext); }
                   | i:ID !ASSIGN                  { $$ = vars[i]; }
                   | OPEN i:Expr CLOSE             { $$ = i; }

           NUMBER  = < [0-9]+ >    -               { $$ = atoi(yytext); }
           ID      = < [a-z]  >    -               { $$ = yytext[0] - 'a'; }
           ASSIGN  = '='           -
           PLUS    = '+'           -
           MINUS   = '-'           -
           TIMES   = '*'           -
           DIVIDE  = '/'           -
           OPEN    = '('           -
           CLOSE   = ')'           -

           -       = [ \t]*
           EOL     = '\n' | '\r\n' | '\r' | ';'

           %%

           int main()
           {
             while (yyparse())
               ;
             return 0;
           }

LEG GRAMMAR FOR LEG GRAMMARS

       The  grammar  for  leg  grammars  is  shown  below.   This  will  both illustrate and formalise the above
       description.

           grammar =       -
                           ( declaration | definition )+
                           trailer? end-of-file

           declaration =   '%{' < ( !'%}' . )* > RPERCENT

           trailer =       '%%' < .* >

           definition =    identifier EQUAL expression SEMICOLON?

           expression =    sequence ( BAR sequence )*

           sequence =      error+

           error =         prefix ( TILDE action )?

           prefix =        AND action
           |               ( AND | NOT )? suffix

           suffix =        primary ( QUERY | STAR | PLUS )?

           primary =       identifier COLON identifier !EQUAL
           |               identifier !EQUAL
           |               OPEN expression CLOSE
           |               literal
           |               class
           |               DOT
           |               action
           |               BEGIN
           |               END

           identifier =    < [-a-zA-Z_][-a-zA-Z_0-9]* > -

           literal =       ['] < ( !['] char )* > ['] -
           |               ["] < ( !["] char )* > ["] -

           class =         '[' < ( !']' range )* > ']' -

           range =         char '-' char | char

           char =          '\\' [abefnrtv'"\[\]\\]
           |               '\\' [0-3][0-7][0-7]
           |               '\\' [0-7][0-7]?
           |               !'\\' .

           action =        '{' < braces* > '}' -

           braces =        '{' braces* '}'
           |               !'}' .

           EQUAL =         '=' -
           COLON =         ':' -
           SEMICOLON =     ';' -
           BAR =           '|' -
           AND =           '&' -
           NOT =           '!' -
           QUERY =         '?' -
           STAR =          '*' -
           PLUS =          '+' -
           OPEN =          '(' -
           CLOSE =         ')' -
           DOT =           '.' -
           BEGIN =         '<' -
           END =           '>' -
           TILDE =         '~' -
           RPERCENT =      '%}' -

           - =             ( space | comment )*
           space =         ' ' | '\t' | end-of-line
           comment =       '#' ( !end-of-line . )* end-of-line
           end-of-line =   '\r\n' | '\n' | '\r'
           end-of-file =   !.

CUSTOMISING THE PARSER

       The following symbols can be redefined in declaration sections to modify the generated parser code.

       YYSTYPE
              The semantic value type.  The pseudo-variable '$$' and the identifiers  'bound'  to  rule  results
              with  the  colon  operator  ':' should all be considered as being declared to have this type.  The
              default value is 'int'.

       YYPARSE
              The name of the main entry point to the parser.  The default value is 'yyparse'.

       YYPARSEFROM
              The name of an alternative entry point to the parser.  This function  expects  one  argument:  the
              function corresponding to the rule from which the search for a match should begin.  The default is
              'yyparsefrom'.  Note that yyparse() is defined as

                  int yyparse() { return yyparsefrom(yy_foo); }

              where 'foo' is the name of the first rule in the grammar.

       YY_INPUT(buf, result, max_size)
              This  macro  is  invoked by the parser to obtain more input text.  buf points to an area of memory
              that can hold at most max_size characters.  The macro should copy  input  text  to  buf  and  then
              assign  the integer variable result to indicate the number of characters copied.  If no more input
              is available, the macro should assign 0 to result.  By default, the YY_INPUT macro is  defined  as
              follows.

                  #define YY_INPUT(buf, result, max_size)        \
                  {                                              \
                    int yyc= getchar();                          \
                    result= (EOF == yyc) ? 0 : (*(buf)= yyc, 1); \
                  }

              Note that if YY_CTX_LOCAL is defined (see below) then an additional first argument, containing the
              parser context, is passed to YY_INPUT.

       YY_DEBUG
              If  this  symbols  is defined then additional code will be included in the parser that prints vast
              quantities of arcane information to the standard error while the parser is running.

       YY_BEGIN
              This macro is invoked to mark the start of input text that will be made available  in  actions  as
              'yytext'.   This  corresponds  to  occurrences  of  '<'  in the grammar.  These are converted into
              predicates that are expected to succeed.  The default definition

                  #define YY_BEGIN (yybegin= yypos, 1)

              therefore saves the current input position and returns 1 ('true') as the result of the predicate.

       YY_END This macros corresponds to '>' in the grammar.  Again, it is a predicate so the default definition
              saves the input position before 'succeeding'.

                  #define YY_END (yyend= yypos, 1)

       YY_PARSE(T)
              This macro declares the parser entry points (yyparse and  yyparsefrom)  to  be  of  type  T.   The
              default definition

                  #define YY_PARSE(T) T

              leaves  yyparse()  and  yyparsefrom()  with  global  visibility.  If they should not be externally
              visible in other source files, this macro can be redefined to declare them 'static'.

                  #define YY_PARSE(T) static T

       YY_CTX_LOCAL
              If this symbol is defined during compilation of a generated parser then global parser  state  will
              be kept in a structure of type 'yycontext' which can be declared as a local variable.  This allows
              multiple  instances  of  parsers to coexist and to be thread-safe.  The parsing function yyparse()
              will be declared to expect a first argument of type 'yycontext *', an instance  of  the  structure
              holding  the global state for the parser.  This instance must be allocated and initialised to zero
              by the client.  A trivial but complete example is as follows.

                  #include <stdio.h>

                  #define YY_CTX_LOCAL

                  #include "the-generated-parser.peg.c"

                  int main()
                  {
                    yycontext ctx;
                    memset(&ctx, 0, sizeof(yycontext));
                    while (yyparse(&ctx));
                    return 0;
                  }

              Note that if this symbol is undefined then the compiled parser will statically allocate its global
              state and will be neither  reentrant  nor  thread-safe.   Note  also  that  the  parser  yycontext
              structure  is  initialised  automatically  the first time yyparse() is called; this structure must
              therefore be properly initialised to zero before the first call to yyparse().

       YY_CTX_MEMBERS
              If YY_CTX_LOCAL is defined (see above) then the macro YY_CTX_MEMBERS can be defined to  expand  to
              any additional member field declarations that the client would like included in the declaration of
              the  'yycontext'  structure type.  These additional members are otherwise ignored by the generated
              parser.  The instance of 'yycontext' associated with  the  currently-active  parser  is  available
              within actions as the pointer variable yy.

       YY_BUFFER_SIZE
              The initial size of the text buffer, in bytes.  The default is 1024 and the buffer size is doubled
              whenever required to meet demand during parsing.  An application that typically parses much longer
              strings could increase this to avoid unnecessary buffer reallocation.

       YY_STACK_SIZE
              The initial size of the variable and action stacks.  The default is 128, which is doubled whenever
              required  to  meet demand during parsing.  Applications that have deep call stacks with many local
              variables, or that perform many actions after a single successful match, could  increase  this  to
              avoid unnecessary buffer reallocation.

       YY_MALLOC(YY, SIZE)
              The  memory  allocator  for  all parser-related storage.  The parameters are the current yycontext
              structure and the number of bytes to allocate.  The default definition is: malloc(SIZE)

       YY_REALLOC(YY, PTR, SIZE)
              The memory reallocator for dynamically-grown storage (such as text buffers and  variable  stacks).
              The  parameters  are  the  current  yycontext structure, the previously-allocated storage, and the
              number  of  bytes  to  which  that  storage  should  be  grown.   The   default   definition   is:
              realloc(PTR, SIZE)

       YY_FREE(YY, PTR)
              The  memory  deallocator.   The  parameters are the current yycontext structure and the storage to
              deallocate.  The default definition is: free(PTR)

       YYRELEASE
              The name of the function that releases all resources held by a yycontext structure.   The  default
              value is 'yyrelease'.

       The following variables can be referred to within actions.

       char *yybuf
              This  variable  points to the parser's input buffer used to store input text that has not yet been
              matched.

       int yypos
              This is the offset (in yybuf) of the next character to be matched and consumed.

       char *yytext
              The most recent matched text delimited by '<' and '>' is stored in this variable.

       int yyleng
              This variable indicates the number of characters in 'yytext'.

       yycontext *yy
              This variable points to the instance of 'yycontext' associated with the currently-active parser.

       Programs that wish to release all the resources associated with a parser can use the following function.

       yyrelease(yycontext*yy)
              Returns all parser-allocated storage associated with yy  to  the  system.   The  storage  will  be
              reallocated on the next call to yyparse().

       Note that the storage for the yycontext structure itself is never allocated or reclaimed implicitly.  The
       application  must  allocate  these  structures in automatic storage, or use calloc() and free() to manage
       them explicitly.  The example in the following section demonstrates one approach to resource management.

LEG EXAMPLE: EXTENDING THE PARSER'S CONTEXT

       The yy variable passed to actions contains the state of the parser plus any additional fields defined  by
       YY_CTX_MEMBERS.   Theses fields can be used to store application-specific information that is global to a
       particular call of yyparse().  A trivial  but  complete  leg  example  follows  in  which  the  yycontext
       structure  is  extended  with  a  count of the number of newline characters seen in the input so far (the
       grammar otherwise consumes and ignores the entire input).  The caller of yyparse() uses  count  to  print
       the number of lines of input that were read.

           %{
           #define YY_CTX_LOCAL 1
           #define YY_CTX_MEMBERS \
             int count;
           %}

           Char    = ('\n' | '\r\n' | '\r')        { yy->count++ }
                   | .

           %%

           #include <stdio.h>
           #include <string.h>

           int main()
           {
               /* create a local parser context in automatic storage */
               yycontext yy;
               /* the context *must* be initialised to zero before first use*/
               memset(&yy, 0, sizeof(yy));

               while (yyparse(&yy))
                   ;
               printf("%d newlines\n", yy.count);

               /* release all resources associated with the context */
               yyrelease(&yy);

               return 0;
           }

DIAGNOSTICS

       peg and leg warn about the following conditions while converting a grammar into a parser.

       syntax error
              The  input grammar was malformed in some way.  The error message will include the text about to be
              matched (often backed up a huge amount from the actual location of the error) and the line  number
              of the most recently considered character (which is often the real location of the problem).

       rule 'foo' used but not defined
              The  grammar referred to a rule named 'foo' but no definition for it was given.  Attempting to use
              the generated parser will likely result in  errors  from  the  linker  due  to  undefined  symbols
              associated with the missing rule.

       rule 'foo' defined but not used
              The  grammar defined a rule named 'foo' and then ignored it.  The code associated with the rule is
              included in the generated parser which will in all other respects be healthy.

       possible infinite left recursion in rule 'foo'
              There exists at least one path through the grammar that leads from  the  rule  'foo'  back  to  (a
              recursive invocation of) the same rule without consuming any input.

       Left  recursion,  especially  that  found  in  standards documents, is often 'direct' and implies trivial
       repetition.

           # (6.7.6)
           direct-abstract-declarator =
               LPAREN abstract-declarator RPAREN
           |   direct-abstract-declarator? LBRACKET assign-expr? RBRACKET
           |   direct-abstract-declarator? LBRACKET STAR RBRACKET
           |   direct-abstract-declarator? LPAREN param-type-list? RPAREN

       The recursion can easily be eliminated by converting the parts of the  pattern  following  the  recursion
       into a repeatable suffix.

           # (6.7.6)
           direct-abstract-declarator =
               direct-abstract-declarator-head?
               direct-abstract-declarator-tail*

           direct-abstract-declarator-head =
               LPAREN abstract-declarator RPAREN

           direct-abstract-declarator-tail =
               LBRACKET assign-expr? RBRACKET
           |   LBRACKET STAR RBRACKET
           |   LPAREN param-type-list? RPAREN

CAVEATS

       A parser that accepts empty input will always succeed.  Consider the following example, not atypical of a
       first attempt to write a PEG-based parser:

           Program = Expression*
           Expression = "whatever"
           %%
           int main() {
             while (yyparse())
               puts("success!");
             return 0;
           }

       This program loops forever, no matter what (if any) input is provided on stdin.  Many fixes are possible,
       the  easiest  being  to  insist that the parser always consumes some non-empty input.  Changing the first
       line to

           Program = Expression+

       accomplishes this.  If the parser is expected to consume the entire input, then explicitly requiring  the
       end-of-file is also highly recommended:

           Program = Expression+ !.

       This  works  because  the  parser  will  only  fail  to  match  ("!" predicate) any character at all ("."
       expression) when it attempts to read beyond the end of the input.

BUGS

       You have to type 'man peg' to read the manual page for leg(1).

       The 'yy' and 'YY' prefixes cannot be changed.

       Left recursion is detected in the input grammar but is not handled correctly in the generated parser.

       Diagnostics for errors in the input grammar are obscure and not particularly helpful.

       The operators ! and ~ should really be named the other way around.

       Several commonly-used lex(1) features (yywrap(), yyin, etc.) are completely absent.

       The generated parser does not contain '#line' directives to direct C compiler errors back to the  grammar
       description when appropriate.

SEE ALSO

       D. Val Schorre, META II, a syntax-oriented compiler writing language, 19th ACM National Conference, 1964,
       pp. 41.301--41.311.   Describes  a  self-implementing  parser  generator  for  analytic  grammars with no
       backtracking.

       Alexander Birman, The TMG Recognition  Schema,  Ph.D.  dissertation,  Princeton,  1970.   A  mathematical
       treatment of the power and complexity of recursive-descent parsing with backtracking.

       Bryan  Ford, Parsing Expression Grammars: A Recognition-Based Syntactic Foundation, ACM SIGPLAN Symposium
       on Principles of Programming Languages, 2004.  Defines PEGs and analyses them in relation to context-free
       and regular grammars.  Introduces the syntax adopted in peg.

       The standard Unix utilities lex(1) and yacc(1) which influenced the syntax and features of leg.

       The source code for peg and leg whose grammar parsers are written using themselves.

       The latest version of this software and documentation:

           http://piumarta.com/software/peg

AUTHOR

       peg, leg and this manual page were written by Ian  Piumarta  (first-name  at  last-name  dot  com)  while
       investigating  the  viability  of regular and parsing-expression grammars for efficiently extracting type
       and signature information from C header files.

       Please send bug reports and suggestions for improvements to the author at the above address.

Version 0.1                                      September 2013                                           PEG(1)