sptr<Node> Parser::ParseStatement() { if (currToken == nullptr) { return sptr<EmptyNode>(new EmptyNode()); } sptr<Node> root = nullptr; Types t = currToken->type; switch (t) { case IDENT: root = ParseIdent(); if (Match(POINTER, DOT, OPENBRACSQ, ASSIGN, -1)) { return ParseAssign(dynamic_pointer_cast<VarNode>(root)); } else { return ParseFuncCall(root); } case BEGIN: return ParseBlock(); case IF: return ParseConditional(); case WITH: return ParseWith(); case WHILE: return ParseWhileLoop(); case REPEAT: return ParseRepeatUntil(); case FOR : return ParseForLoop(); case CASE: return ParseSwitchCase(); default: return sptr<EmptyNode>(new EmptyNode()); } }
PProperty TemplateParser::GetProperty( wxString* childName ) { PProperty property( (Property*)NULL ); // Check for #wxparent, #parent, or #child if ( GetNextToken() == TOK_MACRO ) { try { Ident ident = ParseIdent(); switch (ident) { case ID_WXPARENT: { PObjectBase wxparent( GetWxParent() ); if ( wxparent ) { property = GetRelatedProperty( wxparent ); } break; } case ID_PARENT: { PObjectBase parent( m_obj->GetParent() ); if ( parent ) { property = GetRelatedProperty( parent ); } break; } case ID_CHILD: { PObjectBase child( m_obj->GetChild( 0 ) ); if ( child ) { property = GetRelatedProperty( child ); } break; } default: break; } } catch( wxFBException& ex ) { wxLogError( ex.what() ); } } if ( !property ) { if ( GetNextToken() == TOK_PROPERTY ) { wxString propname = ParsePropertyName( childName ); property = m_obj->GetProperty( propname ); } } return property; }
bool CfgBuildOptions::Parse (CfgBuffer& buf) { if (!SkipKeyword (buf, "buildoptions")) return false; if (SkipWhitespace (buf) || *buf != '{') { Expecting (buf, "token {"); return false; } ++buf; while (!SkipWhitespace (buf)) { BuildOpt *opt = new BuildOpt; if (*buf == '}') { ++buf; break; } if (!ParseIdent (buf, opt->name)) { delete opt; return false; } builds.push_back (opt); opt->count = 1; while (!SkipWhitespace (buf)) { if (*buf == '*') // its a multiplier { ++buf; CfgNumeric val; if (!val.Parse (buf)) return false; opt->count = val.value; } else if (*buf == '{') // its a set of conditions { opt->info = new CfgList; if (!opt->info->Parse (buf)) return false; } else break; } } return true; }
sptr<VarNode> Parser::ParseVar(sptr<VarNode> ident) { sptr<VarNode> var = ident ? ident : ParseIdent(); while (Match(OPENBRACSQ, DOT, POINTER, -1)) { var = sptr<VarNode>((VarNode*) new StmntNode(var, currToken)); Types t = currToken->type; NextToken(); switch(t) { case OPENBRACSQ : var->PushChild(ParseExpList()); NextToken(); break; case DOT : var->PushChild(ParseIdent()); break; default: break; } } return var; }
sptr<Node> Parser::ParseForLoop() { sptr<StmntNode> root(new StmntNode(currToken)); NextToken(); root->PushChild(ParseIdent()); Expect(ASSIGN, -1); root->PushChild(ParseExp()); root->PushChild(sptr<KeywordNode>(new KeywordNode(currToken))); Expect(TO, DOWNTO, -1); root->PushChild(ParseExp()); Expect(DO, -1); root->PushChild(ParseStatement()); return root; }
sptr<ExprNode> Parser::ParsePrimary() { sptr<ExprNode> primary = nullptr; if (Match(INTEGER, REAL, HEX, CHARACTER, STRING, -1)) { primary = sptr<ConstNode>(new ConstNode(currToken)); NextToken(); } else if (Match(IDENT, -1)) { sptr<VarNode> ident = ParseIdent(); primary = Match(OPENBRAC, -1) ? ParseVar(ParseFuncCall(ident)) : ParseVar(ident); } else if (Match(OPENBRAC, -1)) { NextToken(); primary = ParseExp(); if (Match(CLOSEBRAC)) NextToken(); else throw ParserException("Enclosed bracket error"); } return primary; }
bool CfgListElem::Parse (CfgBuffer& buf) { if (SkipWhitespace (buf)) { logPrintf ("%d: Unexpected end of file in list element\n", buf.line); return false; } // parse name if (!ParseIdent (buf, name)) return false; SkipWhitespace (buf); if (*buf == '=') { ++buf; value = ParseValue (buf); return value!=0; } else return true; }
//------------------------------------------------------------------------- // CfgLiteral - parses string constants //------------------------------------------------------------------------- bool CfgLiteral::Parse (CfgBuffer& buf) { if (ident) return ParseIdent (buf, value); ++buf; while (*buf != '\n') { if(*buf == '\\') if(buf[1] == '"') { value += buf[1]; buf.pos += 2; continue; } if(*buf == '"') break; value += *buf; ++buf; } ++buf; return true; }
PRBool nsCSSScanner::Next(nsCSSToken& aToken) { for (;;) { // Infinite loop so we can restart after comments. PRInt32 ch = Read(); if (ch < 0) { return PR_FALSE; } // UNICODE-RANGE if ((ch == 'u' || ch == 'U') && Peek() == '+') return ParseURange(ch, aToken); // IDENT if (StartsIdent(ch, Peek())) return ParseIdent(ch, aToken); // AT_KEYWORD if (ch == '@') { PRInt32 nextChar = Read(); if (nextChar >= 0) { PRInt32 followingChar = Peek(); Pushback(nextChar); if (StartsIdent(nextChar, followingChar)) return ParseAtKeyword(ch, aToken); } } // NUMBER or DIM if ((ch == '.') || (ch == '+') || (ch == '-')) { PRInt32 nextChar = Peek(); if (IsDigit(nextChar)) { return ParseNumber(ch, aToken); } else if (('.' == nextChar) && ('.' != ch)) { nextChar = Read(); PRInt32 followingChar = Peek(); Pushback(nextChar); if (IsDigit(followingChar)) return ParseNumber(ch, aToken); } } if (IsDigit(ch)) { return ParseNumber(ch, aToken); } // ID if (ch == '#') { return ParseRef(ch, aToken); } // STRING if ((ch == '"') || (ch == '\'')) { return ParseString(ch, aToken); } // WS if (IsWhitespace(ch)) { aToken.mType = eCSSToken_WhiteSpace; aToken.mIdent.Assign(PRUnichar(ch)); EatWhiteSpace(); return PR_TRUE; } if (ch == '/' && !IsSVGMode()) { PRInt32 nextChar = Peek(); if (nextChar == '*') { (void) Read(); #if 0 // If we change our storage data structures such that comments are // stored (for Editor), we should reenable this code, condition it // on being in editor mode, and apply glazou's patch from bug // 60290. aToken.mIdent.SetCapacity(2); aToken.mIdent.Assign(PRUnichar(ch)); aToken.mIdent.Append(PRUnichar(nextChar)); return ParseCComment(aToken); #endif if (!SkipCComment()) { return PR_FALSE; } continue; // start again at the beginning } } if (ch == '<') { // consume HTML comment tags if (LookAhead('!')) { if (LookAhead('-')) { if (LookAhead('-')) { aToken.mType = eCSSToken_HTMLComment; aToken.mIdent.AssignLiteral("<!--"); return PR_TRUE; } Pushback('-'); } Pushback('!'); } } if (ch == '-') { // check for HTML comment end if (LookAhead('-')) { if (LookAhead('>')) { aToken.mType = eCSSToken_HTMLComment; aToken.mIdent.AssignLiteral("-->"); return PR_TRUE; } Pushback('-'); } } // INCLUDES ("~=") and DASHMATCH ("|=") if (( ch == '|' ) || ( ch == '~' ) || ( ch == '^' ) || ( ch == '$' ) || ( ch == '*' )) { PRInt32 nextChar = Read(); if ( nextChar == '=' ) { if (ch == '~') { aToken.mType = eCSSToken_Includes; } else if (ch == '|') { aToken.mType = eCSSToken_Dashmatch; } else if (ch == '^') { aToken.mType = eCSSToken_Beginsmatch; } else if (ch == '$') { aToken.mType = eCSSToken_Endsmatch; } else if (ch == '*') { aToken.mType = eCSSToken_Containsmatch; } return PR_TRUE; } else if (nextChar >= 0) { Pushback(nextChar); } } aToken.mType = eCSSToken_Symbol; aToken.mSymbol = ch; return PR_TRUE; } }
PRBool nsCSSScanner::ParseURange(PRInt32 aChar, nsCSSToken& aResult) { PRInt32 intro2 = Read(); PRInt32 ch = Peek(); // We should only ever be called if these things are true. NS_ASSERTION(aChar == 'u' || aChar == 'U', "unicode-range called with improper introducer (U)"); NS_ASSERTION(intro2 == '+', "unicode-range called with improper introducer (+)"); // If the character immediately after the '+' is not a hex digit or // '?', this is not really a unicode-range token; push everything // back and scan the U as an ident. if (!IsHexDigit(ch) && ch != '?') { Pushback(intro2); Pushback(aChar); return ParseIdent(aChar, aResult); } aResult.mIdent.Truncate(); aResult.mIdent.Append(aChar); aResult.mIdent.Append(intro2); PRBool valid = PR_TRUE; PRBool haveQues = PR_FALSE; PRUint32 low = 0; PRUint32 high = 0; int i = 0; for (;;) { ch = Read(); i++; if (i == 7 || !(IsHexDigit(ch) || ch == '?')) { break; } aResult.mIdent.Append(ch); if (IsHexDigit(ch)) { if (haveQues) { valid = PR_FALSE; // all question marks should be at the end } low = low*16 + HexDigitValue(ch); high = high*16 + HexDigitValue(ch); } else { haveQues = PR_TRUE; low = low*16 + 0x0; high = high*16 + 0xF; } } if (ch == '-' && IsHexDigit(Peek())) { if (haveQues) { valid = PR_FALSE; } aResult.mIdent.Append(ch); high = 0; i = 0; for (;;) { ch = Read(); i++; if (i == 7 || !IsHexDigit(ch)) { break; } aResult.mIdent.Append(ch); high = high*16 + HexDigitValue(ch); } } Pushback(ch); aResult.mInteger = low; aResult.mInteger2 = high; aResult.mIntegerValid = valid; aResult.mType = eCSSToken_URange; return PR_TRUE; }
PRBool nsCSSScanner::Next(nsresult& aErrorCode, nsCSSToken& aToken) { PRInt32 ch = Read(aErrorCode); if (ch < 0) { return PR_FALSE; } PRUint8* lexTable = gLexTable; // IDENT if (StartsIdent(ch, Peek(aErrorCode), lexTable)) return ParseIdent(aErrorCode, ch, aToken); // From this point on, 0 <= ch < 256. // AT_KEYWORD if (ch == '@') { PRInt32 nextChar = Read(aErrorCode); PRInt32 followingChar = Peek(aErrorCode); Pushback(nextChar); if (StartsIdent(nextChar, followingChar, lexTable)) return ParseAtKeyword(aErrorCode, ch, aToken); } // NUMBER or DIM if ((ch == '.') || (ch == '+') || (ch == '-')) { PRInt32 nextChar = Peek(aErrorCode); if (CheckLexTable(nextChar, IS_DIGIT, lexTable)) { return ParseNumber(aErrorCode, ch, aToken); } else if (('.' == nextChar) && ('.' != ch)) { nextChar = Read(aErrorCode); PRInt32 followingChar = Peek(aErrorCode); Pushback(nextChar); if (CheckLexTable(followingChar, IS_DIGIT, lexTable)) return ParseNumber(aErrorCode, ch, aToken); } } if ((lexTable[ch] & IS_DIGIT) != 0) { return ParseNumber(aErrorCode, ch, aToken); } // ID if (ch == '#') { return ParseRef(aErrorCode, ch, aToken); } // STRING if ((ch == '"') || (ch == '\'')) { return ParseString(aErrorCode, ch, aToken); } // WS if ((lexTable[ch] & IS_WHITESPACE) != 0) { aToken.mType = eCSSToken_WhiteSpace; aToken.mIdent.Assign(PRUnichar(ch)); (void) EatWhiteSpace(aErrorCode); return PR_TRUE; } if (ch == '/') { PRInt32 nextChar = Peek(aErrorCode); if (nextChar == '*') { (void) Read(aErrorCode); #if 0 // If we change our storage data structures such that comments are // stored (for Editor), we should reenable this code, condition it // on being in editor mode, and apply glazou's patch from bug // 60290. aToken.mIdent.SetCapacity(2); aToken.mIdent.Assign(PRUnichar(ch)); aToken.mIdent.Append(PRUnichar(nextChar)); return ParseCComment(aErrorCode, aToken); #endif return SkipCComment(aErrorCode) && Next(aErrorCode, aToken); } } if (ch == '<') { // consume HTML comment tags if (LookAhead(aErrorCode, '!')) { if (LookAhead(aErrorCode, '-')) { if (LookAhead(aErrorCode, '-')) { aToken.mType = eCSSToken_HTMLComment; aToken.mIdent.AssignLiteral("<!--"); return PR_TRUE; } Pushback('-'); } Pushback('!'); } } if (ch == '-') { // check for HTML comment end if (LookAhead(aErrorCode, '-')) { if (LookAhead(aErrorCode, '>')) { aToken.mType = eCSSToken_HTMLComment; aToken.mIdent.AssignLiteral("-->"); return PR_TRUE; } Pushback('-'); } } // INCLUDES ("~=") and DASHMATCH ("|=") if (( ch == '|' ) || ( ch == '~' ) || ( ch == '^' ) || ( ch == '$' ) || ( ch == '*' )) { PRInt32 nextChar = Read(aErrorCode); if ( nextChar == '=' ) { if (ch == '~') { aToken.mType = eCSSToken_Includes; } else if (ch == '|') { aToken.mType = eCSSToken_Dashmatch; } else if (ch == '^') { aToken.mType = eCSSToken_Beginsmatch; } else if (ch == '$') { aToken.mType = eCSSToken_Endsmatch; } else if (ch == '*') { aToken.mType = eCSSToken_Containsmatch; } return PR_TRUE; } else { Pushback(nextChar); } } aToken.mType = eCSSToken_Symbol; aToken.mSymbol = ch; return PR_TRUE; }
bool TemplateParser::ParseMacro() { Ident ident; ident = ParseIdent(); switch (ident) { case ID_WXPARENT: return ParseWxParent(); break; case ID_PARENT: return ParseParent(); break; case ID_FORM: return ParseForm(); break; case ID_IFNOTNULL: return ParseIfNotNull(); break; case ID_IFNULL: return ParseIfNull(); break; case ID_FOREACH: return ParseForEach(); break; case ID_PREDEFINED: return ParsePred(); break; case ID_PREDEFINED_INDEX: return ParseNPred(); break; case ID_CHILD: return ParseChild(); break; case ID_NEWLINE: return ParseNewLine(); break; case ID_IFEQUAL: ParseIfEqual(); break; case ID_IFNOTEQUAL: ParseIfNotEqual(); break; case ID_IFPARENTTYPEEQUAL: ParseIfParentTypeEqual(); break; case ID_IFPARENTCLASSEQUAL: ParseIfParentClassEqual(); break; case ID_IFPARENTTYPENOTEQUAL: ParseIfParentTypeNotEqual(); break; case ID_IFPARENTCLASSNOTEQUAL: ParseIfParentClassNotEqual(); break; case ID_APPEND: ParseAppend(); break; case ID_CLASS: ParseClass(); break; case ID_INDENT: ParseIndent(); break; case ID_UNINDENT: ParseUnindent(); break; case ID_IFTYPEEQUAL: ParseIfTypeEqual(); break; case ID_IFTYPENOTEQUAL: ParseIfTypeNotEqual(); break; case ID_UTBL: ParseLuaTable(); break; default: THROW_WXFBEX( wxT("Invalid Macro Type") ); break; } return true; }