Grammar and Parser
******************

This appendix will eventually contain a semi-formal description of Octave's language.

Keywords
========

The identifiers below are keywords, and may not be used as variable or function names:

Categories:
...........

Utility Functions | Variable Declaration | Function Definition | Control Statements | Iterating Structures | Classdef Structures | Execution Environment

Alphabetical keyword listing:
.............................

__FILE__ | __LINE__ | break | case | catch | classdef | continue | do | else | elseif | end | end_try_catch | end_unwind_protect | endclassdef | endenumeration | endevents | endfor | endfunction | endif | endmethods | endparfor | endproperties | endswitch | endwhile | endenumeration | events | for | function | global | if | methods | otherwise | parfor | persistent | properties | return | switch | try | until | unwind_protect | unwind_protect_cleanup | while

Utility Functions:
------------------

The function iskeyword can be used to quickly check whether an identifier is reserved by Octave.

 -- iskeyword: ()
 -- iskeyword: (NAME)
     Return true if NAME is an Octave keyword.

     If NAME is omitted, return a list of keywords. isvarname, exist

Variable Declaration:
---------------------

 -- global: VAR
     Declare variables to have global scope.

          global X;
          if (isempty (X))
            x = 1;
          endif

     persistent

 -- persistent: VAR
     Declare variables as persistent.

     A variable that has been declared persistent within a function will retain its contents in memory between subsequent calls to the same function.  The difference between persistent variables and global variables is that persistent variables are local in scope to a particular function and are not visible elsewhere. global

Function Definition:
--------------------

 -- function: OUTPUTS = function_name (INPUT, ...)
 -- function: function_name (INPUT, ...)
 -- function: OUTPUTS = function_name
     Begin a function body with name function_name, with OUTPUTS as results, and with INPUTS as parameters.

     The function can later be invoked in Octave using the syntax

          [OUTPUT1, OUTPUT2, ...] = function_name (INPUT1, INPUT2, ...)

     return

 -- endfunction:
     Mark the end of a function. function

 -- end:
     Last element of an array or the end of any for, parfor, if, do, while, function, switch, try, or unwind_protect block.

     As an index of an array, the magic index "end" refers to the last valid entry in an indexing operation.

     Example:

          X = [ 1 2 3; 4 5 6 ];
          X(1,end)
           => 3
          X(end,1)
           => 4
          X(end,end)
           => 6

     Programming notes:

      1. The end keyword cannot be used within subsref, subsasgn, or substruct for manual indexing operations.

      2. For custom classes, to enable use of end in indexing expressions it must be overloaded with a function definition such as:

               function last_index = end (obj, end_dim, ndim_obj)
                 if (end_dim == ndim_obj)
                   last_index = prod (size (obj)(end_dim:ndim_obj));
                 else
                   last_index = size (obj, end_dim);
                 endif
               endfunction

          For more information see Object Oriented Programming.

     for, parfor, if, do, while, function, switch, try, unwind_protect

 -- return:
     Return execution control immediately from a function or script to the calling code.

     return is used to stop executing code and exit an m-file immediately rather than continuing until the end of the function or script is reached.

     If the function or script was invoked directly, rather than from calling code in an m-file, then Octave returns to the command line. function

Control Statements:
-------------------

 -- if: (COND) ... endif
 -- if: (COND) ... else ... endif
 -- if: (COND) ... elseif (COND) ... endif
 -- if: (COND) ... elseif (COND) ... else ... endif
     Begin an if block.

     The conditional COND is true if it is not empty and if all values are nonzero.

          x = 1;
          if (x == 1)
            disp ("one");
          elseif (x == 2)
            disp ("two");
          else
            disp ("not one or two");
          endif

     switch

 -- else:
     Alternate action for an if block.

     See if for an example. if

 -- elseif: (COND)
     Alternate conditional test for an if block.

     The conditional COND is true if it is not empty and if all values are nonzero.

     See if for an example. if

 -- endif:
     Mark the end of an if block.

     See if for an example. if

 -- switch: STATEMENT
     Begin a switch block.

          yesno = "yes";

          switch (yesno)
            case {"Yes" "yes" "YES" "y" "Y"}
              value = 1;
            case {"No" "no" "NO" "n" "N"}
              value = 0;
            otherwise
              error ("invalid value");
          endswitch

     if, case, otherwise

 -- case: VALUE
 -- case: {VALUE, ...}
     A case statement in a switch block.

     Octave cases are exclusive and do not fall-through as do C-language cases.  A switch statement must have at least one case.  See switch for an example. switch

 -- otherwise:
     The default statement in a switch block which is executed when no other case statements match the input. switch, case

 -- endswitch:
     Mark the end of a switch block.

     See switch for an example. switch

 -- try:
     Begin a try-catch block.

     If an error occurs within a try block, then the catch code will be run and execution will proceed after the catch block (though it is often recommended to use the lasterr function to re-throw the error after cleanup is completed). catch, unwind_protect

 -- catch:
 -- catch: VALUE
     Begin the cleanup part of a try-catch block. try

 -- end_try_catch:
     Mark the end of a try-catch block. try, catch

 -- unwind_protect:
     Begin an unwind_protect block.

     If an error occurs within the first part of an unwind_protect block the commands within the unwind_protect_cleanup block are executed before the error is thrown.  If an error is not thrown, then the unwind_protect_cleanup block is still executed.  In other words, the unwind_protect_cleanup code is guaranteed to execute regardless of success or failure in the unwind_protect block. unwind_protect_cleanup, try

 -- unwind_protect_cleanup:
     Begin the cleanup section of an unwind_protect block. unwind_protect

 -- end_unwind_protect:
     Mark the end of an unwind_protect block. unwind_protect

