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