ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/group/trunk/OOPSE-2.0/src/antlr/ANTLRUtil.cpp
Revision: 2469
Committed: Fri Dec 2 15:38:03 2005 UTC (18 years, 7 months ago) by tim
File size: 3693 byte(s)
Log Message:
End of the Link --> List
Return of the Oject-Oriented
replace yacc/lex parser with antlr parser

File Contents

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