/// <summary>Reads a literal or sub-expression</summary> /// <param name="pos">Position of literal or first token of sub-expression</param> /// <returns>Expression tree</returns> /// <exception cref="Logic::AlgorithmException">Attempted to read incorrect type of Token</exception> /// <exception cref="Logic::ExpressionParserException">Syntax error</exception> /// <remarks>Advances the iterator to beyond the end of the literal or sub-expression</remarks> ExpressionParser::ExpressionTree ExpressionParser::ReadValue(TokenIterator& pos) { ExpressionTree expr = nullptr; // Rule: Value = Literal / '(' Expression ')' // Match: Literal if (MatchLiteral(pos)) return ExpressionTree( new LiteralValue(ReadLiteral(pos)) ); // Read: Bracket [nothrow] if (!MatchOperator(pos, L"(")) { // Failed: Unexpected EOF if (pos >= InputEnd) throw ExpressionParserException(HERE, --pos, L"Missing operand"); // Failed: Unexpected token throw ExpressionParserException(HERE, pos, VString(L"Unexpected '%s'", pos->Text.c_str())); } // Read: Expression (may throw) const ScriptToken& open = ReadOperator(pos); expr = ReadExpression(pos); // Adv. then match // Read: Bracket [nothrow] if (MatchOperator(pos, L")")) return ExpressionTree( new BracketedExpression(open, expr, ReadOperator(pos)) ); // Failure: Missing closing bracket if (pos >= InputEnd) throw ExpressionParserException(HERE, --pos, L"Missing closing bracket"); else throw ExpressionParserException(HERE, pos, L"Expected closing bracket"); }
bool wxSimpleHtmlParser::ParseAttributes(wxSimpleHtmlTag* tag) { // Parse attributes of a tag header until we reach > while (!IsTagEndBracket(GetChar(m_pos)) && !Eof()) { EatWhitespace(); wxString attrName, attrValue; if (IsString()) { ReadString(attrName, TRUE); tag->AppendAttribute(attrName, wxEmptyString); } else if (IsNumeric(GetChar(m_pos))) { ReadNumber(attrName, TRUE); tag->AppendAttribute(attrName, wxEmptyString); } else { // Try to read an attribute name/value pair, or at least a name // without the value ReadLiteral(attrName, TRUE); EatWhitespace(); if (GetChar(m_pos) == wxT('=')) { m_pos ++; EatWhitespace(); if (IsString()) ReadString(attrValue, TRUE); else if (!Eof() && !IsTagEndBracket(GetChar(m_pos))) ReadLiteral(attrValue, TRUE); } if (!attrName.IsEmpty()) tag->AppendAttribute(attrName, attrValue); } } return TRUE; }
/********************************************************************************************** * NextToken *********************************************************************************************/ XMLScanner::TOKEN XMLScanner::NextToken () { if (state == STATE_STREAM_END) return TOKEN_STREAM_END; do { switch (state) { /* Content */ case STATE_CONTENT: switch (current) { /* Element tag */ case '<' : state = STATE_ELEMENT_TAG; if (! output.isEmpty ()) { // TODO : check for whitespace only elements ... return TOKEN_CHARACTER_DATA; } break; case '&' : ReadReference (); break; case ']' : /* checks for invalid CDATA section end */ ReadCharacter (); if (current == ']') { ReadCharacter (); if (current == '>') { ReadCharacter (); throw IllegalCharacterException (); } else { output.Append (']'); output.Append (']'); output.Append (current); } } else { output.Append (']'); output.Append (current); } break; default : output.Append (current); break; } break; /* Element Tag */ case STATE_ELEMENT_START_OPENING: if (current == '!') { ReadCharacter (); state = STATE_SPECIAL_ELEMENT; } else if (current == '?') { ReadCharacter (); state = STATE_CONTENT; return ReadProcessingInstruction (); } else if (current == '/') { ReadCharacter (); state = STATE_ELEMENT_END_NAME; return TOKEN_ELEMENT_END_TAG; } else if (isNameFirst (current)) { state = STATE_ELEMENT_START_NAME; return TOKEN_ELEMENT_START_OPENING; } else { throw UnexpectedCharacterException (previous); } break; /* Special elements (comments and CDATA sections etc ...) */ /* '<!' ... */ case STATE_SPECIAL_ELEMENT: if (current == '-') { ReadComment (); } else if (current == '[') { ReadCDATASection (); } else { throw UnsupportedFeatureException (position); } state = STATE_CONTENT; break; /* Element start name target */ /* '<' ... */ case STATE_ELEMENT_START_NAME: if (isNameFirst (current)) { state = STATE_ELEMENT_ATTRIBUTES_START; return ReadQualifiedName (); } else { throw UnexpectedCharacterException (previous); } break; /* Element start name target */ /* '</' ... */ case STATE_ELEMENT_END_NAME: if (isNameFirst (current)) { state = STATE_ELEMENT_END_TAG; return ReadQualifiedName (); } else { throw UnexpectedCharacterException (previous); } break; /* Attributes */ case STATE_ATTRIBUTES_START: if (isWhitespace (current)) { state = STATE_ATTRIBUTES; } else if (current == '/') { state = STATE_ELEMENT_END_CLOSING; } else if (current == '>') { state = STATE_CONTENT; return TOKEN_ELEMENT_START_CLOSING; } else { throw UnexpectedCharacterException (previous); } break; /* '<' QualifiedName ... */ case STATE_ATTRIBUTES : if (isWhitespace (current)) { break; } else if (isNameFirst (current)) { state = STATE_ATTRIBUTE_EQUAL; return ReadQualifiedName (); } else { throw UnexpectedCharacterException (previous); } break; case STATE_ELEMENT_END_CLOSING: if (current == '>') { state = STATE_CONTENT; return TOKEN_ELEMENT_END_CLOSING; } else { throw UnexpectedCharacterException (previous); } break; case STATE_ATTRIBUTE_EQUAL: if (current == '\'' || current == '\"') { state = STATE_ATTRIBUTES_START; return ReadLiteral (); } break; case STATE_ELEMENT_END_TAG: if (current == '>') { state = STATE_CONTENT; return TOKEN_ELEMENT_END_TAG_CLOSING; } break; } } while (ReadCharacter ()); /* Stream end */ return TOKEN_STREAM_END; }