#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct tree_node {
char* value;
struct tree_node *children; /* head pointer of children list */
struct tree_node *next; /* next peer in child list */
}TreeNode;
/* local protos */
void traverse(TreeNode*);
TreeNode *talloc(const char*);
TreeNode *talloc(const char *value)
{
TreeNode *t = (TreeNode*) malloc(sizeof(TreeNode));
t->value = strdup(value);
t->children = NULL;
t->next = NULL;
return t;
}
void traverse(TreeNode* t)
{
puts(t->value);
TreeNode *c;
for ( c = t->children; c; c = c->next)
traverse©;
}
int main(void)
{
TreeNode *root = talloc("Root");
TreeNode *branch1 = talloc("BranchA");
TreeNode *child1 = talloc(" ChildA");
TreeNode *branch2 = talloc("BranchB");
TreeNode *child2 = talloc(" ChildB");
branch1->children = child1;
branch2->children = child2;
branch1->next = branch2;
root->children = branch1;
traverse(root);
}
Root
BranchA
ChildA
BranchB
ChildB
static int foo()
TreeNode( const string& v ) { value = v; };
#!/usr/bin/ruby1.9
# Lexical Analyzer
#
class Lex
def initialize()
@list = []
@tokens = {
'def' => :define,
'if' => :if,
'then' => :then,
'end' => :end,
'else' => :else,
'do' => :do,
'while' => :while,
'loop' => :loop,
'case' => :case,
'nil' => :nil,
'null' => :null,
'void' => :void,
?'' => :smallquote, # double '' and "" to humor the mudbytes syntax highlighter :)
?"" => :quote,
';' => :semicol,
'{' => :opencurley,
'}' => :closecurley,
'[' => :openbracket,
']' => :closebracket,
'(' => :openparen,
')' => :closeparen,
'+' => :op_plus,
'-' => :op_minus,
'*' => :op_times,
'/' => :op_divide,
'=' => :op_equals,
'==' => :op_isequal,
'.' => :op_deref_dot,
'->' => :op_deref_arrow,
'::' => :op_scope,
}
end
def tokenize()
for s in @pile
if @tokens[s]
@list << @tokens[s]
else
@list << "identifier [#{s}]"
end
end
end
def scan(str)
[?(, ?), ?., ?{, ?}, ?[, ?], ?;, "'", "->", "::"].each {|c| str.gsub!(c, " #{c} ")}
@pile = str.split(' ')
tokenize()
output()
end
def output()
puts "\nLexemes:\n__________________"
@list.each {|s| puts ":#{s}"}
end
end
code = "def main(ch)\n"
code << "{\n"
code << " if ch.level = 34\n"
code << " {\n"
code << " Server::sendGreeting(ch.name());\n"
code << " }\n"
code << "}"
puts "Original Code:\n\n" + code
Lex.new.scan(code)
Original Code:
def main(ch)
{
if ch.level = 34
{
Server::sendGreeting(ch.name());
}
}
Lexemes:
__________________
:define
:identifier [main]
:openparen
:identifier [ch]
:closeparen
:opencurley
:if
:identifier [ch]
:op_deref_dot
:identifier [level]
:op_equals
:identifier [34]
:opencurley
:identifier [Server]
:op_scope
:identifier [sendGreeting]
:openparen
:identifier [ch]
:op_deref_dot
:identifier [name]
:openparen
:closeparen
:closeparen
:semicol
:closecurley
:closecurley
I came up with the following solution in C++ to see how it might work:
A vector works nice as it keeps track of the nodes that are children of the current node.
This is obviously not useful, other than the fact that it helps me understand more how the recursive
algorithm goes through each node and respective children. I still want to create my own scripting language,
but I see the benefit in creating it in C, and not C++. I would like a similar solution in C to practice with, but
without the vector / list I cant figure out how to go about it.
Say I was to make the "children" variable a pointer to the "next" TreeNode? Say you have Node-A, which has 2 children:
Child-A and Child-B, both "A" and "B" are peers in a sense, they both have the same parent node. Well, if the list was just a C-Style linked list, then Child-B would in essence be Child-A's child, not Node-A's.
I thought about adding a pointer called "next" calling the next child in the subset, but haven't decided if that would make
the most sense.