]> git.tdb.fi Git - libs/datafile.git/commitdiff
Fix creating Symbols from arbitary types
authorMikko Rasa <tdb@tdb.fi>
Wed, 27 Oct 2010 20:24:17 +0000 (20:24 +0000)
committerMikko Rasa <tdb@tdb.fi>
Wed, 27 Oct 2010 20:24:17 +0000 (20:24 +0000)
Allow a few other delimiters in symbols
Allow symbols to begin with a non-alphanumeric if escaped
Fix a bug where another token was accepted immediately after a string

source/textparser.cpp
source/textwriter.cpp
source/type.h

index 0076c1b4bab954f8a893abf9f2e6a4ff7da5039a..00192ccc147ce24f4c181a751a741d8fc1481b3d 100644 (file)
@@ -144,6 +144,7 @@ Token TextParser::parse_token()
                OCTAL,
                FLOAT,
                FLOATEXP,
+               STRING_END,
                IDENTIFIER
        };
 
@@ -153,7 +154,7 @@ Token TextParser::parse_token()
                Token::SPECIAL,
                Token::SPECIAL,
                Token::SPECIAL,
-               Token::STRING,
+               Token::SPECIAL,
                Token::SPECIAL,
                Token::INTEGER,
                Token::INTEGER,
@@ -161,6 +162,7 @@ Token TextParser::parse_token()
                Token::INTEGER,
                Token::FLOAT,
                Token::FLOAT,
+               Token::STRING,
                Token::IDENTIFIER
        };
 
@@ -191,10 +193,10 @@ Token TextParser::parse_token()
                                return Token(Token::SPECIAL, string(1, c));
                        else if(isdigit(c))
                                state = DECIMAL;
-                       else if(isalpha(c) || c=='_')
+                       else if(isalpha(c) || c=='_' || c=='\\')
                                state = IDENTIFIER;
                        else
-                               parse_error(c, "0-9A-Za-z_.\"{};+-");
+                               parse_error(c, "0-9A-Za-z_\\.\"{};+-");
                        break;
 
                case SIGN:
@@ -268,6 +270,28 @@ Token TextParser::parse_token()
                        if(c=='\\')
                                escape = !escape;
                        else if(c=='"' && !escape)
+                               state = STRING_END;
+                       else
+                               escape = false;
+                       break;
+
+               case IDENTIFIER:
+                       if(!isalpha(c) && !isdigit(c) && c!='_' && c!='-' && c!='/')
+                               parse_error(c, "0-9A-Za-z_/-");
+                       break;
+
+               case STRING_END:
+                       throw_at(ParseError("Garbage after string"), get_location());
+
+               default:
+                       throw_at(InvalidState("Internal error (bad state)"), get_location());
+               }
+
+               if(is_delimiter(next) && state>=ACCEPT)
+               {
+                       if(state==IDENTIFIER && buf[0]=='\\')
+                               return Token(Token::IDENTIFIER, buf.substr(1));
+                       else if(state==STRING_END)
                        {
                                try
                                {
@@ -280,20 +304,8 @@ Token TextParser::parse_token()
                                }
                        }
                        else
-                               escape = false;
-                       break;
-
-               case IDENTIFIER:
-                       if(!isalpha(c) && !isdigit(c) && c!='_')
-                               parse_error(c, "0-9A-Za-z_");
-                       break;
-
-               default:
-                       throw_at(InvalidState("Internal error (bad state)"), get_location());
+                               return Token(token_type[state], buf);
                }
-
-               if(is_delimiter(next) && state>=ACCEPT)
-                       return Token(token_type[state], buf);
        }
 
        return Token(Token::SPECIAL, "");
index 08909a1c6ed952b190754063d628f4e0e3dbe3dc..eb3aa2d2f6ec778b0411228e6ac6b2f21533e3ce 100644 (file)
@@ -41,7 +41,13 @@ void TextWriter::write_(const Statement &st, unsigned level)
                else if(i->get_signature()==FloatType::signature)
                        out.write(format("%15g", (i->get<FloatType::Store>())));
                else if(i->get_signature()==SymbolType::signature)
-                       out.write(i->get<SymbolType::Store>().name);
+               {
+                       string name = i->get<SymbolType::Store>().name;
+                       if(isdigit(name[0]))
+                               out.write("\\"+name);
+                       else
+                               out.write(name);
+               }
        }
        if(!st.sub.empty())
        {
index 5a87a10222a84794341d9a167c94786ae022927f..242a9e11d1bed7c30cf8bbc978ff1b001133d74b 100644 (file)
@@ -17,7 +17,8 @@ struct Symbol
 {
        std::string name;
 
-       Symbol(const std::string &n): name(n) { }
+       template<typename T>
+       Symbol(const T &n): name(lexical_cast(n)) { }
 
        template<typename T> operator T() const { return lexical_cast<T>(name); }
 };