Mercurial > projects > dil
view src/docgen/config/reader.d @ 806:bcb74c9b895c
Moved out files in the trunk folder to the root.
author | Aziz K?ksal <aziz.koeksal@gmail.com> |
---|---|
date | Sun, 09 Mar 2008 00:12:19 +0100 |
parents | trunk/src/docgen/config/reader.d@2949146f2781 |
children |
line wrap: on
line source
/** * Author: Jari-Matti Mäkelä * License: GPL3 */ module docgen.config.reader; debug import tango.io.Stdout; /** * Lexes a s-exp like input */ char[][] lex(char[] input) { char[][] tokens; uint state = 0, level = 0; size_t sidx = 0; void err(size_t i, int type = 0) { auto b = input[i<20 ? 0 : i-20..i]; auto e = input[i+1..i+21>$ ? $ : i+21]; throw new Exception("Lex: " ~ (type == 0 ? "Illegal character" : type == 1 ? "Wrong number of parenthesis" : "Unexpected end of input") ~ ": " ~ b ~ " >>>" ~ input[i] ~ "<<< " ~ e ~ "." ); } void begin(size_t i) { sidx = i; } void end(size_t i) { tokens ~= input[sidx..i]; } foreach(size_t i, c; input) { if (sidx > i) continue; switch(c) { // states space, token, textEnd case '"': // starts a ""-string switch(state) { case 0: char[] buf; bool escape; char d; sidx = i; while(!((d = input[++sidx]) == '"' && !escape) && sidx<input.length) if (escape) { if (d != '"' && d != '\\') buf ~= '\\'; buf ~= d; escape = false; } else if (d == '\\') escape = true; else buf ~= d; sidx++; tokens ~= buf; state = 2; continue; default: err(i); } case '\\': switch(state) { case 0: begin(i); state = 1; continue; case 1: continue; case 2: err(i); } case '#': // starts a comment sidx = i; while (++sidx<input.length && input[sidx] != '\n') {} continue; case ' ': // whitespace case '\t': case '\n': case '(': // begins a block case ')': // ends a block switch(state) { case 1: end(i); case 0: case 2: switch(c) { case '(': tokens ~= "("; level++; state = 0; break; case ')': tokens ~= ")"; if (!level--) err(i,1); default: state = 0; } } break; default: switch(state) { case 0: begin(i); case 1: state = 1; continue; case 2: err(i); } } } if (state == 3 || level != 0) err(input.length-1,2); if (state > 0) end(input.length); debug { foreach(i, tok; tokens) Stdout.format("{}{}", tok, (i != tokens.length-1 ? " " : "")); Stdout.newline; } return tokens; } /** * Parser a s-exp like input used by the config files. */ char[][][char[]] parse(char[][] tokens) { char[][][char[]] values; size_t i = 1; void err(size_t j) { auto b = tokens[j < 5 ? 0 : j-5..j]; auto e = tokens[j+1..j+6>$ ? $ : j+6]; char[] tmp; foreach(t; b) tmp ~= t ~ " "; tmp ~= ">>>" ~ tokens[j] ~ "<<< "; foreach(t; e) tmp ~= t ~ " "; throw new Exception( "Parse: Illegal token: " ~ tmp ~ "." ); } if (tokens[0] != "(") err(0); void doParse(char[] prefix = null) { if (tokens[i] == "(" || tokens[i] == ")") err(i); if (prefix) prefix ~= "."; auto v = prefix ~ tokens[i++]; //values[v] = null; while (tokens[i] != ")") if (tokens[i++] == "(") doParse(v); else values[v] ~= tokens[i-1]; i++; } doParse(); return values; }