bool ClParserParser:: isValidAssign() { parse_.skipSpace(); if (parse_.eof()) return false; if (! parse_.isAlpha() && ! parse_.isChar('_')) return false; skipIdentifier(); parse_.skipSpace(); while (parse_.isChar('[')) { parse_.skipChar(); if (! skipArray()) return false; parse_.skipSpace(); } while (parse_.isChar('.')) { parse_.skipChar(); parse_.skipSpace(); if (! parse_.isAlpha() && ! parse_.isChar('_')) return false; skipIdentifier(); while (parse_.isChar('[')) { parse_.skipChar(); if (! skipArray()) return false; parse_.skipSpace(); } } if (! parse_.eof()) return false; return true; }
const char *Parser_Perl::findDefinitionOrClass (const char *cp) { while (*cp) { cp = skipEverything (cp); if (!strncmp(cp, "sub", 3) || !strncmp(cp, "package", 7)) { return cp; } cp = skipIdentifier (cp); } return NULL; }
bool ClParserParser:: skipExpression(bool *assign) { bool expression = false; error_code_ = 0; parse_.skipSpace(); while (! parse_.eof()) { /* <expression> := <unary_operator> <expression> */ if (! expression && strchr(parser_unary_operator_chars, parse_.getCharAt()) != nullptr) { skipUnaryOperator(); if (! skipExpression(assign)) return false; if (*assign) { error_code_ = int(ClErr::INVALID_LVALUE_FOR_ASSIGNMENT); return false; } expression = true; } /* <expression> := '(' <expression> ')' */ else if (! expression && parse_.isChar('(')) { bool assign1 = false; parse_.skipChar(); if (! skipExpression(&assign1) && error_code_ != int(ClErr::INVALID_CHARACTER)) return false; error_code_ = 0; parse_.skipSpace(); if (! parse_.isChar(')')) { error_code_ = int(ClErr::MISSING_CLOSE_ROUND_BRACKET); return false; } parse_.skipChar(); expression = true; } /* <expression> := <numeric_value> */ else if (! expression && (parse_.isDigit() || parse_.isChar('.'))) { if (! skipNumericValue()) return false; expression = true; } /* <expression> := <string_value> */ else if (! expression && parse_.isOneOf(parser_string_chars)) { if (! skipStringValue()) return false; expression = true; } /* <expression> := <array_value> */ else if (! expression && parse_.isChar('[')) { parse_.skipChar(); if (! skipArray()) return false; expression = true; } /* <expression> := <dict_value> */ else if (! expression && parse_.isString("{{")) { parse_.skipChars(2); if (! skipDictionary()) return false; expression = true; } /* <expression> := <list_value> */ else if (! expression && parse_.isChar('{')) { parse_.skipChar(); if (! skipList()) return false; expression = true; } /* <expression> := <expression> <binary_operator> <expression> */ else if (expression && parse_.isOneOf(parser_binary_operator_chars)) { bool assign1 = false; skipBinaryOperator(&assign1); if (error_code_ != 0) return false; if (! skipExpression(assign)) return false; if (! assign1 && *assign) { error_code_ = int(ClErr::INVALID_LVALUE_FOR_ASSIGNMENT); return false; } if (assign1) *assign = true; expression = true; } /* <expression> := <expression> '?' <expression> ':' <expression> */ else if (expression && parse_.isChar('?')) { bool assign1 = false; bool assign2 = false; parse_.skipChar(); if (! skipExpression(&assign1) && error_code_ != int(ClErr::INVALID_CHARACTER)) return false; error_code_ = 0; parse_.skipSpace(); if (! parse_.isChar(':')) { error_code_ = int(ClErr::MISSING_COLON_OPERATOR); return false; } parse_.skipChar(); if (! skipExpression(&assign2)) return false; expression = true; *assign = assign1 | assign2; } /* <expression> := <expression> '[' <expression> ',' .... ']' */ else if (expression && parse_.isChar('[')) { parse_.skipChar(); if (! skipArray()) return false; expression = true; } /* <expression> := <expression> ',' <expression> */ else if (expression && parse_.isChar(',')) { bool assign1 = false; ClParserStackMgrInst->push(CL_PARSER_OP_COMMA); ClParserStackMgrInst->toNext(); parse_.skipChar(); if (! skipExpression(&assign1)) return false; expression = true; } /* <expression> := <variable> */ /* <expression> := <variable> '.' <variable> '.' <...> */ /* <expression> := <variable> '[' <expression> ',' .... ']' */ /* <expression> := <function> '(' <expression> ',' .... ')' */ /* <expression> := <type> '(' <expression> ',' .... ')' */ else if (! expression && (parse_.isAlpha() || parse_.isChar('_'))) { skipIdentifier(); if (error_code_ != 0) return false; parse_.skipSpace(); if (parse_.isChar('(')) { parse_.skipChar(); if (! skipArgList()) return false; expression = true; } else { if (parse_.isChar('[')) { parse_.skipChar(); if (! skipArray()) return false; parse_.skipSpace(); } while (parse_.isChar('.')) { parse_.skipChar(); parse_.skipSpace(); skipIdentifier(); if (error_code_ != 0) return false; if (parse_.isChar('[')) { parse_.skipChar(); if (! skipArray()) return false; parse_.skipSpace(); } } expression = true; } } else { error_code_ = int(ClErr::INVALID_CHARACTER); return false; } parse_.skipSpace(); } if (! expression) { error_code_ = int(ClErr::NULL_EXPRESSION); return false; } return true; }
int32_t MessagePattern::parsePluralOrSelectStyle(UMessagePatternArgType argType, int32_t index, int32_t nestingLevel, UParseError *parseError, UErrorCode &errorCode) { if(U_FAILURE(errorCode)) { return 0; } int32_t start=index; UBool isEmpty=TRUE; UBool hasOther=FALSE; for(;;) { // First, collect the selector looking for a small set of terminators. // It would be a little faster to consider the syntax of each possible // token right here, but that makes the code too complicated. index=skipWhiteSpace(index); UBool eos=index==msg.length(); if(eos || msg.charAt(index)==u_rightCurlyBrace) { if(eos==inMessageFormatPattern(nestingLevel)) { setParseError(parseError, start); // Bad plural/select pattern syntax. errorCode=U_PATTERN_SYNTAX_ERROR; return 0; } if(!hasOther) { setParseError(parseError, 0); // Missing 'other' keyword in plural/select pattern. errorCode=U_DEFAULT_KEYWORD_MISSING; return 0; } return index; } int32_t selectorIndex=index; if(UMSGPAT_ARG_TYPE_HAS_PLURAL_STYLE(argType) && msg.charAt(selectorIndex)==u_equal) { // explicit-value plural selector: =double index=skipDouble(index+1); int32_t length=index-selectorIndex; if(length==1) { setParseError(parseError, start); // Bad plural/select pattern syntax. errorCode=U_PATTERN_SYNTAX_ERROR; return 0; } if(length>Part::MAX_LENGTH) { setParseError(parseError, selectorIndex); // Argument selector too long. errorCode=U_INDEX_OUTOFBOUNDS_ERROR; return 0; } addPart(UMSGPAT_PART_TYPE_ARG_SELECTOR, selectorIndex, length, 0, errorCode); parseDouble(selectorIndex+1, index, FALSE, parseError, errorCode); // adds ARG_INT or ARG_DOUBLE } else { index=skipIdentifier(index); int32_t length=index-selectorIndex; if(length==0) { setParseError(parseError, start); // Bad plural/select pattern syntax. errorCode=U_PATTERN_SYNTAX_ERROR; return 0; } // Note: The ':' in "offset:" is just beyond the skipIdentifier() range. if( UMSGPAT_ARG_TYPE_HAS_PLURAL_STYLE(argType) && length==6 && index<msg.length() && 0==msg.compare(selectorIndex, 7, kOffsetColon, 0, 7) ) { // plural offset, not a selector if(!isEmpty) { // Plural argument 'offset:' (if present) must precede key-message pairs. setParseError(parseError, start); errorCode=U_PATTERN_SYNTAX_ERROR; return 0; } // allow whitespace between offset: and its value int32_t valueIndex=skipWhiteSpace(index+1); // The ':' is at index. index=skipDouble(valueIndex); if(index==valueIndex) { setParseError(parseError, start); // Missing value for plural 'offset:'. errorCode=U_PATTERN_SYNTAX_ERROR; return 0; } if((index-valueIndex)>Part::MAX_LENGTH) { setParseError(parseError, valueIndex); // Plural offset value too long. errorCode=U_INDEX_OUTOFBOUNDS_ERROR; return 0; } parseDouble(valueIndex, index, FALSE, parseError, errorCode); // adds ARG_INT or ARG_DOUBLE if(U_FAILURE(errorCode)) { return 0; } isEmpty=FALSE; continue; // no message fragment after the offset } else { // normal selector word if(length>Part::MAX_LENGTH) { setParseError(parseError, selectorIndex); // Argument selector too long. errorCode=U_INDEX_OUTOFBOUNDS_ERROR; return 0; } addPart(UMSGPAT_PART_TYPE_ARG_SELECTOR, selectorIndex, length, 0, errorCode); if(0==msg.compare(selectorIndex, length, kOther, 0, 5)) { hasOther=TRUE; } } } if(U_FAILURE(errorCode)) { return 0; } // parse the message fragment following the selector index=skipWhiteSpace(index); if(index==msg.length() || msg.charAt(index)!=u_leftCurlyBrace) { setParseError(parseError, selectorIndex); // No message fragment after plural/select selector. errorCode=U_PATTERN_SYNTAX_ERROR; return 0; } index=parseMessage(index, 1, nestingLevel+1, argType, parseError, errorCode); if(U_FAILURE(errorCode)) { return 0; } isEmpty=FALSE; } }
int32_t MessagePattern::parseArg(int32_t index, int32_t argStartLength, int32_t nestingLevel, UParseError *parseError, UErrorCode &errorCode) { int32_t argStart=partsLength; UMessagePatternArgType argType=UMSGPAT_ARG_TYPE_NONE; addPart(UMSGPAT_PART_TYPE_ARG_START, index, argStartLength, argType, errorCode); if(U_FAILURE(errorCode)) { return 0; } int32_t nameIndex=index=skipWhiteSpace(index+argStartLength); if(index==msg.length()) { setParseError(parseError, 0); // Unmatched '{' braces in message. errorCode=U_UNMATCHED_BRACES; return 0; } // parse argument name or number index=skipIdentifier(index); int32_t number=parseArgNumber(nameIndex, index); if(number>=0) { int32_t length=index-nameIndex; if(length>Part::MAX_LENGTH || number>Part::MAX_VALUE) { setParseError(parseError, nameIndex); // Argument number too large. errorCode=U_INDEX_OUTOFBOUNDS_ERROR; return 0; } hasArgNumbers=TRUE; addPart(UMSGPAT_PART_TYPE_ARG_NUMBER, nameIndex, length, number, errorCode); } else if(number==UMSGPAT_ARG_NAME_NOT_NUMBER) { int32_t length=index-nameIndex; if(length>Part::MAX_LENGTH) { setParseError(parseError, nameIndex); // Argument name too long. errorCode=U_INDEX_OUTOFBOUNDS_ERROR; return 0; } hasArgNames=TRUE; addPart(UMSGPAT_PART_TYPE_ARG_NAME, nameIndex, length, 0, errorCode); } else { // number<-1 (ARG_NAME_NOT_VALID) setParseError(parseError, nameIndex); // Bad argument syntax. errorCode=U_PATTERN_SYNTAX_ERROR; return 0; } index=skipWhiteSpace(index); if(index==msg.length()) { setParseError(parseError, 0); // Unmatched '{' braces in message. errorCode=U_UNMATCHED_BRACES; return 0; } UChar c=msg.charAt(index); if(c==u_rightCurlyBrace) { // all done } else if(c!=u_comma) { setParseError(parseError, nameIndex); // Bad argument syntax. errorCode=U_PATTERN_SYNTAX_ERROR; return 0; } else /* ',' */ { // parse argument type: case-sensitive a-zA-Z int32_t typeIndex=index=skipWhiteSpace(index+1); while(index<msg.length() && isArgTypeChar(msg.charAt(index))) { ++index; } int32_t length=index-typeIndex; index=skipWhiteSpace(index); if(index==msg.length()) { setParseError(parseError, 0); // Unmatched '{' braces in message. errorCode=U_UNMATCHED_BRACES; return 0; } if(length==0 || ((c=msg.charAt(index))!=u_comma && c!=u_rightCurlyBrace)) { setParseError(parseError, nameIndex); // Bad argument syntax. errorCode=U_PATTERN_SYNTAX_ERROR; return 0; } if(length>Part::MAX_LENGTH) { setParseError(parseError, nameIndex); // Argument type name too long. errorCode=U_INDEX_OUTOFBOUNDS_ERROR; return 0; } argType=UMSGPAT_ARG_TYPE_SIMPLE; if(length==6) { // case-insensitive comparisons for complex-type names if(isChoice(typeIndex)) { argType=UMSGPAT_ARG_TYPE_CHOICE; } else if(isPlural(typeIndex)) { argType=UMSGPAT_ARG_TYPE_PLURAL; } else if(isSelect(typeIndex)) { argType=UMSGPAT_ARG_TYPE_SELECT; } } else if(length==13) { if(isSelect(typeIndex) && isOrdinal(typeIndex+6)) { argType=UMSGPAT_ARG_TYPE_SELECTORDINAL; } } // change the ARG_START type from NONE to argType partsList->a[argStart].value=(int16_t)argType; if(argType==UMSGPAT_ARG_TYPE_SIMPLE) { addPart(UMSGPAT_PART_TYPE_ARG_TYPE, typeIndex, length, 0, errorCode); } // look for an argument style (pattern) if(c==u_rightCurlyBrace) { if(argType!=UMSGPAT_ARG_TYPE_SIMPLE) { setParseError(parseError, nameIndex); // No style field for complex argument. errorCode=U_PATTERN_SYNTAX_ERROR; return 0; } } else /* ',' */ { ++index; if(argType==UMSGPAT_ARG_TYPE_SIMPLE) { index=parseSimpleStyle(index, parseError, errorCode); } else if(argType==UMSGPAT_ARG_TYPE_CHOICE) { index=parseChoiceStyle(index, nestingLevel, parseError, errorCode); } else { index=parsePluralOrSelectStyle(argType, index, nestingLevel, parseError, errorCode); } } } // Argument parsing stopped on the '}'. addLimitPart(argStart, UMSGPAT_PART_TYPE_ARG_LIMIT, index, 1, argType, errorCode); return index+1; }