Iterating Structures:
---------------------

 -- for: I = RANGE
     Begin a for loop.

          for i = 1:10
            i
          endfor

     parfor, do, while

 -- endfor:
     Mark the end of a for loop.

     See for for an example. for

 -- while: (COND)
     Begin a while loop.

     The conditional COND is true if it is not empty and if all values are nonzero.

          i = 0;
          while (i < 10)
            i++
          endwhile

     do, endwhile, for, until

 -- endwhile:
     Mark the end of a while loop.

     See while for an example. do, while

 -- do:
     Begin a do-until loop.

     This differs from a while loop in that the body of the loop is executed at least once.

          i = 0;
          do
            i++
          until (i == 10)

     for, until, while

 -- until: (COND)
     End a do-until loop.

     The conditional COND is true if it is not empty and if all values are nonzero.

     See do for an example. do

 -- parfor: I = RANGE
 -- parfor: (I = RANGE, MAXPROC)
     Begin a for loop that may execute in parallel.

     A parfor loop has the same syntax as a for loop.  If your Octave session has a parallel processing pool enabled, the iterations of the parfor loop will be executed in parallel across the pool's workers. Otherwise, parfor will behave exactly as for.

     When operating in parallel mode, a parfor loop's iterations are not guaranteed to occur sequentially, and there are additional restrictions about the data access operations you can do inside the loop body.

     Warning: parallel processing pools are currently unimplemented in Octave; parfor currently behaves exactly as a normal for loop.

          parfor i = 1:10
            i
          endparfor

     for, do, while

 -- endparfor:
     Mark the end of a parfor loop.

     See parfor for an example. parfor

 -- break:
     Exit the innermost enclosing do, while, or for loop. do, while, for, parfor, continue

 -- continue:
     Jump to the end of the innermost enclosing do, while, or for loop. break, do, while, for, parfor

Classdef Structures:
--------------------

 -- classdef:
     Begin a classdef block. properties, methods, events, enumeration

 -- endclassdef:
     Mark the end of a classdef definition. classdef

 -- properties:
     Mark the beginning of a block of properties in a classdef definition.  Note that the function "properties" is a function that lists the properties of a classdef class or object. endproperties

 -- endproperties:
     Mark the end of a properties block in a classdef definition. properties

 -- methods:
     Mark the beginning of a block of methods in a classdef definition.  Note that the function "methods" is a function that lists the methods of a class or object. endmethods

 -- endmethods:
     Mark the end of a methods block in a classdef definition. methods

 -- events:
     Begin an events block in a classdef definition.

 -- endevents:
     Mark the end of an events block in a classdef definition. events

 -- enumeration:
     Begin an enumeration block in a classdef definition.

 -- endenumeration:
     Mark the end of an enumeration block in a classdef definition. enumeration

Execution Environment:
----------------------

 -- __FILE__:
     When the lexer recognizes the "__FILE__" keyword it returns a character array containing the full name and path of the file that is being executed. "__FILE__" will return stdin if called from the command line. __LINE__

 -- __LINE__:
     When the lexer recognizes the "__LINE__" keyword it returns a numeric value containing the current input line number of the function or file being executed.  "__LINE__" will return 1 if called from the command line. __FILE__

Parser
======

The parser has a number of variables that affect its internal operation. These variables are generally documented in the manual alongside the code that they affect.

In addition, there are three non-specific parser customization functions. add_input_event_hook can be used to schedule a user function for periodic evaluation.  remove_input_event_hook will stop a user function from being evaluated periodically.

 -- ID =: add_input_event_hook (FCN)
 -- ID =: add_input_event_hook (FCN, DATA)
     Add the named function or function handle FCN to the list of functions to call periodically when Octave is waiting for input.

     The function should have the form

          FCN (DATA)

     If DATA is omitted, Octave calls the function without any arguments.

     The returned identifier may be used to remove the function handle from the list of input hook functions. remove_input_event_hook

 -- remove_input_event_hook: (NAME)
 -- remove_input_event_hook: (FCN_ID)
     Remove the named function or function handle with the given identifier from the list of functions to call periodically when Octave is waiting for input. add_input_event_hook

Finally, when the parser cannot identify an input token it calls a particular function to handle this.  By default, this is the internal function "__unimplemented__" which makes suggestions about possible Octave substitutes for MATLAB functions.

 -- VAL =: missing_function_hook ()
 -- OLD_VAL =: missing_function_hook (NEW_VAL)
 -- OLD_VAL =: missing_function_hook (NEW_VAL, "local")
     Query or set the internal variable that specifies the function to call to provide extra information when an unknown identifier is referenced.

     When called from inside a function with the "local" option, the variable is changed locally for the function and any subroutines it calls. The original variable value is restored when exiting the function. missing_component_hook