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