#include "Encoding.h"
#include "Parser.h"
+#include "support/textutils.h"
#include <iostream>
}
+bool Token::isAlnumASCII() const
+{
+ return cat_ == catLetter ||
+ (cat_ == catOther && cs_.length() == 1 && isDigitASCII(cs_[0]));
+}
+
+
+#ifdef FILEDEBUG
+void debugToken(std::ostream & os, Token const & t, unsigned int flags)
+{
+ char sep = ' ';
+ os << "t: " << t << " flags: " << flags;
+ if (flags & FLAG_BRACE_LAST) { os << sep << "BRACE_LAST"; sep = '|'; }
+ if (flags & FLAG_RIGHT ) { os << sep << "RIGHT" ; sep = '|'; }
+ if (flags & FLAG_END ) { os << sep << "END" ; sep = '|'; }
+ if (flags & FLAG_BRACK_LAST) { os << sep << "BRACK_LAST"; sep = '|'; }
+ if (flags & FLAG_TEXTMODE ) { os << sep << "TEXTMODE" ; sep = '|'; }
+ if (flags & FLAG_ITEM ) { os << sep << "ITEM" ; sep = '|'; }
+ if (flags & FLAG_LEAVE ) { os << sep << "LEAVE" ; sep = '|'; }
+ if (flags & FLAG_SIMPLE ) { os << sep << "SIMPLE" ; sep = '|'; }
+ if (flags & FLAG_EQUATION ) { os << sep << "EQUATION" ; sep = '|'; }
+ if (flags & FLAG_SIMPLE2 ) { os << sep << "SIMPLE2" ; sep = '|'; }
+ if (flags & FLAG_OPTION ) { os << sep << "OPTION" ; sep = '|'; }
+ if (flags & FLAG_BRACED ) { os << sep << "BRACED" ; sep = '|'; }
+ if (flags & FLAG_CELL ) { os << sep << "CELL" ; sep = '|'; }
+ if (flags & FLAG_TABBING ) { os << sep << "TABBING" ; sep = '|'; }
+ os << "\n";
+}
+#endif
+
+
//
// Parser
//
}
-void Parser::skip_spaces(bool skip_comments)
+bool Parser::skip_spaces(bool skip_comments)
{
// We just silently return if we have no more tokens.
// skip_spaces() should be callable at any time,
// the caller must check p::good() anyway.
+ bool skipped = false;
while (good()) {
get_token();
if (isParagraph()) {
putback();
break;
}
- if ( curr_token().cat() == catSpace ||
- curr_token().cat() == catNewline ||
- (curr_token().cat() == catComment && curr_token().cs().empty()))
+ if (curr_token().cat() == catSpace ||
+ curr_token().cat() == catNewline) {
+ skipped = true;
+ continue;
+ }
+ if ((curr_token().cat() == catComment && curr_token().cs().empty()))
continue;
- if (skip_comments && curr_token().cat() == catComment)
- cerr << " Ignoring comment: " << curr_token().asInput();
- else {
+ if (skip_comments && curr_token().cat() == catComment) {
+ // If positions_ is not empty we are doing some kind
+ // of look ahead
+ if (!positions_.empty())
+ cerr << " Ignoring comment: "
+ << curr_token().asInput();
+ } else {
putback();
break;
}
}
+ return skipped;
}
putback();
else if (skip_comments && curr_token().cat() == catComment) {
// TODO: Get rid of this
- cerr << "Unignoring comment: " << curr_token().asInput();
+ // If positions_ is not empty we are doing some kind
+ // of look ahead
+ if (!positions_.empty())
+ cerr << "Unignoring comment: "
+ << curr_token().asInput();
putback();
}
else
}
+void Parser::pushPosition()
+{
+ positions_.push_back(pos_);
+}
+
+
+void Parser::popPosition()
+{
+ pos_ = positions_.back();
+ positions_.pop_back();
+}
+
+
bool Parser::good()
{
if (pos_ < tokens_.size())
}
+bool Parser::hasOpt()
+{
+ // An optional argument can occur in any of the following forms:
+ // - \foo[bar]
+ // - \foo [bar]
+ // - \foo
+ // [bar]
+ // - \foo %comment
+ // [bar]
+
+ // remember current position
+ unsigned int oldpos = pos_;
+ // skip spaces and comments
+ while (good()) {
+ get_token();
+ if (isParagraph()) {
+ putback();
+ break;
+ }
+ if (curr_token().cat() == catSpace ||
+ curr_token().cat() == catNewline ||
+ curr_token().cat() == catComment)
+ continue;
+ putback();
+ break;
+ }
+ bool const retval = (next_token().asInput() == "[");
+ pos_ = oldpos;
+ return retval;
+}
+
+
Parser::Arg Parser::getFullArg(char left, char right)
{
skip_spaces(true);
}
-string Parser::getFullOpt()
+string Parser::getFullOpt(bool keepws)
{
Arg arg = getFullArg('[', ']');
if (arg.first)
return '[' + arg.second + ']';
+ if (keepws)
+ unskip_spaces(true);
return string();
}
-string Parser::getOpt()
-{
- string const res = getArg('[', ']');
- return res.empty() ? string() : '[' + res + ']';
-}
-
-
-string Parser::getOptContent()
-// the same as getOpt but without the brackets
+string Parser::getOpt(bool keepws)
{
string const res = getArg('[', ']');
- return res.empty() ? string() : res;
+ if (res.empty()) {
+ if (keepws)
+ unskip_spaces(true);
+ return string();
+ }
+ return '[' + res + ']';
}