1// This is a ragel file for generating a paser for MTL files
2// Note that some MTL files are whitespace sensitive
3// Mainly with unquoted string names with spaces
4// ala
5//
6// newmtl material name with spaces and no quotes
7//
8// or
9//
10// map_Kd my texture file.png
11//
12%%{
13  machine simple_lexer;
14
15  default = ^0;
16  lineend = ('\n' | '\r\n');
17  greyspace = [\t\v\f ];
18  comment = '#'[^\r\n]* . lineend;
19
20  action appendString { recentString += *p;  }
21  action storeString
22  {
23    Token tok;
24    tok.StringValue = recentString;
25    tok.Type = Token::String;
26    tokens.push_back(tok);
27    recentString.clear();
28    currentNum.clear();
29    recentSpace.clear();
30  }
31  string = ([^\t\v\f\r\n ]+ @appendString);
32
33  action appendSpace { recentSpace += *p;  }
34  action storeSpace
35  {
36    Token tok;
37    tok.StringValue = recentSpace;
38    tok.Type = Token::Space;
39    tokens.push_back(tok);
40    recentSpace.clear();
41    currentNum.clear();
42    recentString.clear();
43  }
44  spacestring = ([\t\v\f ]+ @appendSpace);
45
46  action appendNum { currentNum += *p;  }
47  action storeNum
48  {
49    currentNum += '\0';
50    Token tok;
51    tok.StringValue = currentNum;
52    tok.NumberValue = std::atof(currentNum.c_str());
53    tok.Type = Token::Number;
54    tokens.push_back(tok);
55    currentNum.clear();
56    recentString.clear();
57    recentSpace.clear();
58  }
59  number = ('+'|'-')? @appendNum [0-9]+ @appendNum ('.' @appendNum [0-9]+ @appendNum)?;
60
61  main := |*
62    comment => { currentNum.clear(); recentString.clear(); recentSpace.clear(); };
63
64
65    number => storeNum;
66
67    string => storeString;
68
69    spacestring => storeSpace;
70
71    lineend =>
72    {
73      Token tok;
74      tok.Type = Token::LineEnd;
75      tokens.push_back(tok);
76      currentNum.clear(); recentString.clear(); recentSpace.clear();
77    };
78
79    default => { std::string value = "Error unknown text: "; value += std::string(ts, te-ts); cerr << value << "\n"; };
80
81  *|;
82
83}%%
84
85%% write data;
86
87int parseMTL(
88  const char *start,
89  std::vector<Token>  &tokens
90)
91{
92  int act, cs, res = 0;
93  const char *p = start;
94  const char *pe = p + strlen(start) + 1;
95  const char *eof = pe;
96  const char *ts = nullptr;
97  const char *te = nullptr;
98
99  std::string recentString;
100  std::string recentSpace;
101  std::string currentNum;
102
103  %% write init;
104  %% write exec;
105
106  return res;
107}
108