~ubuntu-branches/ubuntu/trusty/blender/trusty

« back to all changes in this revision

Viewing changes to extern/eltopo/common/newparser.cpp

  • Committer: Package Import Robot
  • Author(s): Jeremy Bicha
  • Date: 2013-03-06 12:08:47 UTC
  • mfrom: (1.5.1) (14.1.8 experimental)
  • Revision ID: package-import@ubuntu.com-20130306120847-frjfaryb2zrotwcg
Tags: 2.66a-1ubuntu1
* Resynchronize with Debian (LP: #1076930, #1089256, #1052743, #999024,
  #1122888, #1147084)
* debian/control:
  - Lower build-depends on libavcodec-dev since we're not
    doing the libav9 transition in Ubuntu yet

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
#include <newparser.h>
2
 
#include <lexer.h>
3
 
 
4
 
const ParseTree* ParseTree::
5
 
get_branch(const std::string& name) const
6
 
{
7
 
    std::map<std::string,ParseTree>::const_iterator p=branches.find(name);
8
 
    if(p==branches.end()) return 0;
9
 
    else return &p->second;
10
 
}
11
 
 
12
 
bool ParseTree::remove_first_matching_branch( const std::string& name )
13
 
{
14
 
    std::map<std::string,ParseTree>::iterator p=branches.find(name);
15
 
    if(p==branches.end()) return false;
16
 
    branches.erase( p );
17
 
    return true;
18
 
}
19
 
 
20
 
bool ParseTree::
21
 
get_number(const std::string& name, double& result) const
22
 
{
23
 
    std::map<std::string,double>::const_iterator p=numbers.find(name);
24
 
    if(p==numbers.end()) return false;
25
 
    result=p->second;
26
 
    return true;
27
 
}
28
 
 
29
 
bool ParseTree::
30
 
get_int(const std::string& name, int& result) const
31
 
{
32
 
    double number;
33
 
    if(get_number(name, number)){
34
 
        result=(int)std::floor(number);
35
 
        return true;
36
 
    }else
37
 
        return false;
38
 
}
39
 
 
40
 
bool ParseTree::
41
 
get_string(const std::string& name, std::string& result) const
42
 
{
43
 
    std::map<std::string,std::string>::const_iterator p=strings.find(name);
44
 
    if(p==strings.end()) return false;
45
 
    result=p->second;
46
 
    return true;
47
 
}
48
 
 
49
 
const Array1d* ParseTree::
50
 
get_vector(const std::string& name) const
51
 
{
52
 
    std::map<std::string,Array1d>::const_iterator p=vectors.find(name);
53
 
    if(p==vectors.end()) return 0;
54
 
    else return &p->second;
55
 
}
56
 
 
57
 
bool ParseTree::
58
 
get_vec2d(const std::string& name, Vec2d& v) const
59
 
{
60
 
    std::map<std::string,Array1d>::const_iterator p=vectors.find(name);
61
 
    if(p==vectors.end()) return false;
62
 
    if(p->second.n!=2){
63
 
        std::cerr<<"Error: looking for 2d vector ["<<name<<"] but got dimension "<<p->second.n<<std::endl;
64
 
        return false;
65
 
    }
66
 
    v[0]=p->second[0];
67
 
    v[1]=p->second[1];
68
 
    return true;
69
 
}
70
 
 
71
 
bool ParseTree::
72
 
get_vec3d(const std::string& name, Vec3d& v) const
73
 
{
74
 
    std::map<std::string,Array1d>::const_iterator p=vectors.find(name);
75
 
    if(p==vectors.end()) return false;
76
 
    if(p->second.n!=3){
77
 
        std::cerr<<"Error: looking for 3d vector ["<<name<<"] but got dimension "<<p->second.n<<std::endl;
78
 
        return false;
79
 
    }
80
 
    v[0]=p->second[0];
81
 
    v[1]=p->second[1];
82
 
    v[2]=p->second[2];
83
 
    return true;
84
 
}
85
 
 
86
 
namespace {
87
 
    
88
 
    bool parse_vector(Lexer& lexer, Array1d& v)
89
 
    {
90
 
        Token token;
91
 
        v.resize(0);
92
 
        for(;;){
93
 
            lexer.read(token);
94
 
            switch(token.type){
95
 
                case TOKEN_EOF:
96
 
                    std::cerr<<"Parse error: looking for closing bracket but hit end-of-file"<<std::endl;
97
 
                    return false;
98
 
                case TOKEN_ERROR:
99
 
                    std::cerr<<"Lex error: cannot make sense of ["<<token.string_value<<"]"<<std::endl;
100
 
                    return false;
101
 
                case TOKEN_NUMBER:
102
 
                    v.push_back(token.number_value);
103
 
                    break;
104
 
                case TOKEN_RIGHT_BRACKET:
105
 
                    return true;
106
 
                default:
107
 
                    std::cerr<<"Parse error: looking for a number or a closing bracket, got unexpected token "<<token<<std::endl;
108
 
                    return false;
109
 
            }
110
 
        }
111
 
    }
112
 
    
113
 
    bool recursive_parse(Lexer& lexer, ParseTree& tree, bool root_level)
114
 
    {
115
 
        Token token;
116
 
        std::string name;
117
 
        for(;;){
118
 
            lexer.read(token);
119
 
            switch(token.type){
120
 
                case TOKEN_EOF:
121
 
                    if(!root_level){
122
 
                        std::cerr<<"Parse error: looking for closing parenthesis but hit end-of-file"<<std::endl;
123
 
                        return false;
124
 
                    }else
125
 
                        return true;
126
 
                case TOKEN_ERROR:
127
 
                    std::cerr<<"Lex error: cannot make sense of ["<<token.string_value<<"]"<<std::endl;
128
 
                    return false;
129
 
                case TOKEN_IDENTIFIER: case TOKEN_STRING:
130
 
                    name=token.string_value;
131
 
                    if(tree.branches.find(name)!=tree.branches.end()
132
 
                       || tree.numbers.find(name)!=tree.numbers.end()
133
 
                       || tree.strings.find(name)!=tree.strings.end()
134
 
                       || tree.vectors.find(name)!=tree.vectors.end()){
135
 
                        std::cerr<<"Parse error: name ["<<name<<"] appears multiple times in record"<<std::endl;
136
 
                        return false;
137
 
                    }
138
 
                    break;
139
 
                case TOKEN_RIGHT_PAREN:
140
 
                    if(root_level){
141
 
                        std::cerr<<"Parse error: hit closing parenthesis at root level"<<std::endl;
142
 
                        return false;
143
 
                    }else
144
 
                        return true;
145
 
                default:
146
 
                    std::cerr<<"Parse error: looking for a name, got unexpected token "<<token<<std::endl;
147
 
                    return false;
148
 
            }
149
 
            // we've now got the name, let's read the value
150
 
            lexer.read(token);
151
 
            switch(token.type){
152
 
                case TOKEN_EOF:
153
 
                    std::cerr<<"Parse error: looking for a value for ["<<name<<"] but hit end-of-file"<<std::endl;
154
 
                    return false;
155
 
                case TOKEN_ERROR:
156
 
                    std::cerr<<"Lex error: cannot make sense of ["<<token.string_value<<"]"<<std::endl;
157
 
                    return false;
158
 
                case TOKEN_IDENTIFIER: case TOKEN_STRING:
159
 
                    tree.strings.insert(std::make_pair(name, token.string_value));
160
 
                    break;
161
 
                case TOKEN_NUMBER:
162
 
                    tree.numbers.insert(std::make_pair(name, token.number_value));
163
 
                    break;
164
 
                case TOKEN_LEFT_PAREN:
165
 
                {
166
 
                    ParseTree subtree;
167
 
                    if(!recursive_parse(lexer, subtree, false)) return false;
168
 
                    tree.branches.insert(std::make_pair(name, subtree));
169
 
                }
170
 
                    break;
171
 
                case TOKEN_RIGHT_PAREN:
172
 
                    std::cerr<<"Parse error: looking for a value for ["<<name<<"] but hit closing parenthesis"<<std::endl;
173
 
                    return false;
174
 
                case TOKEN_LEFT_BRACKET:
175
 
                {
176
 
                    Array1d v;
177
 
                    if(!parse_vector(lexer, v)) return false;
178
 
                    tree.vectors.insert(std::make_pair(name, v));
179
 
                }
180
 
                    break;
181
 
                case TOKEN_RIGHT_BRACKET:
182
 
                    std::cerr<<"Parse error: looking for a value for ["<<name<<"] but hit closing bracket"<<std::endl;
183
 
                    return false;
184
 
            }
185
 
        }
186
 
    }
187
 
    
188
 
}  // unnamed namespace
189
 
 
190
 
 
191
 
bool parse_stream(std::istream& input, ParseTree& tree)
192
 
{
193
 
    Lexer lexer(input);
194
 
    return recursive_parse(lexer, tree, true);
195
 
}