r++
Steven T. Hatton
hattons at globalsymmetry.com
Thu Aug 25 06:19:05 UTC 2005
I have so many thoughts and questions on this subject that I could write a
book. I guess I should probably take it one piece at a time. First let me
point out that I have found a very nice discussion of the subject of syntax
and parsing here:
http://cs.wwc.edu/~aabyan/PLBook/HTML/Syntax.html
When I went to copy the link, I tried to get to the top of the book and found
there is more here than I originally thought. What I had been reading looks
to be an older version. There appears to be two (or more) separate books,
and at least two version of the Programming Languages book.
What I had been looking at is rooted here:
http://cs.wwc.edu/~aabyan/PLBook/HTML/
There seems to be a more recent version here:
http://cs.wwc.edu/~aabyan/PLBook/book/node8.html
(I don't like the info-style layout as much as the free-flow of the older
version FWIW.)
Then there's another book:
http://www.cs.wwc.edu/~aabyan/Logic/index.html
The Logical Foundations of Computer Science and Mathematics
That is the Queen of the Sciences!
Now, here's my question for Robe, or for anyone else who cares to address it.
I now realize there are two distinct sets of nodes in a generalized parse
tree. There are abstract nodes, and there are concrete nodes. The abstract
nodes do not immediately represent tokens in the parsed language.
Interestingly, two abstract nodes can represent the exact same range of
terminals. To expose this I hacked on Robe's DumpTree code a bit to create a
poor-man's XML dumper:
// XmlDumpTree.h
#ifndef XMLDUMPTREE_H
#define XMLDUMPTREE_H
#include "default_visitor.h"
#include "XmlDumpTree.h"
#include <iostream>
class XmlDumpTree: protected DefaultVisitor {
public:
XmlDumpTree(std::ostream &out_ = std::cout, unsigned char indent_ = 2);
void dump(AST *node) { visit(node); }
protected:
virtual void visit(AST *node);
private:
std::ostream &_out;
unsigned char _indent;
};
#endif // XMLDUMPTREE_H
// XmlDumpTree.cpp
#include "XmlDumpTree.h" //N.B. the mixed case.
#include <iostream>
static char const * const names[] = {
0,
"AccessSpecifier",
"AsmDefinition",
"BaseClause",
"BaseSpecifier",
"BinaryExpression",
"CastExpression",
"ClassMemberAccess",
"ClassSpecifier",
"CompoundStatement",
"Condition",
"ConditionalExpression",
"CppCastExpression",
"CtorInitializer",
"DeclarationStatement",
"Declarator",
"DeleteExpression",
"DoStatement",
"ElaboratedTypeSpecifier",
"EnumSpecifier",
"Enumerator",
"ExceptionSpecification",
"ExpressionOrDeclarationStatement",
"ExpressionStatement",
"ForStatement",
"FunctionCall",
"FunctionDefinition",
"IfStatement",
"IncrDecrExpression",
"InitDeclarator",
"Initializer",
"InitializerClause",
"LabeledStatement",
"LinkageBody",
"LinkageSpecification",
"MemInitializer",
"Name",
"Namespace",
"NamespaceAliasDefinition",
"NewDeclarator",
"NewExpression",
"NewInitializer",
"NewTypeId",
"Operator",
"OperatorFunctionId",
"ParameterDeclaration",
"ParameterDeclarationClause",
"PostfixExpression",
"PrimaryExpression",
"PtrOperator",
"PtrToMember",
"ReturnStatement",
"SimpleDeclaration",
"SimpleTypeSpecifier",
"SizeofExpression",
"StringLiteral",
"SubscriptExpression",
"SwitchStatement",
"TemplateArgument",
"TemplateDeclaration",
"TemplateParameter",
"ThrowExpression",
"TranslationUnit",
"TryBlockStatement",
"TypeId",
"TypeIdentification",
"TypeParameter",
"Typedef",
"UnaryExpression",
"UnqualifiedName",
"Using",
"UsingDirective",
"WhileStatement",
"WinDeclSpec"
};
XmlDumpTree::XmlDumpTree(std::ostream &out_, unsigned char indent_)
: _out(out_)
, _indent(indent_)
{}
void XmlDumpTree::visit(AST *node) {
static int _indent = 0;
if (node) _out
<<std::string(_indent * 2, ' ')<<"<"<<names[node->kind]
<<" \"start="<<node->start_token<<"\""
<<" \"end="<<node->end_token<<"\">"<<"\n";
++_indent;
DefaultVisitor::visit(node);
--_indent;
if (node) _out<<std::string(_indent * 2, '
')<<"</"<<names[node->kind]<<">"<<'\n';
}
$ diff main.cpp /download/org/kdevelop/kdevelop-4/parser/main.cpp
26c26
< #include "XmlDumpTree.h"
---
> #include "dumptree.h"
61,64c61,65
< if (ast && dump) {
< XmlDumpTree dump(std::cout);
< dump.dump(ast);
< }
---
> if (ast && dump)
> {
> DumpTree dump(std::cout);
> dump.dump(ast);
> }
// HelloWorld.cpp
#include <iostream>
int main () {
std::cout<<"Hello World"<<std::endl;
}
./r++0 -dump HelloWorld.cpp
<TranslationUnit "start=0" "end=16">
<FunctionDefinition "start=0" "end=16">
<SimpleTypeSpecifier "start=0" "end=1">
</SimpleTypeSpecifier>
<InitDeclarator "start=1" "end=4">
<Declarator "start=1" "end=4">
<Name "start=1" "end=2">
<UnqualifiedName "start=1" "end=2">
</UnqualifiedName>
</Name>
<ParameterDeclarationClause "start=3" "end=3">
</ParameterDeclarationClause>
</Declarator>
</InitDeclarator>
<CompoundStatement "start=4" "end=16">
<ExpressionStatement "start=5" "end=15">
<BinaryExpression "start=5" "end=14">
<BinaryExpression "start=5" "end=10">
<PostfixExpression "start=5" "end=8">
<PrimaryExpression "start=5" "end=8">
<Name "start=5" "end=8">
<UnqualifiedName "start=5" "end=6">
</UnqualifiedName>
<UnqualifiedName "start=7" "end=8">
</UnqualifiedName>
</Name>
</PrimaryExpression>
</PostfixExpression>
<PostfixExpression "start=9" "end=10">
<PrimaryExpression "start=9" "end=10">
<StringLiteral "start=9" "end=10">
</StringLiteral>
</PrimaryExpression>
</PostfixExpression>
</BinaryExpression>
<PostfixExpression "start=11" "end=14">
<PrimaryExpression "start=11" "end=14">
<Name "start=11" "end=14">
<UnqualifiedName "start=11" "end=12">
</UnqualifiedName>
<UnqualifiedName "start=13" "end=14">
</UnqualifiedName>
</Name>
</PrimaryExpression>
</PostfixExpression>
</BinaryExpression>
</ExpressionStatement>
</CompoundStatement>
</FunctionDefinition>
</TranslationUnit>
Notice how
<PostfixExpression "start=11" "end=14">
<PrimaryExpression "start=11" "end=14">
<Name "start=11" "end=14">
all share the same token range. I assume that means [11,14).
My question is this: do any of the nodes in the parse tree formally represent
the concrete tokens in the source code being parsed? Can these be easily
identified? Is it simply a matter of determining if they are terminals?
--
Regards,
Steven
More information about the KDevelop-devel
mailing list