using System.Linq; using System.Collections.Generic; using System.Text; namespace TLang { public class Parser { private static bool _checkForArrayType(ref int i,List tokens) { if(i+2 < tokens.Count && tokens[i+1].Type == LexSymbol.Symbol && tokens[i+2].Type == LexSymbol.Symbol && tokens[i+1].TokenText == "[" && tokens[i+2].TokenText == "]") { //we are getting somewhere //type normal parse //type [ ] normal parse i+=2; return true; } return false; } public static ProgramNode Parse(List tokens) { ProgramNode node=new ProgramNode(); //function pointers are //funcptr func identifer (arg_type arg_name, ...); //funcptr // a function can be // func identifier (arg_type arg_name,...) // return_type identifier (arg_type arg_name, ...) // func identifier (arg_type arg_name) // return_type identifier (arg_type arg_name) // func identifier () // return_type identifier () //a const variable can be (also in func) //variable_type identifier; //variable_type identifier = expression; int i = 0; for(;i tokens) { i++; List argumentNodes = new List(); //type arg,type arg for(;i tokens) { //if(EXPRESSION) {} else {} //if(EXPRESSION) {} //while {} //break; //return EXPRESSION; //TYPE VARNAME = EXPRESSION; //VARNAME = EXPRESSION; //FUNCNAME(EXPRESSION,...) LexToken type_token_keyword_token = tokens[i]; if(type_token_keyword_token.Type == LexSymbol.Symbol && type_token_keyword_token.TokenText == "{") { ScopeNode node=new ScopeNode(); i++; for(;i tokens,FunctionNode node) { node.Body=ParseStatement(ref i,tokens); } private static Expression ParseExpression(ref int i, List tokens) { //Console.WriteLine(tokens[i].TokenText); //an expression can be //number //char //string //function_call //bool //variable //function call //method_name(expression ...) LexToken identifer = tokens[i]; if(identifer.Type == LexSymbol.Integer) { i++; return new ConstInt(identifer.TokenText); } if(identifer.Type == LexSymbol.Float) { i++; return new ConstFloat(identifer.TokenText); } if(identifer.Type == LexSymbol.Char) { i++; return new ConstChar(identifer.TokenText); } if(identifer.Type == LexSymbol.String) { i++; return new ConstString(identifer.TokenText); } //either function call or identifer if(identifer.Type == LexSymbol.Identifier) { if(i+1 args=new List(); Console.WriteLine(tokens[i].TokenText); i+=2; for(;i Arguments {get;set;} public override NodeType Type {get{return NodeType.CallMethod;}} public FunctionCallNode(string tokenText, List args) { Name = tokenText; Arguments = args; } } public class ConstFloat : Expression { public override string ToString() { return $"Const Float: {Text}"; } public override NodeType Type {get{return NodeType.ConstFloat;}} public string Text {get;set;} public ConstFloat(string tokenText) { Text = tokenText; } } public class ConstInt : Expression { public override string ToString() { return $"Const Int: {Text}"; } public string Text {get;set;} public ConstInt(string tokenText) { Text = tokenText; } public override NodeType Type {get{return NodeType.ConstInt;}} } public class ProgramNode : Node { public override NodeType Type {get {return NodeType.Program;}} public ProgramNode() { Functions=new List(); Variables=new List(); } public List Functions {get;set;} public List Variables {get;set;} public override string ToString() { StringBuilder funcs=new StringBuilder(); foreach(var args in Functions) { funcs.Append($"{args}\n"); } StringBuilder vars = new StringBuilder(); foreach(var args in Variables) { vars.Append($"{args}\n"); } return $"Program:\nFunctions:\n{TabOver(funcs.ToString())}\nGlobal Variables:\n{TabOver(vars.ToString())}"; } } public class VariableDeclarationNode : Node { public string Name {get;set;}=""; public string VariableType {get;set;}=""; public Expression InitialValue {get;set;}=new UninitNode(); public override NodeType Type {get{return NodeType.VariableCreate;}} public override string ToString() { return $"Variable declared with name: {Name}\nType: {VariableType}\nInitial Value:\n{TabOver(InitialValue.ToString())}"; } } public class ArgumentNode : Node { public override NodeType Type {get {return NodeType.Arguments;}} public string ArgType {get;set;}=""; public string Name {get;set;}=""; public override string ToString() { return $"ArgType: {ArgType}\nName: {Name}"; } } public class ScopeNode : Node { public List Nodes {get;set;}=new List(); public override NodeType Type {get{return NodeType.Scope;}} public override string ToString() { StringBuilder b=new StringBuilder(); foreach(var node in Nodes) { b.Append(node.ToString()+"\n"); } return $"Scope:\n{TabOver(b.ToString())}"; } } public class FunctionNode : Node { public override string ToString() { StringBuilder b=new StringBuilder(); int i=0; foreach(var args in Arguments) { b.Append($"args[{i}]: {args}\n"); i++; } return $"Function: {Name}\nReturn Type: {ReturnType}\nArguments:\n{TabOver(b.ToString())}\nBody:{TabOver(Body.ToString())}"; } public string ReturnType {get;set;}=""; public override NodeType Type {get {return NodeType.Function;}} public string Name {get;set;}=""; public Node Body {get;set;} public List Arguments {get;set;}=new List(); } public enum NodeType { ConstInt=0, ConstFloat=1, ConstString=2, ConstChar=3, VariableCreate=4, GetVariableValue=5, SetVariableValue=6, CallMethod=7, Return=8, Function=9, Program=10, Arguments=11, Uninit=12, GetArrayValue=13, Scope=14, If=15, Else=16, While=17, Break=18, } public abstract class Expression : Node { public override string ToString() { return $"Expression {base.ToString()}"; } } public class UninitNode : Expression { public override string ToString() { return $"Uninitilized {base.ToString()}"; } public override NodeType Type {get {return NodeType.Uninit;}} } public abstract class Node { public override string ToString() { return $"Node:\nFilePosition: {FilePosition}\nColumn: {Column}\nLine: {Line}"; } protected string TabOver(string text) { StringBuilder b=new StringBuilder(); foreach(var txt in text.Split('\n')) { b.Append($"\t{txt}\n"); } return b.ToString(); } public abstract NodeType Type {get;} public int FilePosition {get;set;} public int Column {get;set;} public int Line {get;set;} } }