diff --git a/libwccl/ops/expression.h b/libwccl/ops/expression.h
new file mode 100644
index 0000000000000000000000000000000000000000..8d3e71a84c6c9cf8e351faf13dfc063c176a8061
--- /dev/null
+++ b/libwccl/ops/expression.h
@@ -0,0 +1,28 @@
+#ifndef LIBWCCL_OPS_EXPRESSION_H
+#define LIBWCCL_OPS_EXPRESSION_H
+
+#include <libcorpus2/tagset.h>
+#include <boost/noncopyable.hpp>
+
+namespace Wccl {
+
+/**
+ * Abstract base class for WCCL expressions
+ */
+class Expression : public boost::noncopyable {
+public:
+	/**
+	 * @returns String representation of the expression.
+	 */
+	virtual std::string to_string(const Corpus2::Tagset& tagset) const = 0;
+	/**
+	 * @returns String representation of the expression that does not
+	 * require a tagset.
+	 * @note Might be incomplete and/or contain internal info.
+	 */
+	virtual std::string to_raw_string() const = 0;
+};
+
+} /* end ns Wccl */
+
+#endif // LIBWCCL_OPS_EXPRESSION_H