OpenMD 3.0
Molecular Dynamics in the Open
Loading...
Searching...
No Matches
ANTLRUtil.cpp
1/* 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$
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
16namespace antlr {
17#endif
18
19/** Eat whitespace from the input stream
20 * @param is the stream to read from
21 */
22ANTLR_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 */
46ANTLR_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 */
112ANTLR_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 */
148void 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