public void ParseIdent(InputTextStream inStream) { Kind = ExprTokenKind.IDENT; string buf; char c; Length = inStream.ReadInto(out buf, out c, ch => char.IsLetterOrDigit(ch) || ch == '_'); Value = Value.Get(buf, true); // [DM] It equals to 'value.set_string(buf);' }
public int ParseReservedWord(InputTextStream inStream) { char c = inStream.Peek; if (Array.IndexOf(ReservedWordLetters, c) >= 0) { string buf; Length = inStream.ReadInto(out buf, out c, ch => char.IsLetter(ch)); if (buf == "and") { Symbol = "&"; Kind = ExprTokenKind.KW_AND; return(1); } if (buf == "div") { Symbol = "/"; Kind = ExprTokenKind.KW_DIV; return(1); } if (buf == "else") { Symbol = "else"; Kind = ExprTokenKind.KW_ELSE; return(1); } if (buf == "false") { Symbol = "false"; Kind = ExprTokenKind.VALUE; Value = Value.False; return(1); } if (buf == "if") { Symbol = "if"; Kind = ExprTokenKind.KW_IF; return(1); } if (buf == "or") { Symbol = "|"; Kind = ExprTokenKind.KW_OR; return(1); } if (buf == "not") { Symbol = "!"; Kind = ExprTokenKind.EXCLAM; return(1); } if (buf == "true") { Symbol = "true"; Kind = ExprTokenKind.VALUE; Value = Value.True; return(1); } return(0); } return(-1); }
/// <summary> /// Ported from void expr_t::token_t::next(std::istream& in, const parse_flags_t& pflags) /// </summary> public void Next(InputTextStream inStream, AmountParseFlagsEnum pflags) { if (inStream.Eof) { Kind = ExprTokenKind.TOK_EOF; return; } char c = inStream.PeekNextNonWS(); if (inStream.Eof) { Kind = ExprTokenKind.TOK_EOF; return; } Symbol = new string(c, 1); Length = 1; switch (c) { case '&': inStream.Get(); c = inStream.Peek; if (c == '&') { c = inStream.Get(); Length = 2; } Kind = ExprTokenKind.KW_AND; break; case '|': inStream.Get(); c = inStream.Peek; if (c == '|') { c = inStream.Get(); Length = 2; } Kind = ExprTokenKind.KW_OR; break; case '(': c = inStream.Get(); Kind = ExprTokenKind.LPAREN; break; case ')': c = inStream.Get(); Kind = ExprTokenKind.RPAREN; break; case '[': { c = inStream.Get(); string buf; Length += inStream.ReadInto(out buf, out c, ch => ch != ']'); if (c != ']') { Expected(']', c); } c = inStream.Get(); Length++; DateInterval timespan = new DateInterval(buf); Date? begin = timespan.Begin; if (!begin.HasValue) { throw new ParseError(ParseError.ParseError_DateSpecifierDoesNotReferToAStartingDate); } Kind = ExprTokenKind.VALUE; Value = Value.Get(begin.Value); break; } case '\'': case '"': { char delim = inStream.Get(); string buf; Length += inStream.ReadInto(out buf, out c, ch => ch != delim); if (c != delim) { Expected(delim, c); } c = inStream.Get(); Length++; Kind = ExprTokenKind.VALUE; Value = Value.Get(buf, true); // [DM] It equals to 'value.set_string(buf);' break; } case '{': { c = inStream.Get(); Amount temp = new Amount(); temp.Parse(inStream, AmountParseFlagsEnum.PARSE_NO_MIGRATE); c = inStream.Get(); if (c != '}') { Expected('}', c); } Length++; Kind = ExprTokenKind.VALUE; Value = Value.Get(temp); break; } case '!': inStream.Get(); c = inStream.Peek; if (c == '=') { c = inStream.Get(); Symbol = "!="; Kind = ExprTokenKind.NEQUAL; Length = 2; break; } else if (c == '~') { c = inStream.Get(); Symbol = "!~"; Kind = ExprTokenKind.NMATCH; Length = 2; break; } Kind = ExprTokenKind.EXCLAM; break; case '-': inStream.Get(); c = inStream.Peek; if (c == '>') { c = inStream.Get(); Symbol = "->"; Kind = ExprTokenKind.ARROW; Length = 2; break; } Kind = ExprTokenKind.MINUS; break; case '+': c = inStream.Get(); Kind = ExprTokenKind.PLUS; break; case '*': c = inStream.Get(); Kind = ExprTokenKind.STAR; break; case '?': c = inStream.Get(); Kind = ExprTokenKind.QUERY; break; case ':': inStream.Get(); c = inStream.Peek; Kind = ExprTokenKind.COLON; break; case '/': { c = inStream.Get(); if (pflags.HasFlag(AmountParseFlagsEnum.PARSE_OP_CONTEXT)) { // operator context Kind = ExprTokenKind.SLASH; } else { // terminal context // Read in the regexp string buf; Length += inStream.ReadInto(out buf, out c, ch => ch != '/'); if (c != '/') { Expected('/', c); } c = inStream.Get(); Length++; Kind = ExprTokenKind.VALUE; Value = Value.Get(new Mask(buf)); } break; } case '=': { inStream.Get(); c = inStream.Peek; if (c == '~') { c = inStream.Get(); Symbol = "=~"; Kind = ExprTokenKind.MATCH; Length = 2; break; } if (c == '=') { c = inStream.Get(); Symbol = "=="; Kind = ExprTokenKind.EQUAL; Length = 2; break; } Kind = ExprTokenKind.ASSIGN; break; } case '<': c = inStream.Get(); if (inStream.Peek == '=') { c = inStream.Get(); Symbol = "<="; Kind = ExprTokenKind.LESSEQ; Length = 2; break; } Kind = ExprTokenKind.LESS; break; case '>': c = inStream.Get(); if (inStream.Peek == '=') { c = inStream.Get(); Symbol = ">="; Kind = ExprTokenKind.GREATEREQ; Length = 2; break; } Kind = ExprTokenKind.GREATER; break; case '.': c = inStream.Get(); Kind = ExprTokenKind.DOT; break; case ',': c = inStream.Get(); Kind = ExprTokenKind.COMMA; break; case ';': c = inStream.Get(); Kind = ExprTokenKind.SEMI; break; default: { int pos = inStream.Pos; // First, check to see if it's a reserved word, such as: and or not int result = ParseReservedWord(inStream); if (char.IsLetter(c) && result == 1) { break; } // If not, rewind back to the beginning of the word to scan it // again. If the result was -1, it means no identifier was scanned // so we don't have to rewind. if (result == 0 || inStream.Eof) { inStream.Pos = pos; } if (inStream.Eof) { throw new InvalidOperationException("eof"); } // When in relaxed parsing mode, we want to migrate commodity flags // so that any precision specified by the user updates the current // maximum displayed precision. AmountParseFlagsEnum parseFlags = AmountParseFlagsEnum.PARSE_NO_ANNOT; if (pflags.HasFlag(AmountParseFlagsEnum.PARSE_NO_MIGRATE)) { parseFlags |= AmountParseFlagsEnum.PARSE_NO_MIGRATE; } if (pflags.HasFlag(AmountParseFlagsEnum.PARSE_NO_REDUCE)) { parseFlags |= AmountParseFlagsEnum.PARSE_NO_REDUCE; } try { Amount temp = new Amount(); if (!temp.Parse(inStream, parseFlags | AmountParseFlagsEnum.PARSE_SOFT_FAIL)) { inStream.Pos = pos; c = inStream.Peek; if (c != InputTextStream.EndOfFileChar) { if (!char.IsLetter(c) && c != '_') { Expected(default(char), c); } ParseIdent(inStream); } else { throw new ParseError(ParseError.ParseError_UnexpectedEOF); } if (Value.Type != ValueTypeEnum.String || Value.IsZero) { Kind = ExprTokenKind.ERROR; Symbol = new string(c, 1); throw new ParseError(ParseError.ParseError_FailedToParseIdentifier); } } else { Kind = ExprTokenKind.VALUE; Value = Value.Get(temp); Length = inStream.Pos - pos; } } catch { Kind = ExprTokenKind.ERROR; Length = inStream.Pos - pos; throw; } break; } } }