if (line.charAt(pos) == '<')
subject = parseuri();
else if (line.charAt(pos) == '_')
subject = parsebnode();
else
throw new DukeException("Subject in line " + lineno +
" is neither URI nor bnode: " + line);
skipws();
// property
if (pos >= line.length())
throw new DukeException("Line ends before predicate on line " + lineno);
else if (line.charAt(pos) != '<')
throw new DukeException("Predicate does not start with '<', " +
"nearby: '" +
line.substring(pos - 5, pos + 5) + "', at " +
"position: " + pos + " in line " + lineno);
String property = parseuri();
skipws();
// object
boolean literal = false;
String object;
if (pos >= line.length())
throw new DukeException("Line ends before object on line " + lineno);
else if (line.charAt(pos) == '<')
object = parseuri();
else if (line.charAt(pos) == '"') {
object = unescape(parseliteral());
literal = true;
} else if (line.charAt(pos) == '_')
object = parsebnode();
else
throw new DukeException("Illegal object on line " + lineno + ": " +
line.substring(pos));
// terminator
skipws();
if (pos >= line.length() || line.charAt(pos++) != '.')
throw new DukeException("Statement did not end with period; line: '" +
line + "', line number: " + lineno);
skipws();
if (pos + 1 < line.length())
throw new DukeException("Garbage after period on line " + lineno);
handler.statement(subject, property, object, literal);
}