~ubuntu-branches/debian/sid/kdevelop/sid

« back to all changes in this revision

Viewing changes to lib/antlr/src/ANTLRUtil.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Jeremy Lainé
  • Date: 2006-05-23 18:39:42 UTC
  • Revision ID: james.westby@ubuntu.com-20060523183942-hucifbvh68k2bwz7
Tags: upstream-3.3.2
Import upstream version 3.3.2

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* ANTLR Translator Generator
 
2
 * Project led by Terence Parr at http://www.jGuru.com
 
3
 * Software rights: http://www.antlr.org/RIGHTS.html
 
4
 *
 
5
 */
 
6
 
 
7
#include <antlr/config.hpp>
 
8
#include <antlr/IOException.hpp>
 
9
 
 
10
#include <iostream>
 
11
#include <cctype>
 
12
#include <string>
 
13
 
 
14
#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE
 
15
namespace antlr {
 
16
#endif
 
17
 
 
18
/** Eat whitespace from the input stream
 
19
 * @param is the stream to read from
 
20
 */
 
21
ANTLR_USE_NAMESPACE(std)istream& eatwhite( ANTLR_USE_NAMESPACE(std)istream& is )
 
22
{
 
23
        char c;
 
24
        while( is.get(c) )
 
25
        {
 
26
#ifdef ANTLR_CCTYPE_NEEDS_STD
 
27
                if( !ANTLR_USE_NAMESPACE(std)isspace(c) )
 
28
#else
 
29
                if( !isspace(c) )
 
30
#endif
 
31
                {
 
32
                        is.putback(c);
 
33
                        break;
 
34
                }
 
35
        }
 
36
        return is;
 
37
}
 
38
 
 
39
/** Read a string enclosed by '"' from a stream. Also handles escaping of \".
 
40
 * Skips leading whitespace.
 
41
 * @param in the istream to read from.
 
42
 * @returns the string read from file exclusive the '"'
 
43
 * @throws IOException if string is badly formatted
 
44
 */
 
45
ANTLR_USE_NAMESPACE(std)string read_string( ANTLR_USE_NAMESPACE(std)istream& in )
 
46
{
 
47
        char ch;
 
48
        ANTLR_USE_NAMESPACE(std)string ret("");
 
49
        // States for a simple state machine...
 
50
        enum { START, READING, ESCAPE, FINISHED };
 
51
        int state = START;
 
52
 
 
53
        eatwhite(in);
 
54
 
 
55
        while( state != FINISHED && in.get(ch) )
 
56
        {
 
57
                switch( state )
 
58
                {
 
59
                case START:
 
60
                        // start state: check wether starting with " then switch to READING
 
61
                        if( ch != '"' )
 
62
                                throw IOException("string must start with '\"'");
 
63
                        state = READING;
 
64
                        continue;
 
65
                case READING:
 
66
                        // reading state: look out for escape sequences and closing "
 
67
                        if( ch == '\\' )                // got escape sequence
 
68
                        {
 
69
                                state = ESCAPE;
 
70
                                continue;
 
71
                        }
 
72
                        if( ch == '"' )                 // close quote -> stop
 
73
                        {
 
74
                                state = FINISHED;
 
75
                                continue;
 
76
                        }
 
77
                        ret += ch;                              // else append...
 
78
                        continue;
 
79
                case ESCAPE:
 
80
                        switch(ch)
 
81
                        {
 
82
                        case '\\':
 
83
                                ret += ch;
 
84
                                state = READING;
 
85
                                continue;
 
86
                        case '"':
 
87
                                ret += ch;
 
88
                                state = READING;
 
89
                                continue;
 
90
                        case '0':
 
91
                                ret += '\0';
 
92
                                state = READING;
 
93
                                continue;
 
94
                        default:                                                // unrecognized escape is not mapped
 
95
                                ret += '\\';
 
96
                                ret += ch;
 
97
                                state = READING;
 
98
                                continue;
 
99
                        }
 
100
                }
 
101
        }
 
102
        if( state != FINISHED )
 
103
                throw IOException("badly formatted string: "+ret);
 
104
 
 
105
        return ret;
 
106
}
 
107
 
 
108
/* Read a ([A-Z][0-9][a-z]_)* kindoff thing. Skips leading whitespace.
 
109
 * @param in the istream to read from.
 
110
 */
 
111
ANTLR_USE_NAMESPACE(std)string read_identifier( ANTLR_USE_NAMESPACE(std)istream& in )
 
112
{
 
113
        char ch;
 
114
        ANTLR_USE_NAMESPACE(std)string ret("");
 
115
 
 
116
        eatwhite(in);
 
117
 
 
118
        while( in.get(ch) )
 
119
        {
 
120
#ifdef ANTLR_CCTYPE_NEEDS_STD
 
121
                if( ANTLR_USE_NAMESPACE(std)isupper(ch) ||
 
122
                         ANTLR_USE_NAMESPACE(std)islower(ch) ||
 
123
                         ANTLR_USE_NAMESPACE(std)isdigit(ch) ||
 
124
                         ch == '_' )
 
125
#else
 
126
                if( isupper(ch) || islower(ch) || isdigit(ch) || ch == '_' )
 
127
#endif
 
128
                        ret += ch;
 
129
                else
 
130
                {
 
131
                        in.putback(ch);
 
132
                        break;
 
133
                }
 
134
        }
 
135
        return ret;
 
136
}
 
137
 
 
138
/** Read a attribute="value" thing. Leading whitespace is skipped.
 
139
 * Between attribute and '=' no whitespace is allowed. After the '=' it is
 
140
 * permitted.
 
141
 * @param in the istream to read from.
 
142
 * @param attribute string the attribute name is put in
 
143
 * @param value string the value of the attribute is put in
 
144
 * @throws IOException if something is fishy. E.g. malformed quoting
 
145
 * or missing '='
 
146
 */
 
147
void read_AttributeNValue( ANTLR_USE_NAMESPACE(std)istream& in,
 
148
                                                                        ANTLR_USE_NAMESPACE(std)string& attribute,
 
149
                                                                        ANTLR_USE_NAMESPACE(std)string& value )
 
150
{
 
151
        attribute = read_identifier(in);
 
152
 
 
153
        char ch;
 
154
        if( in.get(ch) && ch == '=' )
 
155
                value = read_string(in);
 
156
        else
 
157
                throw IOException("invalid attribute=value thing "+attribute);
 
158
}
 
159
 
 
160
#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE
 
161
}
 
162
#endif