This commit is contained in:
Hackerpilot 2014-05-06 19:32:37 -07:00
commit 1ecb831476
12 changed files with 80 additions and 18 deletions

View File

@ -19,7 +19,7 @@ The following examples assume that we are analyzing a simple file called hellowo
### Token Count ### Token Count
The "--tokenCount" or "-t" option prints the number of tokens in the given file The "--tokenCount" or "-t" option prints the number of tokens in the given file
$ dscanner --tokencount helloworld.d $ dscanner --tokenCount helloworld.d
20 20
### Import Listing ### Import Listing
@ -198,6 +198,6 @@ but not yet implemented.
# Useful code # Useful code
The source code for DScanner has a complete lexer, parser, and abstact syntax The source code for DScanner has a complete lexer, parser, and abstact syntax
tree library for D code under the stdx/d/ directory. It is intended that these tree library for D code under the std/d/ directory. It is intended that these
modules eventually end up in Phobos, so feel free to use them for your own D modules eventually end up in Phobos, so feel free to use them for your own D
tools. tools.

View File

@ -1314,8 +1314,9 @@ class XMLPrinter : ASTVisitor
case tok!"stringLiteral": tagName = "stringLiteral"; break; case tok!"stringLiteral": tagName = "stringLiteral"; break;
case tok!"dstringLiteral": tagName = "dstringLiteral"; break; case tok!"dstringLiteral": tagName = "dstringLiteral"; break;
case tok!"wstringLiteral": tagName = "wstringLiteral"; break; case tok!"wstringLiteral": tagName = "wstringLiteral"; break;
case tok!"scriptLine": tagName = "scriptLine"; break;
case tok!"$": output.writeln("<dollar/>"); return; case tok!"$": output.writeln("<dollar/>"); return;
default: output.writeln("<", str(token.type), "/>"); return; default: tagName = "token"; break;
} }
output.writeln("<", tagName, ">", xmlEscape(token.text), "</", tagName, ">"); output.writeln("<", tagName, ">", xmlEscape(token.text), "</", tagName, ">");
} }

View File

@ -24,8 +24,8 @@ dmd\
# astprinter.d\ # astprinter.d\
# formatter.d\ # formatter.d\
# outliner.d\ # outliner.d\
# stdx/*.d\ # std/*.d\
# stdx/d/*.d\ # std/d/*.d\
# analysis/*.d\ # analysis/*.d\
# -O3 -frelease -fno-bounds-check\ # -O3 -frelease -fno-bounds-check\
# -odscanner\ # -odscanner\
@ -39,8 +39,8 @@ dmd\
# astprinter.d\ # astprinter.d\
# formatter.d\ # formatter.d\
# outliner.d\ # outliner.d\
# stdx/*.d\ # std/*.d\
# stdx/d/*.d\ # std/d/*.d\
# analysis/*.d\ # analysis/*.d\
# -O3 -release\ # -O3 -release\
# -oq -of=dscanner\ # -oq -of=dscanner\

25
ctags.d
View File

@ -90,6 +90,26 @@ class CTagsPrinter : ASTVisitor
context = c; context = c;
} }
override void visit(const Constructor dec)
{
tagLines ~= "this\t%s\t%d;\"\tf\tarity:%d%s\n".format(fileName,
dec.line, dec.parameters.parameters.length, context);
auto c = context;
context = "\tfunction: this";
dec.accept(this);
context = c;
}
override void visit(const Destructor dec)
{
tagLines ~= "~this\t%s\t%d;\"\tf%s\n".format(fileName, dec.line,
context);
auto c = context;
context = "\tfunction: this";
dec.accept(this);
context = c;
}
override void visit(const EnumDeclaration dec) override void visit(const EnumDeclaration dec)
{ {
if (dec.name == tok!"") if (dec.name == tok!"")
@ -136,6 +156,11 @@ class CTagsPrinter : ASTVisitor
dec.accept(this); dec.accept(this);
} }
override void visit(const Invariant dec)
{
tagLines ~= "invariant\t%s\t%d;\"\tv%s\n".format(fileName, dec.line, context);
}
alias visit = ASTVisitor.visit; alias visit = ASTVisitor.visit;
string fileName; string fileName;

View File

