Diff
Not logged in

Differences From Artifact [4e484112cd314d8d]:

To Artifact [a4ea515a0f014c9c]:


13 template ExceptionWithPosition() 13 template ExceptionWithPosition() 14 { 14 { 15 const LexPosition pos; 15 const LexPosition pos; 16 this( const LexPosition pos, string msg, string file=null, size_t line=0 16 this( const LexPosition pos, string msg, string file=null, size_t line=0 17 { super(sprintf!"[%s] %s"(pos, msg), file, line, next); this.pos 17 { super(sprintf!"[%s] %s"(pos, msg), file, line, next); this.pos 18 } 18 } 19 19 20 /// | 20 /// Thrown when encountered an EOF in the middle of a lexical token > 21 21 class UnexpectedEOF : Exception 22 class UnexpectedEOF : Exception 22 { 23 { 23 mixin ExceptionWithPosition; 24 mixin ExceptionWithPosition; 24 } 25 } 25 26 26 /// | 27 /// Thrown when encountered a lexical error > 28 27 class LexException : Exception 29 class LexException : Exception 28 { 30 { 29 mixin ExceptionWithPosition; 31 mixin ExceptionWithPosition; 30 }; 32 }; 31 33 32 /// Represents a position in a source code | 34 /// Represents a position in source codes 33 35 34 class LexPosition 36 class LexPosition 35 { 37 { 36 immutable string filename; /// name of the source file 38 immutable string filename; /// name of the source file 37 immutable int lineno; /// 1-origin 39 immutable int lineno; /// 1-origin 38 immutable int column; /// 1-origin 40 immutable int column; /// 1-origin 39 41 ................................................................................................................................................................................ 93 assert( !__traits(compiles, t.pos=p) ); 95 assert( !__traits(compiles, t.pos=p) ); 94 assert( !__traits(compiles, t.str=789) ); 96 assert( !__traits(compiles, t.str=789) ); 95 assert( !__traits(compiles, t.quoted=true) ); 97 assert( !__traits(compiles, t.quoted=true) ); 96 } 98 } 97 99 98 /// Named Construtors for Lexer 100 /// Named Construtors for Lexer 99 101 100 Lexer lexerFromFile(T...)( string filename, T rest ) | 102 Lexer lexerFromFile(T...)( string filename, T ln_cn ) 101 { 103 { 102 return lexerFromString( std.file.readText(filename), filename, rest ); | 104 return lexerFromString( std.file.readText(filename), filename, ln_cn ); 103 } 105 } 104 106 105 /// Named Construtors for Lexer | 107 /// Named Construtor for Lexer 106 108 107 LexerT!(PositionedReader!CharSeq) /* ddoc doesn't recognize auto return... bugzi 109 LexerT!(PositionedReader!CharSeq) /* ddoc doesn't recognize auto return... bugzi 108 lexerFromString(CharSeq)( CharSeq str, string filename="<unnamed>", int lineno=1 110 lexerFromString(CharSeq)( CharSeq str, string filename="<unnamed>", int lineno=1 109 { 111 { 110 return new LexerT!(PositionedReader!CharSeq)( 112 return new LexerT!(PositionedReader!CharSeq)( 111 PositionedReader!CharSeq(str, filename, lineno, column) 113 PositionedReader!CharSeq(str, filename, lineno, column) 112 ); 114 ); 113 } 115 } 114 116 115 /// Standard Lexer Type (all you have to know is that this is a forward range of | 117 /// Standard Lexer Type (all you have to know is that this is a forward range of 116 118 117 alias LexerT!(PositionedReader!string) Lexer; 119 alias LexerT!(PositionedReader!string) Lexer; 118 120 119 /// Lexer Implementation 121 /// Lexer Implementation 120 122 121 class LexerT(Reader) 123 class LexerT(Reader) 122 if( isForwardRange!(Reader) && is(ElementType!(Reader) == dchar) ) | 124 if( isForwardRange!(Reader) && is(ElementType!(Reader)==dchar) ) 123 { 125 { 124 /// Range primitive 126 /// Range primitive 125 bool empty() /*@property*/ 127 bool empty() /*@property*/ 126 { 128 { 127 return current is null; 129 return current is null; 128 } 130 } 129 131 ................................................................................................................................................................................ 149 private: // implementation 151 private: // implementation 150 152 151 Reader reader; 153 Reader reader; 152 Token current; 154 Token current; 153 155 154 invariant() 156 invariant() 155 { 157 { 156 assert( reader.empty || !std.ctype.isspace(reader.front) ); | 158 assert( reader.empty || !isSpace(reader.front) ); 157 } 159 } 158 160 159 this( Reader reader, Token current = null ) 161 this( Reader reader, Token current = null ) 160 { 162 { 161 this.reader = reader; 163 this.reader = reader; 162 readWhile!isSpace(); 164 readWhile!isSpace(); 163 this.current = (current is null ? readNext() : current); 165 this.current = (current is null ? readNext() : current); 164 } 166 } 165 167 166 public static { | 168 public static > 169 { 167 bool isSpace (dchar c) { return std.ctype.isspace(c)!=0; } 170 bool isSpace (dchar c) { return std.ctype.isspace(c)!=0; } 168 bool isSymbol (dchar c) { return 0x21<=c && c<=0x7f && !std.cty 171 bool isSymbol (dchar c) { return 0x21<=c && c<=0x7f && !std.cty 169 bool isSSymbol (dchar c) { return "()[]{};@".canFind(c); } 172 bool isSSymbol (dchar c) { return "()[]{};@".canFind(c); } 170 bool isMSymbol (dchar c) { return isSymbol(c) && !isSSymbol(c) & 173 bool isMSymbol (dchar c) { return isSymbol(c) && !isSSymbol(c) & 171 bool isLetter (dchar c) { return !isSpace(c) && !isSymbol(c); } 174 bool isLetter (dchar c) { return !isSpace(c) && !isSymbol(c); } 172 } 175 } 173 176 ................................................................................................................................................................................ 374 assert( lex.empty ); 377 assert( lex.empty ); 375 assert_eq( lexerFromString(`-@`).front.str, "-" ); 378 assert_eq( lexerFromString(`-@`).front.str, "-" ); 376 } 379 } 377 380 378 /// Forward range for reader character by character, 381 /// Forward range for reader character by character, 379 /// keeping track of position information and caring \r\n -> \n conversion. 382 /// keeping track of position information and caring \r\n -> \n conversion. 380 383 381 private < 382 struct PositionedReader(CharSeq) 384 struct PositionedReader(CharSeq) 383 if( isForwardRange!(CharSeq) && is(ElementType!(CharSeq) == dchar) ) | 385 if( isForwardRange!(CharSeq) && is(ElementType!(CharSeq)==dchar) ) 384 { 386 { 385 CharSeq buffer; 387 CharSeq buffer; 386 string filename; 388 string filename; 387 int lineno; 389 int lineno; 388 int column; 390 int column; 389 391 390 /// Range primitive 392 /// Range primitive