ROSE  0.9.9.109
BinarySymbolicExprParser.h
1 #ifndef ROSE_BinaryAnalysis_SymbolicExprParser_H
2 #define ROSE_BinaryAnalysis_SymbolicExprParser_H
3 
4 #include <BinarySymbolicExpr.h>
5 #include <Sawyer/SharedPointer.h>
6 
7 namespace Rose {
8 namespace BinaryAnalysis {
9 
24 public:
26  class SyntaxError: public std::runtime_error {
27  public:
28  std::string inputName;
29  unsigned lineNumber;
30  unsigned columnNumber;
31  void print(std::ostream&) const;
32  SyntaxError(const std::string &mesg, const std::string &inputName, unsigned lineNumber, unsigned columnNumber);
33  ~SyntaxError() throw () {}
34  };
35 
37  class Token {
38  public:
40  enum Type {
41  NONE = 0,
47  };
48 
49  private:
50  Type type_;
51  std::string lexeme_; // lexeme
52  size_t width_; // width of value in bits, as in "[N]"
53  size_t width2_; // second width, as M in "[N->M]"
54  Sawyer::Container::BitVector bits_; // bits representing constant terms
55  unsigned lineNumber_, columnNumber_; // for start of token
56 
57  public:
60  : type_(NONE), width_(0), width2_(0), lineNumber_(0), columnNumber_(0) {}
61 
63  Token(Type type, size_t width, const std::string &lexeme, unsigned lineNumber, unsigned columnNumber)
64  : type_(type), lexeme_(lexeme), width_(width), width2_(0),
65  lineNumber_(lineNumber), columnNumber_(columnNumber) {
66  ASSERT_forbid(BITVECTOR==type);
67  }
68 
70  Token(Type type, size_t width, size_t width2, const std::string &lexeme, unsigned lineNumber, unsigned columnNumber)
71  : type_(type), lexeme_(lexeme), width_(width), width2_(width2),
72  lineNumber_(lineNumber), columnNumber_(columnNumber) {
73  ASSERT_forbid(BITVECTOR==type);
74  }
75 
77  Token(const Sawyer::Container::BitVector &bv, const std::string &lexeme, unsigned lineNumber, unsigned columnNumber)
78  : type_(BITVECTOR), lexeme_(lexeme), width_(bv.size()), width2_(0), bits_(bv),
79  lineNumber_(lineNumber), columnNumber_(columnNumber) {}
80 
82  SymbolicExprParser::SyntaxError syntaxError(const std::string &mesg, const std::string &name="input") const {
83  return SymbolicExprParser::SyntaxError(mesg, name, lineNumber_, columnNumber_);
84  }
85 
87  Type type() const { return type_; }
88 
90  const std::string &lexeme() const { return lexeme_; }
91 
93  size_t width() const { return width_; }
94 
96  size_t width2() const { return width2_; }
97 
99  const Sawyer::Container::BitVector& bits() const { return bits_; }
100 
102  unsigned lineNumber() const { return lineNumber_; }
103 
105  unsigned columnNumber() const { return columnNumber_; }
106  };
107 
112  class TokenStream {
113  std::istream &input_;
114  std::string name_;
115  unsigned lineNumber_, columnNumber_;
116  const Token endToken_;
117  std::vector<Token> tokens_;
118  int readAhead_;
119 
120  public:
125  explicit TokenStream(std::istream &input, const std::string &name="input",
126  unsigned lineNumber=1, unsigned columnNumber=0)
127  : input_(input), name_(name), lineNumber_(lineNumber), columnNumber_(columnNumber), readAhead_(EOF) {
128  init();
129  }
130 
132  const std::string& name() const { return name_; }
133 
135  unsigned lineNumber() const { return lineNumber_; }
136 
138  unsigned columnNumber() const { return columnNumber_; }
139 
141  const Token& operator[](size_t idx);
142 
144  void shift(size_t n=1);
145 
147  int nextCharacter();
148 
151  int consumeCharacter();
152 
154  void consumeWhiteSpace();
155 
157  int consumeEscapeSequence();
158 
161  void consumeInlineComment();
162 
165 
172  std::string consumeTerm();
173 
175  size_t consumeWidth();
176 
179  size_t consumeWidth(size_t &width2 /*out*/);
180 
183  Token scan();
184 
185  private:
186  void init();
187 
188  // Try to fill the token vector so it contains tokens up through at least [idx]
189  void fillTokenList(size_t idx);
190  };
191 
194  std::string title_;
195  std::string docString_;
196  public:
197  virtual ~Expansion() {}
198 
201 
205  const std::string& title() const { return title_; }
206  void title(const std::string &s) { title_ = s; }
214  const std::string& docString() const { return docString_; }
215  void docString(const std::string &s) { docString_ = s; }
217  };
218 
220  class AtomExpansion: public Expansion {
221  public:
224 
228  virtual SymbolicExpr::Ptr operator()(const Token &name) = 0;
229  };
230 
232  class OperatorExpansion: public Expansion {
233  public:
234  virtual ~OperatorExpansion() {}
235 
238 
242  virtual SymbolicExpr::Ptr operator()(const Token &name, const SymbolicExpr::Nodes &operands) = 0;
243  };
244 
246  typedef std::vector<AtomExpansion::Ptr> AtomTable;
247 
249  typedef std::vector<OperatorExpansion::Ptr> OperatorTable;
250 
251 private:
252  AtomTable atomTable_;
253  OperatorTable operatorTable_;
254 
255 public:
257  SymbolicExprParser() { init(); }
258 
263  SymbolicExpr::Ptr parse(const std::string&, const std::string &inputName="string");
264 
268  SymbolicExpr::Ptr parse(std::istream &input, const std::string &filename,
269  unsigned lineNumber=1, unsigned columnNumber=0);
270 
274  SymbolicExpr::Ptr parse(TokenStream&);
275 
278 
281 
285  const AtomTable& atomTable() const { return atomTable_; }
286  AtomTable& atomTable() { return atomTable_; }
292  const OperatorTable& operatorTable() const { return operatorTable_; }
293  OperatorTable& operatorTable() { return operatorTable_; }
300  std::string docString() const;
301 
302 private:
303  void init();
304 };
305 
306 std::ostream& operator<<(std::ostream&, const SymbolicExprParser::SyntaxError&);
307 
308 } // namespace
309 } // namespace
310 
311 #endif
const OperatorTable & operatorTable() const
Return all operator expansion functors.
Virtual base class for atom and operator expansion.
const Token & operator[](size_t idx)
Returns the specified token without consuming it.
void shift(size_t n=1)
Consume the specified number of tokens.
Token(Type type, size_t width, const std::string &lexeme, unsigned lineNumber, unsigned columnNumber)
Constructs a specific token from a string.
int nextCharacter()
Returns the next character.
unsigned lineNumber() const
Line number for start of token.
std::string inputName
Name of input, usually a file name.
OperatorTable & operatorTable()
Return all operator expansion functors.
unsigned columnNumber() const
Current column number.
std::vector< OperatorExpansion::Ptr > OperatorTable
Ordered operator table.
Tokens generated by the lexical analysis.
size_t consumeWidth()
Parse and consume a width specification.
Sawyer::SharedPointer< AtomExpansion > Ptr
Shared-ownership pointer to an AtomExpansion.
void consumeInlineComment()
Skip over angle-bracket comments.
Main namespace for the ROSE library.
Parses symbolic expressions from text.
int consumeCharacter()
Consume the next character.
Reference-counting smart pointer.
Definition: SharedPointer.h:34
const std::string & name() const
Name of this input stream.
virtual SymbolicExpr::Ptr operator()(const Token &name, const SymbolicExpr::Nodes &operands)=0
Operator to expand a list into an expression tree.
Token()
Constructs an end-of-input token with no position information.
Token scan()
Parse and consume the next token.
virtual SymbolicExpr::Ptr operator()(const Token &name)=0
Operator to expand the symbol into an expression tree.
void docString(const std::string &s)
Property: Documentation string.
AtomTable & atomTable()
Return all atom expansion functors.
std::string consumeTerm()
Parse and consume a term.
size_t width() const
Width of expression in bits.
const std::string & lexeme() const
Lexeme from which token was parsed.
Sawyer::SharedPointer< OperatorExpansion > Ptr
Shared-ownership pointer to an OperatorExpansion.
void consumeWhiteSpace()
Skip over characters until a non-white-space character is encountered.
Token(const Sawyer::Container::BitVector &bv, const std::string &lexeme, unsigned lineNumber, unsigned columnNumber)
Construct a token for a numeric constant.
SymbolicExprParser::SyntaxError syntaxError(const std::string &mesg, const std::string &name="input") const
Creates a syntax error from a token plus message.
const std::string & docString() const
Property: Documentation string.
void title(const std::string &s)
Property: Title to use for documentation.
std::string docString() const
Documentation string.
void print(std::ostream &) const
Print error message to stream.
void appendOperatorExpansion(const OperatorExpansion::Ptr &)
Append a new functor for expanding operators into symbolic expressions.
Base class for reference counted objects.
Definition: SharedObject.h:22
void consumeWhiteSpaceAndComments()
Skip over white space and/or inline comments.
int consumeEscapeSequence()
Skip over an escape sequence and return the escaped character.
std::vector< AtomExpansion::Ptr > AtomTable
Ordered atom table.
Token(Type type, size_t width, size_t width2, const std::string &lexeme, unsigned lineNumber, unsigned columnNumber)
Constructs a specific token from a string.
Sawyer::SharedPointer< Expansion > Ptr
Shared-ownership pointer to an Expansion.
size_t width2() const
Width of domain (address) in bits for memory states.
const std::string & title() const
Property: Title to use for documentation.
const Sawyer::Container::BitVector & bits() const
Bit vector for numeric constants.
TokenStream(std::istream &input, const std::string &name="input", unsigned lineNumber=1, unsigned columnNumber=0)
Scan tokens from a character stream.
unsigned columnNumber() const
Column number for start of token.
SymbolicExpr::Ptr parse(const std::string &, const std::string &inputName="string")
Create a symbolic expression by parsing a string.
void appendAtomExpansion(const AtomExpansion::Ptr &)
Append a new functor for expanding atoms into symbolic expressions.
const AtomTable & atomTable() const
Return all atom expansion functors.