{ Sample macros for Pascal parsers. }

{ This first group is not used much. }
begin_comment = '{';
char_quote = '''';            { for C, which makes a distinction }
end_comment = '}';
string_quote = '''';
zero_origin = 'false';        { don't force zero origin for arrays }

{ Apply cases:  Either a nop is generated (when there are 0 flags),
  or a case for each flag.  #N stands for the flag name, and #P for
  the whole production.  Note that there will be trouble if the
  production has token(s) with a closing curly brace. }
apply_case =
"case pflag of#{
  #N:  { #P }
    begin
      writeln(rfile, '#N applied.')
    end#^;#}
  end  { apply case };
";
apply_nop =  "{ no tagged productions }
";

{ Array inits (including token tables). }
token_table_init =
  { section which defines the tok table.  #N is the token name,
    #V is the token value (which the same as the index), and #X is
    the cumulative character count, plus one for a terminator. }
"{ initialize the token tables. }#{
puttok('#N', #V, #X);#}
";
array_names =  { array names, in the traditional order. }
  'STATEX, MAP, POPNO, STK_STATE, STK_TOSTATE,
   TOKNUM, TOSTATE, INSYM, PRODX, PRODS';
array_types =  { array type names, in the same order }
  'state_array, reduce_array, pop_array, ss_array, ss_array,
   token_array, tostate_array, insym_array, reduce_array, prod_array';
array_line_break = '#-
  { #3I: }  ';  { stuff to be inserted when the elt count overflows }
array_static_init =
  { template for Turbo Pascal typed consts.  translated starting
    from the #{, it means start loop, print the line break string
    if on the first or nth element, print the value, exit if none
    left, print ", ", and terminate the loop. }
'#N:  #T = (#{#10@#V#^, #});
';
array_assignment_init =
  { set of subscripted assignments for array initialization }
"{ initialize the #N array }#{
#N[#I] := #V;#}
";

{ Symbol table initialization }
symbol_table_init =
  { section which defines reserved wds.  one putsym call per symbol;
    #N is name, and #V is value (#I is also available). }
"{ initialize keywords in the symbol table. }#{
putsym('#N', #V);#}
";

{ scanner stuff }

char_case =  { character case in the scanner }
"'#C':  #S  { '#C' character case };
";
char_next_char =
  { start working on the next character position. }
"begin
  nextch;
  #S
end";
char_assignment = "token := #V  { '#N' }";  { when the token is known }
char_test =
  { the character in the current position is ambiguous.  If the next
    token starts with #C, then start working on the next character
    position; else try the next possibility for this character
    position.  this form is repeated until the ambiguity quits. }
"if ch = '#C' then
  #S
else #~";
char_error =
  { when there is no token which matches the prefix scanned. }
"
  begin
    error('Illegal character');
    get_token;
  end";
