From f6f4a46cf5b14f9a2170cd6475958efbf320caec Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Tue, 5 Aug 2008 13:17:04 -0400 Subject: Moved around most of the files so that source code is in src/, documentation is in doc/, etc. --- parser.cc | 441 -------------------------------------------------------------- 1 file changed, 441 deletions(-) delete mode 100644 parser.cc (limited to 'parser.cc') diff --git a/parser.cc b/parser.cc deleted file mode 100644 index 4795c8f7..00000000 --- a/parser.cc +++ /dev/null @@ -1,441 +0,0 @@ -/* - * Copyright (c) 2003-2008, John Wiegley. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * - Neither the name of New Artisans LLC nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "parser.h" - -namespace ledger { - -expr_t::ptr_op_t -expr_t::parser_t::parse_value_term(std::istream& in, - const flags_t tflags) const -{ - ptr_op_t node; - - token_t& tok = next_token(in, tflags); - - switch (tok.kind) { - case token_t::VALUE: - node = new op_t(op_t::VALUE); - node->set_value(tok.value); - break; - - case token_t::MASK: - node = new op_t(op_t::MASK); - node->set_mask(tok.value.as_string()); - break; - - case token_t::IDENT: { -#if 0 -#ifdef USE_BOOST_PYTHON - if (tok.value->as_string() == "lambda") // special - try { - char c, buf[4096]; - - std::strcpy(buf, "lambda "); - READ_INTO(in, &buf[7], 4000, c, true); - - ptr_op_t eval = new op_t(op_t::O_EVAL); - ptr_op_t lambda = new op_t(op_t::FUNCTION); - lambda->functor = new python_functor_t(python_eval(buf)); - eval->set_left(lambda); - ptr_op_t sym = new op_t(op_t::SYMBOL); - sym->name = new string("__ptr"); - eval->set_right(sym); - - node = eval; - - goto done; - } - catch(const boost::python::error_already_set&) { - throw_(parse_error, "Error parsing lambda expression"); - } -#endif /* USE_BOOST_PYTHON */ -#endif - - string ident = tok.value.as_string(); - - // An identifier followed by ( represents a function call - tok = next_token(in, tflags); - - if (tok.kind == token_t::LPAREN) { - node = new op_t(op_t::IDENT); - node->set_ident(ident); - - ptr_op_t call_node(new op_t(op_t::O_CALL)); - call_node->set_left(node); - call_node->set_right(parse_value_expr(in, tflags | EXPR_PARSE_PARTIAL)); - - tok = next_token(in, tflags); - if (tok.kind != token_t::RPAREN) - tok.expected(')'); - - node = call_node; - } else { - if (std::isdigit(ident[0])) { - node = new op_t(op_t::INDEX); - node->set_index(lexical_cast(ident.c_str())); - } else { - node = new op_t(op_t::IDENT); - node->set_ident(ident); - } - push_token(tok); - } - break; - } - - case token_t::LPAREN: - node = parse_value_expr(in, tflags | EXPR_PARSE_PARTIAL); - if (! node) - throw_(parse_error, tok.symbol << " operator not followed by expression"); - - tok = next_token(in, tflags); - if (tok.kind != token_t::RPAREN) - tok.expected(')'); - break; - - default: - push_token(tok); - break; - } - -#if 0 -#ifdef USE_BOOST_PYTHON - done: -#endif -#endif - return node; -} - -expr_t::ptr_op_t -expr_t::parser_t::parse_unary_expr(std::istream& in, - const flags_t tflags) const -{ - ptr_op_t node; - - token_t& tok = next_token(in, tflags); - - switch (tok.kind) { - case token_t::EXCLAM: { - ptr_op_t term(parse_value_term(in, tflags)); - if (! term) - throw_(parse_error, - tok.symbol << " operator not followed by argument"); - - // A very quick optimization - if (term->kind == op_t::VALUE) { - term->as_value_lval().in_place_negate(); - node = term; - } else { - node = new op_t(op_t::O_NOT); - node->set_left(term); - } - break; - } - - case token_t::MINUS: { - ptr_op_t term(parse_value_term(in, tflags)); - if (! term) - throw_(parse_error, - tok.symbol << " operator not followed by argument"); - - // A very quick optimization - if (term->kind == op_t::VALUE) { - term->as_value_lval().in_place_negate(); - node = term; - } else { - node = new op_t(op_t::O_NEG); - node->set_left(term); - } - break; - } - - default: - push_token(tok); - node = parse_value_term(in, tflags); - break; - } - - return node; -} - -expr_t::ptr_op_t -expr_t::parser_t::parse_mul_expr(std::istream& in, - const flags_t tflags) const -{ - ptr_op_t node(parse_unary_expr(in, tflags)); - - if (node) { - token_t& tok = next_token(in, tflags); - - if (tok.kind == token_t::STAR || tok.kind == token_t::KW_DIV) { - ptr_op_t prev(node); - node = new op_t(tok.kind == token_t::STAR ? - op_t::O_MUL : op_t::O_DIV); - node->set_left(prev); - node->set_right(parse_mul_expr(in, tflags)); - if (! node->right()) - throw_(parse_error, - tok.symbol << " operator not followed by argument"); - - tok = next_token(in, tflags); - } - push_token(tok); - } - - return node; -} - -expr_t::ptr_op_t -expr_t::parser_t::parse_add_expr(std::istream& in, - const flags_t tflags) const -{ - ptr_op_t node(parse_mul_expr(in, tflags)); - - if (node) { - token_t& tok = next_token(in, tflags); - - if (tok.kind == token_t::PLUS || - tok.kind == token_t::MINUS) { - ptr_op_t prev(node); - node = new op_t(tok.kind == token_t::PLUS ? - op_t::O_ADD : op_t::O_SUB); - node->set_left(prev); - node->set_right(parse_add_expr(in, tflags)); - if (! node->right()) - throw_(parse_error, - tok.symbol << " operator not followed by argument"); - - tok = next_token(in, tflags); - } - push_token(tok); - } - - return node; -} - -expr_t::ptr_op_t -expr_t::parser_t::parse_logic_expr(std::istream& in, - const flags_t tflags) const -{ - ptr_op_t node(parse_add_expr(in, tflags)); - - if (node) { - op_t::kind_t kind = op_t::LAST; - flags_t _flags = tflags; - token_t& tok = next_token(in, tflags); - - switch (tok.kind) { - case token_t::EQUAL: - if (tflags & EXPR_PARSE_NO_ASSIGN) - tok.rewind(in); - else - kind = op_t::O_EQ; - break; - case token_t::NEQUAL: - kind = op_t::O_NEQ; - break; - case token_t::MATCH: - kind = op_t::O_MATCH; - break; - case token_t::LESS: - kind = op_t::O_LT; - break; - case token_t::LESSEQ: - kind = op_t::O_LTE; - break; - case token_t::GREATER: - kind = op_t::O_GT; - break; - case token_t::GREATEREQ: - kind = op_t::O_GTE; - break; - default: - push_token(tok); - break; - } - - if (kind != op_t::LAST) { - ptr_op_t prev(node); - node = new op_t(kind); - node->set_left(prev); - node->set_right(parse_add_expr(in, _flags)); - - if (! node->right()) - throw_(parse_error, - tok.symbol << " operator not followed by argument"); - } - } - - return node; -} - -expr_t::ptr_op_t -expr_t::parser_t::parse_and_expr(std::istream& in, - const flags_t tflags) const -{ - ptr_op_t node(parse_logic_expr(in, tflags)); - - if (node) { - token_t& tok = next_token(in, tflags); - - if (tok.kind == token_t::KW_AND) { - ptr_op_t prev(node); - node = new op_t(op_t::O_AND); - node->set_left(prev); - node->set_right(parse_and_expr(in, tflags)); - if (! node->right()) - throw_(parse_error, - tok.symbol << " operator not followed by argument"); - } else { - push_token(tok); - } - } - return node; -} - -expr_t::ptr_op_t -expr_t::parser_t::parse_or_expr(std::istream& in, - const flags_t tflags) const -{ - ptr_op_t node(parse_and_expr(in, tflags)); - - if (node) { - token_t& tok = next_token(in, tflags); - - if (tok.kind == token_t::KW_OR) { - ptr_op_t prev(node); - node = new op_t(op_t::O_OR); - node->set_left(prev); - node->set_right(parse_or_expr(in, tflags)); - if (! node->right()) - throw_(parse_error, - tok.symbol << " operator not followed by argument"); - } else { - push_token(tok); - } - } - return node; -} - -expr_t::ptr_op_t -expr_t::parser_t::parse_querycolon_expr(std::istream& in, - const flags_t tflags) const -{ - ptr_op_t node(parse_or_expr(in, tflags)); - - if (node) { - token_t& tok = next_token(in, tflags); - - if (tok.kind == token_t::QUERY) { - ptr_op_t prev(node); - node = new op_t(op_t::O_AND); - node->set_left(prev); - node->set_right(parse_or_expr(in, tflags)); - if (! node->right()) - throw_(parse_error, - tok.symbol << " operator not followed by argument"); - - token_t& next_tok = next_token(in, tflags); - if (next_tok.kind != token_t::COLON) - next_tok.expected(':'); - - prev = node; - node = new op_t(op_t::O_OR); - node->set_left(prev); - node->set_right(parse_or_expr(in, tflags)); - if (! node->right()) - throw_(parse_error, - tok.symbol << " operator not followed by argument"); - } else { - push_token(tok); - } - } - return node; -} - -expr_t::ptr_op_t -expr_t::parser_t::parse_value_expr(std::istream& in, - const flags_t tflags) const -{ - ptr_op_t node(parse_querycolon_expr(in, tflags)); - - if (node) { - token_t& tok = next_token(in, tflags); - - if (tok.kind == token_t::COMMA) { - ptr_op_t prev(node); - node = new op_t(op_t::O_COMMA); - node->set_left(prev); - node->set_right(parse_value_expr(in, tflags)); - if (! node->right()) - throw_(parse_error, - tok.symbol << " operator not followed by argument"); - tok = next_token(in, tflags); - } - - if (tok.kind != token_t::TOK_EOF) { - if (tflags & EXPR_PARSE_PARTIAL) - push_token(tok); - else - tok.unexpected(); - } - } - else if (! (tflags & EXPR_PARSE_PARTIAL)) { - throw_(parse_error, "Failed to parse value expression"); - } - - return node; -} - -expr_t::ptr_op_t -expr_t::parser_t::parse(std::istream& in, const flags_t flags) -{ - try { - ptr_op_t top_node = parse_value_expr(in, flags); - - if (use_lookahead) { - use_lookahead = false; - lookahead.rewind(in); - } - lookahead.clear(); - - return top_node; - } - catch (const std::exception& err) { - add_error_context("While parsing value expression:\n"); -#if 0 - add_error_context(line_context(str, (long)in.tellg() - 1)); -#endif - throw err; - } -} - -} // namespace ledger -- cgit v1.2.3