12 /// identifier_expr: identifier | identifier '(' expression* ')'
13 ex parser::parse_identifier_expr()
15 std::string name = scanner->str;
16 get_next_tok(); // eat identifier.
18 if (token != '(') // symbol
19 return find_or_insert_symbol(name, syms, strict);
21 // function/ctor call.
22 get_next_tok(); // eat (
26 ex e = parse_expression();
33 throw std::invalid_argument("Expected ')' or ',' in argument list");
40 prototype the_prototype = make_pair(name, args.size());
41 prototype_table::const_iterator reader = funcs.find(the_prototype);
42 if (reader == funcs.end()) {
43 bail_out(std::invalid_argument,
44 "no function \"" << name << "\" with " << args.size()
47 ex ret = reader->second(args);
51 /// paren_expr: '(' expression ')'
52 ex parser::parse_paren_expr()
54 get_next_tok(); // eat (.
55 ex e = parse_expression();
58 throw std::invalid_argument("parser::parse_paren_expr: expected ')'");
59 get_next_tok(); // eat ).
63 extern numeric* _num_1_p;
65 /// unary_expr: [+-] expression
66 ex parser::parse_unary_expr(const int s)
68 // consume '-' (or '+')
70 ex v = parse_expression();
73 return (new mul(v, *_num_1_p))->setflag(status_flags::dynallocated);
77 throw std::invalid_argument(
79 + ": invalid unary operator \""
84 /// primary: identifier_expr | number_expr | paren_expr | unary_expr
85 ex parser::parse_primary()
88 case lexer::token_type::identifier:
89 return parse_identifier_expr();
90 case lexer::token_type::number:
91 return parse_number_expr();
93 return parse_paren_expr();
95 return parse_unary_expr('-');
97 return parse_unary_expr('+');
98 case lexer::token_type::literal:
99 return parse_literal_expr();
100 case lexer::token_type::eof:
101 bail_out(std::invalid_argument, "got EOF while parsing the expression");
103 bail_out(std::invalid_argument, "unknown token " <<
105 (token ? std::string("") + char(token) : "NULL")
110 /// expression ::= primary binoprhs
111 ex parser::parse_expression()
113 ex lhs = parse_primary();
114 ex res = parse_binop_rhs(0, lhs);
118 /// number_expr: number
119 ex parser::parse_number_expr()
121 ex n = numeric(scanner->str.c_str());
122 get_next_tok(); // consume the number
126 /// literal_expr: 'I' | 'Pi' | 'Euler' | 'Catalan'
127 ex parser::parse_literal_expr()
129 if (scanner->str == "I")
131 else if (scanner->str == "Pi")
133 else if (scanner->str == "Euler")
135 else if (scanner->str == "Catalan")
137 bug("unknown literal: \"" << scanner->str << "\"");
140 ex parser::operator()(std::istream& input)
142 scanner->switch_input(&input);
144 ex ret = parse_expression();
148 ex parser::operator()(const std::string& input)
150 std::istringstream is(input);
151 ex ret = operator()(is);
155 int parser::get_next_tok()
157 token = scanner->gettok();
161 parser::parser(const symtab& syms_, const prototype_table& funcs_,
162 const bool strict_) : strict(strict_), funcs(funcs_),
165 scanner = new lexer();