Parser pseudocode

WARNING This page is a work in progress

Main loop

initialize result
initialize parser state

set arg to value of command line argument n° a
if active option is set
and active option type is 'switch'
or (active option type is 'argument'
and active option temporary argument count = 1)
or (active option type is 'multiargument'
and ((active option temporary argument count + active option argument count) = active option max argument count)
then
unset active option

if parser state flag 'end of options' is set
treat arg as a positional argument
else if arg = "--"
add 'end of options' to parser state flags
unset active option
else if arg = "-"
if active option is set
if active option type is 'multiargument"
if active option temporary argument count is 0
warning #2 Ignore end-of-argument marker
add arg to active option temporary argument list
else
unset active option
else if active option type is 'argument"
set arg to active option temporary argument
end if
else
treat arg as positional argument or subcommand name

else if arg starts with '\-'
remove leading '\' from arg
if active option is set
and active option accepts argument (which should be always true)
then
append arg to active option temporary argument list
else
treat arg as positional argument or subcommand name

else if active option is set and active option argument count = 0
append arg to active option temporary argument list

else if arg starts with "--"
if active option is set
unset active option

set arg tail to content of arg after the first '='
set temp cli option name to content of arg before the first '='
set temp option name to content of (arg + 2) before the first '='
if an option can be found using temp option name
set active option to this option
set active option cli name to temp cli option nmae
else
fatal error #1 Unknown option <option-cli-name>
add 'aborted' flag to parser state
break loop

if active option is set
check if active option is expected
if active option is not expected
add 'unexpected option' flag to parser state flags
if arg tail is not empty
append arg to active option temporary argument list
end if
else if arg starts with "-"
if active option is set
unset active option
set arg to content of (arg + 1)
while arg is not empty
if active option is set
unset active option
set temp option name to first character of arg
set temp cli option name to ('-' + first character of arg)
if an option can be found using temp option name
set active option to this option
set active option cli name to temp cli option nmae
check if active option is expected
if active option is not expected
add 'unexpected option' flag to parser state flags
if active option type is 'argument' or 'multiargument'
and (arg + 1) is not empty
append (arg + 1) to active option temporary argument list
break while
else
fatal error #1 Unknown option <option-cli-name>
add 'aborted' flag to parser state flags
break loop
set arg to content of (arg + 1)
end while
else if active option is set
append arg to active option temporary argument list
else
treat arg as positional argument or subcommand
set value of a to (a + 1)

unset active option

set change occurs to false
for each option in the global scope and the active subcommand
if option type is 'mutli-argument'
if option presence is set
and "min argument" attribute is defined
and option argument count < "min argument"
then
error #11 At least <number> arguments required for <option-cli-name>
set change occurs to true
unmark option and exclusive group parents
else if option type is 'argument'
if option presence is not set
and option as a default value
and option is expected
then
set option argument value to default value
set change occurs to true
mark option and all its parents as set


if option not present
and option is required
then
error #4,#5 or #6 Missing required option ...
end if

set infos to positional argument descriptions of this subcommand
set infos to positional argument descriptions of the main program

and there is at least one argument in the parser state argument list
error #8 or #9 Subcommand/program does not accept positional arguments


if positional argument info is at end of infos
break for

increment processed value count by 1
increment current positional argument value count by 1

if value validates positional argument info rules
append value to result argument list
increment valid value count by 1
else
TODO continue or abort ?

if current positional argument value count reach positional argument info max argument limit
set current positional argument value count to 0
set positional argument info to the next element of infos

increment positional argument number by 1


if processed value count < number of elements of parser state argument list
error #10 //Too many arguments
else if
positional argument info is not at end of infos##
for each remaining positional argument info
if this positional argument is required
error #7 //Required positional argument is missing//

Procedures

procedure unset active option
set markSet to false
if parser state flag 'unexpected option' is set
error #12 Unexpected option active option cli name

if active option type is 'switch'
if active option temporary arguments count > 0
or ((active option temporary arguments count = 1)
and first active option temporary argument is empty)
then
error #13 Option active option cli name does not allow an argument
else
set markSet to true
else if active option type is 'argument'
if active option temporary argument count > 0
set value to first item of active option temporary argument list
if parser state flag 'unexpected option' is not set
and value validates option rules
then
set markSet to true
set active option value to value
else
set active option value to null
else
error #3 Missing argument for option active option cli name
else if active option type is 'multi argument'
if active option temporary argument count > 0
then
for each value of active option temporary argument list
if parser state flag 'unexpected option' is not set
and value validates option rules
then
set markSet to true
append value to active option argument list
else
append null to active option argument list
end for
else
error #3 Missing argument for option active option cli name
end if

if parser state flag 'unexpected option' is not set
and markSet is true
then
mark active option and all its parents as set
end if

clear active option temporary argument list
set active option to null
remove 'unexpected option' flag from parser state flags

procedure mark option and all its parents as value
set option result presence value to value
set child to option

for each ancestor of option ancestors
if value is true
set ancestor result presence to (ancestor result presence + 1)
else
set ancestor result presence to (ancestor result presence - 1)

if ancestor group type is 'exclusive'
and value is true
set ancestor selected option to child

if ancestor result presence value is 0
set ancestor selected option to null

set child to ancestor

procedure validate option argument value: boolean
set result to true
for each validator of option
set v to result of validation of value by validator
set result to (result or v)

return result

procedure treat arg as a positional argument
if parser state flag 'end of options'' is not set
and result active subcommand is not set
and no positional arguments where set yet
then
if a subcommand named arg exists
set result active subcommand to arg
end procedure
end if

append arg to result positional argument list

procedure check if option is expected
for each ancestor of option ancestors
if ancestor group type is 'exclusive'
and ancestor result presence is > 0
and ancestor selected option is not option
then
return false
end if

return true

procedure check if option is required
if option is not marked as required
return false

for each ancestor of option ancestors
if ancestor is an exclusive group
and ((ancestor is not marked as set)
or (ancestor is marked as set by another option))
then
return false
end if
end for

return true
---- The program interface definition framework