- # Returns a concrete instance of `DocCommand` depending on the string.
- new(command_string: String) do
- if command_string.has_prefix("doc:") then
- return new ArticleCommand(command_string)
- else if command_string.has_prefix("comment:") then
- return new CommentCommand(command_string)
- else if command_string.has_prefix("list:") then
- return new ListCommand(command_string)
- else if command_string.has_prefix("param:") then
- return new ParamCommand(command_string)
- else if command_string.has_prefix("return:") then
- return new ReturnCommand(command_string)
- else if command_string.has_prefix("new:") then
- return new NewCommand(command_string)
- else if command_string.has_prefix("call:") then
- return new CallCommand(command_string)
- else if command_string.has_prefix("code:") then
- return new CodeCommand(command_string)
+ # command = parser.parse(":") # syntax error
+ # assert command == null
+ # assert parser.errors.not_empty
+ # ~~~
+ fun parse(string: String): nullable DocCommand do
+ var pos = 0
+ var tmp = new FlatBuffer
+ errors.clear
+
+ # Parse command name
+ pos = string.read_until(tmp, pos, ':')
+ var name = tmp.write_to_string.trim
+
+ # Check allowed commands
+ if name.is_empty then
+ error("empty command name", 0)
+ return null
+ end
+ if not allowed_commands.has(name) then
+ error("unknown command name", 0)
+ return null
+ end
+
+ # Build the command
+ var command = new_command(name, string)
+ if command == null then
+ error("unknown command name", 0)
+ return null
+ end
+
+ # Parse the argument
+ tmp.clear
+ pos = string.read_until(tmp, pos + 1, '|')
+ var arg = tmp.write_to_string.trim
+ if arg.is_empty then
+ error("empty command arg", pos)
+ return null
+ end
+ command.arg = arg
+
+ # Parse command options
+ while pos < string.length do
+ # Parse option name
+ tmp.clear
+ pos = string.read_until(tmp, pos + 1, ':', ',')
+ var oname = tmp.write_to_string.trim
+ var oval = ""
+ if oname.is_empty then break
+ # Parse option value
+ if pos < string.length and string[pos] == ':' then
+ tmp.clear
+ pos = string.read_until(tmp, pos + 1, ',')
+ oval = tmp.write_to_string.trim
+ end
+ command.opts[oname] = oval
+ # TODO Check options