public ExprOp ParseAssingExpr(InputTextStream inStream, AmountParseFlagsEnum tFlags) { ExprOp node = ParseLambdaExpr(inStream, tFlags); if (node != null && !tFlags.HasFlag(AmountParseFlagsEnum.PARSE_SINGLE)) { while (true) { ExprToken tok = NextToken(inStream, tFlags | AmountParseFlagsEnum.PARSE_OP_CONTEXT); if (tok.Kind == ExprTokenKind.ASSIGN) { ExprOp prev = node; node = new ExprOp(OpKindEnum.O_DEFINE); node.Left = prev; ExprOp scope = new ExprOp(OpKindEnum.SCOPE); scope.Left = ParseLambdaExpr(inStream, tFlags); node.Right = scope; } else { PushToken(tok); break; } } } return(node); }
public ExprOp ParseOrExpr(InputTextStream inStream, AmountParseFlagsEnum tFlags) { ExprOp node = ParseAndExpr(inStream, tFlags); if (node != null && !tFlags.HasFlag(AmountParseFlagsEnum.PARSE_SINGLE)) { while (true) { ExprToken tok = NextToken(inStream, tFlags | AmountParseFlagsEnum.PARSE_OP_CONTEXT); if (tok.Kind == ExprTokenKind.KW_OR) { ExprOp prev = node; node = new ExprOp(OpKindEnum.O_OR); node.Left = prev; node.Right = ParseAndExpr(inStream, tFlags); if (node.Right == null) { throw new ParseError(String.Format(ParseError.ParseError_OperatorNotFollowedByArgument, tok.Symbol)); } } else { PushToken(tok); break; } } } return(node); }
public ExprOp ParseCallExpr(InputTextStream inStream, AmountParseFlagsEnum tFlags) { ExprOp node = ParseValueTerm(inStream, tFlags); if (node != null && !tFlags.HasFlag(AmountParseFlagsEnum.PARSE_SINGLE)) { while (true) { ExprToken tok = NextToken(inStream, tFlags | AmountParseFlagsEnum.PARSE_OP_CONTEXT); if (tok.Kind == ExprTokenKind.LPAREN) { ExprOp prev = node; node = new ExprOp(OpKindEnum.O_CALL); node.Left = prev; PushToken(tok); // let the parser see the '(' again node.Right = ParseValueExpr(inStream, tFlags | AmountParseFlagsEnum.PARSE_SINGLE); } else { PushToken(tok); break; } } } return(node); }
public ExprOp ParseCommaExpr(InputTextStream inStream, AmountParseFlagsEnum tFlags) { ExprOp node = ParseQuerycolonExpr(inStream, tFlags); if (node != null && !tFlags.HasFlag(AmountParseFlagsEnum.PARSE_SINGLE)) { ExprOp next = null; while (true) { ExprToken tok = NextToken(inStream, tFlags | AmountParseFlagsEnum.PARSE_OP_CONTEXT); if (tok.Kind == ExprTokenKind.COMMA) { if (next == null) { ExprOp prev = node; node = new ExprOp(OpKindEnum.O_CONS); node.Left = prev; next = node; } ExprToken ntok = NextToken(inStream, tFlags); PushToken(ntok); if (ntok.Kind == ExprTokenKind.RPAREN) { break; } ExprOp chain = new ExprOp(OpKindEnum.O_CONS); chain.Left = ParseQuerycolonExpr(inStream, tFlags); next.Right = chain; next = chain; } else { PushToken(tok); break; } } } return(node); }
public ExprOp ParseValueExpr(InputTextStream inStream, AmountParseFlagsEnum tFlags) { ExprOp node = ParseAssingExpr(inStream, tFlags); if (node != null && !tFlags.HasFlag(AmountParseFlagsEnum.PARSE_SINGLE)) { ExprOp chain = null; while (true) { ExprToken tok = NextToken(inStream, tFlags | AmountParseFlagsEnum.PARSE_OP_CONTEXT); if (tok.Kind == ExprTokenKind.SEMI) { ExprOp seq = new ExprOp(OpKindEnum.O_SEQ); if (chain == null) { seq.Left = node; node = seq; } else { seq.Left = chain.Right; chain.Right = seq; } seq.Right = ParseAssingExpr(inStream, tFlags); chain = seq; } else { PushToken(tok); break; } } } return(node); }
/// <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; } } }
public ExprOp ParseQuerycolonExpr(InputTextStream inStream, AmountParseFlagsEnum tFlags) { ExprOp node = ParseOrExpr(inStream, tFlags); if (node != null && !tFlags.HasFlag(AmountParseFlagsEnum.PARSE_SINGLE)) { ExprToken tok = NextToken(inStream, tFlags |= AmountParseFlagsEnum.PARSE_OP_CONTEXT); if (tok.Kind == ExprTokenKind.QUERY) { ExprOp prev = node; node = new ExprOp(OpKindEnum.O_QUERY); node.Left = prev; node.Right = ParseOrExpr(inStream, tFlags); if (node.Right == null) { throw new ParseError(String.Format(ParseError.ParseError_OperatorNotFollowedByArgument, tok.Symbol)); } NextToken(inStream, tFlags |= AmountParseFlagsEnum.PARSE_OP_CONTEXT, ExprTokenKind.COLON); prev = node.Right; ExprOp subNode = new ExprOp(OpKindEnum.O_COLON); subNode.Left = prev; subNode.Right = ParseOrExpr(inStream, tFlags); if (subNode.Right == null) { throw new ParseError(String.Format(ParseError.ParseError_OperatorNotFollowedByArgument, tok.Symbol)); } node.Right = subNode; } else if (tok.Kind == ExprTokenKind.KW_IF) { ExprOp ifOp = ParseOrExpr(inStream, tFlags); if (ifOp == null) { throw new ParseError("'if' keyword not followed by argument"); } tok = NextToken(inStream, tFlags |= AmountParseFlagsEnum.PARSE_OP_CONTEXT); if (tok.Kind == ExprTokenKind.KW_ELSE) { ExprOp elseOp = ParseOrExpr(inStream, tFlags); if (elseOp == null) { throw new ParseError("'else' keyword not followed by argument"); } ExprOp subNode = new ExprOp(OpKindEnum.O_COLON); subNode.Left = node; subNode.Right = elseOp; node = new ExprOp(OpKindEnum.O_QUERY); node.Left = ifOp; node.Right = subNode; } else { ExprOp nullNode = new ExprOp(OpKindEnum.VALUE); nullNode.AsValue = Value.Empty; ExprOp subNode = new ExprOp(OpKindEnum.O_COLON); subNode.Left = node; subNode.Right = nullNode; node = new ExprOp(OpKindEnum.O_QUERY); node.Left = ifOp; node.Right = subNode; PushToken(tok); } } else { PushToken(tok); } } return(node); }
public ExprOp ParseLogicExpr(InputTextStream inStream, AmountParseFlagsEnum tFlags) { ExprOp node = ParseAddExpr(inStream, tFlags); if (node != null && !tFlags.HasFlag(AmountParseFlagsEnum.PARSE_SINGLE)) { while (true) { OpKindEnum kind = OpKindEnum.LAST; AmountParseFlagsEnum flags = tFlags; ExprToken tok = NextToken(inStream, tFlags | AmountParseFlagsEnum.PARSE_OP_CONTEXT); bool negate = false; switch (tok.Kind) { case ExprTokenKind.EQUAL: if (tFlags.HasFlag(AmountParseFlagsEnum.PARSE_NO_ASSIGN)) { tok.Rewind(inStream); } else { kind = OpKindEnum.O_EQ; } break; case ExprTokenKind.NEQUAL: kind = OpKindEnum.O_EQ; negate = true; break; case ExprTokenKind.MATCH: kind = OpKindEnum.O_MATCH; break; case ExprTokenKind.NMATCH: kind = OpKindEnum.O_MATCH; negate = true; break; case ExprTokenKind.LESS: kind = OpKindEnum.O_LT; break; case ExprTokenKind.LESSEQ: kind = OpKindEnum.O_LTE; break; case ExprTokenKind.GREATER: kind = OpKindEnum.O_GT; break; case ExprTokenKind.GREATEREQ: kind = OpKindEnum.O_GTE; break; default: PushToken(tok); goto exitLoop; } if (kind != OpKindEnum.LAST) { ExprOp prev = node; node = new ExprOp(kind); node.Left = prev; node.Right = ParseAddExpr(inStream, flags); if (node.Right == null) { throw new ParseError(String.Format(ParseError.ParseError_OperatorNotFollowedByArgument, tok.Symbol)); } if (negate) { prev = node; node = new ExprOp(OpKindEnum.O_NOT); node.Left = prev; } } } } exitLoop: return(node); }