@ -9,7 +9,7 @@
{ {
"name": "library", "name": "library",
"targetType": "library", "targetType": "library",
"sourcePaths": ["stdx"], "sourcePaths": ["std"],
}, },
{ {
"name": "dscanner", "name": "dscanner",

View File

@ -49,6 +49,8 @@ html { background-color: #fdf6e3; color: #002b36; }
writeSpan("num", t.text); writeSpan("num", t.text);
else if (isOperator(t.type)) else if (isOperator(t.type))
writeSpan("op", str(t.type)); writeSpan("op", str(t.type));
else if (t.type == tok!"specialTokenSequence" || t.type == tok!"scriptLine")
writeSpan("cons", t.text.replace("<", "&lt;"));
else else
{ {
version(Windows) version(Windows)

1
main.d
View File

@ -101,6 +101,7 @@ int main(string[] args)
config.whitespaceBehavior = WhitespaceBehavior.include; config.whitespaceBehavior = WhitespaceBehavior.include;
config.stringBehavior = StringBehavior.source; config.stringBehavior = StringBehavior.source;
config.commentBehavior = CommentBehavior.include; config.commentBehavior = CommentBehavior.include;
config.specialTokenBehavior = SpecialTokenBehavior.include;
auto tokens = byToken(bytes, config, cache); auto tokens = byToken(bytes, config, cache);
if (highlight) if (highlight)
{ {

View File

@ -2860,7 +2860,7 @@ private struct BasicRegion(uint minAlign = platformAlignment)
static if (minAlign > 1) static if (minAlign > 1)
{ {
auto newStore = cast(void*) roundUpToMultipleOf( auto newStore = cast(void*) roundUpToMultipleOf(
cast(ulong) store.ptr, cast(size_t) store.ptr,
alignment); alignment);
assert(newStore <= store.ptr + store.length); assert(newStore <= store.ptr + store.length);
_current = newStore; _current = newStore;
@ -2904,7 +2904,7 @@ private struct BasicRegion(uint minAlign = platformAlignment)
// Just bump the pointer to the next good allocation // Just bump the pointer to the next good allocation
auto save = _current; auto save = _current;
_current = cast(void*) roundUpToMultipleOf( _current = cast(void*) roundUpToMultipleOf(
cast(ulong) _current, a); cast(size_t) _current, a);
if (auto b = allocate(bytes)) return b; if (auto b = allocate(bytes)) return b;
// Failed, rollback // Failed, rollback
_current = save; _current = save;
@ -3064,7 +3064,7 @@ struct InSituRegion(size_t size, size_t minAlign = platformAlignment)
{ {
assert(!_crt); assert(!_crt);
_crt = cast(void*) roundUpToMultipleOf( _crt = cast(void*) roundUpToMultipleOf(
cast(ulong) _store.ptr, alignment); cast(size_t) _store.ptr, alignment);
_end = _store.ptr + _store.length; _end = _store.ptr + _store.length;
} }
@ -3109,7 +3109,7 @@ struct InSituRegion(size_t size, size_t minAlign = platformAlignment)
// Just bump the pointer to the next good allocation // Just bump the pointer to the next good allocation
auto save = _crt; auto save = _crt;
_crt = cast(void*) roundUpToMultipleOf( _crt = cast(void*) roundUpToMultipleOf(
cast(ulong) _crt, a); cast(size_t) _crt, a);
if (auto b = allocate(bytes)) return b; if (auto b = allocate(bytes)) return b;
// Failed, rollback // Failed, rollback
_crt = save; _crt = save;

View File

@ -1239,7 +1239,9 @@ public:
} }
/** */ MemberFunctionAttribute[] memberFunctionAttributes; /** */ MemberFunctionAttribute[] memberFunctionAttributes;
/** */ FunctionBody functionBody; /** */ FunctionBody functionBody;
/** */ size_t location; /** */ size_t line;
/** */ size_t column;
/** */ size_t index;
/** */ string comment; /** */ string comment;
mixin OpEquals; mixin OpEquals;
} }
@ -1780,6 +1782,8 @@ public:
} }
/** */ BlockStatement blockStatement; /** */ BlockStatement blockStatement;
/** */ string comment; /** */ string comment;
size_t line;
size_t index;
mixin OpEquals; mixin OpEquals;
} }
@ -1952,8 +1956,9 @@ final class Module : ASTNode
public: public:
override void accept(ASTVisitor visitor) const override void accept(ASTVisitor visitor) const
{ {
mixin (visitIfNotNull!(moduleDeclaration, declarations)); mixin (visitIfNotNull!(scriptLine, moduleDeclaration, declarations));
} }
/** */ Token scriptLine;
/** */ ModuleDeclaration moduleDeclaration; /** */ ModuleDeclaration moduleDeclaration;
/** */ Declaration[] declarations; /** */ Declaration[] declarations;
mixin OpEquals; mixin OpEquals;

View File

@ -41,7 +41,7 @@ private enum dynamicTokens = [
"whitespace", "doubleLiteral", "floatLiteral", "idoubleLiteral", "whitespace", "doubleLiteral", "floatLiteral", "idoubleLiteral",
"ifloatLiteral", "intLiteral", "longLiteral", "realLiteral", "ifloatLiteral", "intLiteral", "longLiteral", "realLiteral",
"irealLiteral", "uintLiteral", "ulongLiteral", "characterLiteral", "irealLiteral", "uintLiteral", "ulongLiteral", "characterLiteral",
"dstringLiteral", "stringLiteral", "wstringLiteral", "scriptLine" "dstringLiteral", "stringLiteral", "wstringLiteral"
]; ];
private enum pseudoTokenHandlers = [ private enum pseudoTokenHandlers = [
@ -119,6 +119,18 @@ public enum WhitespaceBehavior : ubyte
/// Whitespace is treated as a token /// Whitespace is treated as a token
include include
} }
/**
* Configure special token handling behavior
*/
public enum SpecialTokenBehavior : ubyte
{
/// Special tokens are skipped
skip,
/// Special tokens are treated as a token
include
}
/** /**
* Configure comment handling behavior * Configure comment handling behavior
*/ */
@ -136,6 +148,7 @@ public struct LexerConfig
StringBehavior stringBehavior; StringBehavior stringBehavior;
WhitespaceBehavior whitespaceBehavior; WhitespaceBehavior whitespaceBehavior;
CommentBehavior commentBehavior; CommentBehavior commentBehavior;
SpecialTokenBehavior specialTokenBehavior;
} }
public bool isBasicType(IdType type) nothrow pure @safe public bool isBasicType(IdType type) nothrow pure @safe
@ -434,6 +447,7 @@ public struct DLexer
} }
do _popFront(); while (front == tok!"comment"); do _popFront(); while (front == tok!"comment");
if (front == tok!"whitespace") goto case tok!"whitespace"; if (front == tok!"whitespace") goto case tok!"whitespace";
if (front == tok!"specialTokenSequence") goto case tok!"specialTokenSequence";
} }
break; break;
case tok!"whitespace": case tok!"whitespace":
@ -441,6 +455,15 @@ public struct DLexer
{ {
do _popFront(); while (front == tok!"whitespace"); do _popFront(); while (front == tok!"whitespace");
if (front == tok!"comment") goto case tok!"comment"; if (front == tok!"comment") goto case tok!"comment";
if (front == tok!"specialTokenSequence") goto case tok!"specialTokenSequence";
}
break;
case tok!"specialTokenSequence":
if (config.specialTokenBehavior == SpecialTokenBehavior.skip)
{
do _popFront(); while (front == tok!"specialTokenSequence");
if (front == tok!"comment") goto case tok!"comment";
if (front == tok!"whitespace") goto case tok!"whitespace";
} }
break; break;
default: default:

