aboutsummaryrefslogtreecommitdiff
path: root/src/utils
diff options
context:
space:
mode:
authordos-reis <gdr@axiomatics.org>2010-09-12 01:37:50 +0000
committerdos-reis <gdr@axiomatics.org>2010-09-12 01:37:50 +0000
commit388a4332860c39a19fedbe2bdc4dbc8b411115e6 (patch)
treeccb845facd4be011978e4b401e343211a5e21ccf /src/utils
parent8ffa40b0f97e90033c1be9e97430e0dee02f4e01 (diff)
downloadopen-axiom-388a4332860c39a19fedbe2bdc4dbc8b411115e6.tar.gz
* utils/sexpr.H (Token::character): New token type.
(Character): New. (Syntax::Visitor::visit): Overload for Character. (Allocator::make_character): Declare. (Parser::parse_character): Likewise. * utils/sexpr.cc (operator<<) [Token::character]: Print data for character token. (Lexer::tokenize): Recognize a character literal. (Parser::parse_character): Define.
Diffstat (limited to 'src/utils')
-rw-r--r--src/utils/sexpr.H13
-rw-r--r--src/utils/sexpr.cc33
2 files changed, 46 insertions, 0 deletions
diff --git a/src/utils/sexpr.H b/src/utils/sexpr.H
index f7c9f766..e81fe096 100644
--- a/src/utils/sexpr.H
+++ b/src/utils/sexpr.H
@@ -71,6 +71,7 @@ namespace OpenAxiom {
sharp_colon = OPENAXIOM_SEXPR_TOKEN2('#',':'), // "#:"
digraph_end = OPENAXIOM_SEXPR_TOKEN2(256,256),
integer, // integer literal
+ character, // character literal
string, // string literal
identifier, // plain identifier
sharp_integer_equal, // anchor definition, #n=<form>
@@ -136,6 +137,14 @@ namespace OpenAxiom {
void accept(Visitor&) const;
};
+ // ---------------
+ // -- Character --
+ // ---------------
+ struct Character : Atom {
+ explicit Character(const Token&);
+ void accept(Visitor&) const;
+ };
+
// ------------
// -- String --
// ------------
@@ -259,6 +268,7 @@ namespace OpenAxiom {
struct Syntax::Visitor {
virtual void visit(const Atom&) = 0;
virtual void visit(const Integer&);
+ virtual void visit(const Character&);
virtual void visit(const String&);
virtual void visit(const Symbol&);
virtual void visit(const Reference&);
@@ -329,6 +339,7 @@ namespace OpenAxiom {
~Allocator();
const Integer* make_integer(const Token&);
+ const Character* make_character(const Token&);
const String* make_string(const Token&);
const Symbol* make_symbol(const Token&, Symbol::Kind);
const Reference* make_reference(const Token&, size_t);
@@ -341,6 +352,7 @@ namespace OpenAxiom {
private:
UniqueAllocator<Integer> ints;
+ UniqueAllocator<Character> chars;
UniqueAllocator<String> strs;
UniqueAllocator<Symbol> syms;
UniqueAllocator<Anchor> ancs;
@@ -370,6 +382,7 @@ namespace OpenAxiom {
std::vector<const Syntax*>& syns;
const Symbol* parse_symbol(const Token*&, const Token*);
+ const Character* parse_character(const Token*&, const Token*);
const Anchor* parse_anchor(const Token*&, const Token*);
const Reference* parse_reference(const Token*&, const Token*);
const Symbol* parse_uninterned(const Token*&, const Token*);
diff --git a/src/utils/sexpr.cc b/src/utils/sexpr.cc
index 4910f053..db822410 100644
--- a/src/utils/sexpr.cc
+++ b/src/utils/sexpr.cc
@@ -52,6 +52,7 @@ namespace OpenAxiom {
case Token::sharp_apostrophe: os << "SHARP_APOSTROPHE"; break;
case Token::sharp_colon: os << "SHARP_COLON"; break;
case Token::integer: os << "INTEGER"; break;
+ case Token::character: os << "CHARACTER"; break;
case Token::string: os << "STRING"; break;
case Token::identifier: os << "IDENTIFIER"; break;
case Token::sharp_integer_sharp:
@@ -200,6 +201,12 @@ namespace OpenAxiom {
t.lexeme = strings.intern(start, cur - start + 1);
++cur;
}
+ else if (cur + 1 < end and cur[1] == '\\') {
+ start = cur += 2;
+ skip_to_word_boundary(cur, end);
+ t.type = Token::character;
+ t.lexeme = strings.intern(start, cur - start);
+ }
else {
skip_to_word_boundary(cur, end);
t.lexeme = strings.intern(start, cur - start);
@@ -263,6 +270,16 @@ namespace OpenAxiom {
v.visit(*this);
}
+ // ---------------
+ // -- Character --
+ // ---------------
+ Character::Character(const Token& t) : Atom(t) { }
+
+ void
+ Character::accept(Visitor& v) const {
+ v.visit(*this);
+ }
+
// ------------
// -- String --
// ------------
@@ -378,6 +395,11 @@ namespace OpenAxiom {
}
void
+ Syntax::Visitor::visit(const Character& c) {
+ visit(as<Atom>(c));
+ }
+
+ void
Syntax::Visitor::visit(const String& s) {
visit(as<Atom>(s));
}
@@ -504,6 +526,14 @@ namespace OpenAxiom {
return alloc.make_symbol(*cur++, kind);
}
+ const Character*
+ Parser::parse_character(const Token*& cur, const Token* last) {
+ // NOTE: For the time being, accept only simple characters.
+ if (cur->lexeme->size() != 1)
+ parse_error("invalid literal character syntax");
+ return alloc.make_character(*cur++);
+ }
+
// Parse an anchor definition of the form #n=<syntax>
const Anchor*
Parser::parse_anchor(const Token*& cur, const Token* last) {
@@ -596,6 +626,9 @@ namespace OpenAxiom {
switch (cur->type) {
case Token::integer:
return alloc.make_integer(*cur++);
+
+ case Token::character:
+ return parse_character(cur, last);
case Token::string:
return alloc.make_string(*cur++);