View File

@ -1976,6 +1976,9 @@ class ClassFour(A, B) if (someTest()) : Super {}}c;
node.comment = comment; node.comment = comment;
comment = null; comment = null;
if (expect(tok!"~") is null) return null; if (expect(tok!"~") is null) return null;
node.index = current.index;
node.line = current.line;
node.column = current.column;
if (expect(tok!"this") is null) return null; if (expect(tok!"this") is null) return null;
if (expect(tok!"(") is null) return null; if (expect(tok!"(") is null) return null;
if (expect(tok!")") is null) return null; if (expect(tok!")") is null) return null;
@ -2281,7 +2284,7 @@ class ClassFour(A, B) if (someTest()) : Super {}}c;
{ {
if (!canBeRange) if (!canBeRange)
{ {
error(`Cannot have more than one foreach varible for a foreach range statement`); error(`Cannot have more than one foreach variable for a foreach range statement`);
return null; return null;
} }
advance(); advance();
@ -3184,6 +3187,8 @@ interface "Four"
Invariant parseInvariant() Invariant parseInvariant()
{ {
auto node = allocate!Invariant; auto node = allocate!Invariant;
node.index = current.index;
node.line = current.line;
if (expect(tok!"invariant") is null) return null; if (expect(tok!"invariant") is null) return null;
if (currentIs(tok!"(")) if (currentIs(tok!"("))
{ {
@ -3556,7 +3561,7 @@ invariant() foo();
mixin(traceEnterAndExit!(__FUNCTION__)); mixin(traceEnterAndExit!(__FUNCTION__));
Module m = allocate!Module; Module m = allocate!Module;
if (currentIs(tok!"scriptLine")) if (currentIs(tok!"scriptLine"))
advance(); m.scriptLine = advance();
if (currentIs(tok!"module")) if (currentIs(tok!"module"))
m.moduleDeclaration = parseModuleDeclaration(); m.moduleDeclaration = parseModuleDeclaration();
while (moreTokens()) while (moreTokens())

View File

@ -33,7 +33,7 @@
* ) * )
* Examples: * Examples:
* $(UL * $(UL
* $(LI A _lexer for D is available $(LINK2 https://github.com/Hackerpilot/Dscanner/blob/master/stdx/d/lexer.d, here).) * $(LI A _lexer for D is available $(LINK2 https://github.com/Hackerpilot/Dscanner/blob/master/std/d/lexer.d, here).)
* $(LI A _lexer for Lua is available $(LINK2 https://github.com/Hackerpilot/lexer-demo/blob/master/lualexer.d, here).) * $(LI A _lexer for Lua is available $(LINK2 https://github.com/Hackerpilot/lexer-demo/blob/master/lualexer.d, here).)
* $(LI A _lexer for JSON is available $(LINK2 https://github.com/Hackerpilot/lexer-demo/blob/master/jsonlexer.d, here).) * $(LI A _lexer for JSON is available $(LINK2 https://github.com/Hackerpilot/lexer-demo/blob/master/jsonlexer.d, here).)
* ) * )