pascalabcnet/Parsers/PascalABCParserNew/ABCPascalParserTools.cs
Бондарев Иван e6e67c193c initial commit
2015-05-14 21:35:07 +02:00

687 lines
28 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using System.Collections.Generic;
using PascalABCCompiler.SyntaxTree;
using PascalABCCompiler.Errors;
using QUT.Gppg;
using GPPGParserScanner;
using System;
namespace PascalABCNewParser
{
public class Union
{
public access_modifer_node amn;
public addressed_value av;
public array_const ac;
public assign a;
public attribute_list al;
public attribute at;
public block b;
public bool bo;
public case_node cn;
public case_variant cv;
public case_variants cvs;
public class_body cb;
public class_definition cld;
public const_definition cd;
public const_node con;
public consts_definitions_list cdl;
public class_members cm;
public declaration d1;
public declarations d;
public enumerator en;
public enumerator_list enl;
public exception_block eb;
public exception_handler eh;
public exception_handler_list ehl;
public exception_ident ei;
public expression ex; // !
public expression_as_statement eas;
public expression_list el; // !
public external_directive ed;
public file_type ft;
public for_cycle_type fct;
public for_node fn;
public foreach_stmt fes;
public format_expr fe;
public formal_parameters fp;
public get_address ga;
public goto_statement gs;
public ident id; // !
public ident_list il;
public if_node ifn;
public implementation_node ind;
public indexers_types it;
public initfinal_part ifp;
public inherited_message im;
public interface_node inn;
public label_definitions lds;
public List<object> lo;
public literal lit;
public literal_const_line lcn;
public lock_stmt ls;
public method_name mn;
public named_type_reference ntr;
public named_type_reference_list ntrl;
public new_expr nex;
public Object ob; // !
public op_type_node op;
public op_typecast opt;
public operator_name_ident oni;
public pascal_set_constant psc;
public property_accessors pa;
public property_array_default pad;
public property_parameter pp;
public property_parameter_list ppl;
public procedure_attribute pat;
public procedure_attributes_list pal;
public procedure_call pc;
public procedure_definition pd;
public procedure_header ph;
public program_name pn;
public program_module pm;
public property_interface pint;
public question_colon_expression qce;
public raise_stmt rs;
public record_const rc;
public record_const_definition rcd;
public ref_type rt;
public repeat_node rn;
public set_type_definition std;
public simple_property sp;
public statement st; // !
public statement_list sl;
public string_const sconst;
public syntax_tree_node node;
public simple_attribute_list sal;
public sizeof_operator soo;
public string_num_definition snd;
public SyntaxError se;
public template_param_list tpl;
public template_type_reference ttr;
public token_info ti;
public try_handler th;
public try_stmt ts;
public type_declarations tds;
public type_definition td;
public type_definition_list tdl;
public typecast_node tcn;
public typed_parameters tpars;
public typeof_operator too;
public uses_list ul;
public unit_module um;
public unit_name un;
public unit_or_namespace uon;
public using_list ugl;
public var_def_statement vds;
public var_statement vs;
public variable_definitions vd;
public where_definition_list wdl;
public where_definition wd;
public while_node wn;
public with_statement ws;
public default_operator dop;
}
public static class StringResources
{
private static string prefix = "PASCALABCPARSER_";
public static string Get(string Id)
{
string ret = PascalABCCompiler.StringResources.Get(prefix + Id);
if (ret == prefix + Id)
return Id;
else
return ret;
}
}
// Класс глобальных описаний и статических методов
// для использования различными подсистемами парсера и сканера
public class PT // PT - parser tools
{
private const int max_char_const = 0xFFFF;
// SSM: Errors инициализируется в другом месте - сюда только передается!
public List<Error> errors;
public System.Collections.Stack NodesStack; // SSM: для каких-то вспомогательных целей в двух правилах
public bool build_tree_for_brackets = false; // SSM: тоже ерунда какая-то
public string CurrentFileName;
int lambda_num = 0;
public List<function_lambda_definition> pascalABC_lambda_definitions;
public List<var_def_statement> pascalABC_var_statements;
public List<type_declaration> pascalABC_type_declarations;
// TODO: CompilerDirectives по идее сюда еще надо
// Преобразование GPPG LexLocation в наш SourceContext
public PT()
{
NodesStack = new System.Collections.Stack();
pascalABC_lambda_definitions = new List<function_lambda_definition>();
pascalABC_var_statements = new List<var_def_statement>();
pascalABC_type_declarations = new List<type_declaration>();
}
public SourceContext ToSourceContext(LexLocation loc)
{
if (loc != null)
return new SourceContext(loc.StartLine, loc.StartColumn + 1, loc.EndLine, loc.EndColumn);
return null;
}
public string CreateErrorString(params object[] args)
{
string[] ww = new string[args.Length - 1];
for (int i = 1; i < args.Length; i++)
ww[i - 1] = (string)args[i];
string w = string.Join(" или ", ww);
return string.Format("Синтаксическая ошибка: встречено {0}, а ожидалось {1}", args[0], w); // Это неверно - временное исправление
}
public void AddError(string message, LexLocation loc)
{
errors.Add(new SyntaxError(message, CurrentFileName, loc, null));
}
public ident create_directive_name(string text, SourceContext sc)
{
ident dn = new ident(new string(text.ToCharArray(1, text.Length - 1)));
dn.source_context = sc;
return dn;
}
public string ReplaceSpecialSymbols(string text)
{
text = text.Replace("''", "'");
return text;
}
public char_const create_char_const(string text, SourceContext sc)
{
string char_text = new string(text.ToCharArray(1, text.Length - 2));
char_text = ReplaceSpecialSymbols(char_text);
char_const ct = new char_const();
ct.source_context = sc;
if (char_text.Length == 1)
{
ct.cconst = char_text[0];
return ct;
}
return null;
}
public sharp_char_const create_sharp_char_const(string text, SourceContext sc)
{
string int_text = new string(text.ToCharArray(1, text.Length - 1));
sharp_char_const scc = null;
int val = 0;
if (int.TryParse(int_text, out val))
{
if (val > max_char_const)
{
scc = new sharp_char_const(0);
errors.Add(new TooBigCharNumberInSharpCharConstant(CurrentFileName, sc, scc));
}
else
scc = new sharp_char_const(val);
scc.source_context = sc;
}
else
{
errors.Add(new TooBigCharNumberInSharpCharConstant(CurrentFileName, sc, scc));
}
return scc;
}
public const_node create_double_const(string text, SourceContext sc)
{
const_node cn = null;
try
{
System.Globalization.NumberFormatInfo sgnfi = new System.Globalization.NumberFormatInfo();
sgnfi.NumberDecimalSeparator = ".";
double val = double.Parse(text, sgnfi);
cn = new double_const(val);
cn.source_context = sc;
}
catch (Exception)
{
errors.Add(new BadFloat(CurrentFileName, sc, null));
}
return cn;
}
public const_node create_hex_const(string text, SourceContext sc)
{
return create_int_const(text, sc, System.Globalization.NumberStyles.HexNumber);
}
public const_node create_int_const(string text, SourceContext sc)
{
return create_int_const(text, sc, System.Globalization.NumberStyles.Integer);
}
public const_node create_int_const(string text, SourceContext sc, System.Globalization.NumberStyles NumberStyles)
{
//таблица целых констант на уровне синтаксиса
// не может быть - 0 +
// 32--------16----8----|----8----16--------32----------------64(bits)
// [ int64 )[ int32 ]( int64 ]( uint64 ]
if (NumberStyles == System.Globalization.NumberStyles.HexNumber)
text = text.Substring(1);
const_node cn = new int32_const();
if (text.Length < 8)
(cn as int32_const).val = Int32.Parse(text, NumberStyles);
else
{
try
{
UInt64 uint64 = UInt64.Parse(text, NumberStyles);
if (uint64 <= Int32.MaxValue)
(cn as int32_const).val = (Int32)uint64;
else
if (uint64 <= Int64.MaxValue)
cn = new int64_const((Int64)uint64);
else
cn = new uint64_const(uint64);
}
catch (Exception)
{
if (NumberStyles == System.Globalization.NumberStyles.HexNumber)
errors.Add(new BadHex(CurrentFileName, sc, null));
else
errors.Add(new BadInt(CurrentFileName, sc, null));
}
}
cn.source_context = sc;
return cn;
}
public ident create_ident(string text, SourceContext sc)
{
if (text.IndexOf('&') == 0)
text = text.Substring(1);
ident id = new ident(text);
id.source_context = sc;
return id;
}
public procedure_attributes_list AddModifier(procedure_attributes_list proc_list, proc_attribute modif)
{
if (proc_list == null)
proc_list = new procedure_attributes_list();
foreach (procedure_attribute attr in proc_list.proc_attributes)
if (attr.attribute_type == modif)
return proc_list;
proc_list.proc_attributes.Add(new procedure_attribute(modif));
return proc_list;
}
public literal create_string_const(string text, SourceContext sc)
{
literal lt;
if (text.Length == 3 && text[0] == '\'' && text[2] == '\'')
{
lt = new char_const(text[1]);
lt.source_context = sc;
return lt;
}
text = ReplaceSpecialSymbols(text.Substring(1, text.Length - 2));
lt = new string_const(text);
lt.source_context = sc;
return lt;
}
public procedure_definition lambda(function_lambda_definition _function_lambda_definition)
{
procedure_definition _func_def = new procedure_definition();
method_name _method_name1 = new method_name(null, new ident(_function_lambda_definition.lambda_name), null);
//parsertools.create_source_context(_method_name1, _method_name1.meth_name, _method_name1.meth_name);
function_header _function_header1 = new function_header();
object rt1 = new object();
_function_header1.name = _method_name1;
if (_function_header1.name.meth_name is template_type_name)
{
_function_header1.template_args = (_function_header1.name.meth_name as template_type_name).template_args;
ident id = new ident(_function_header1.name.meth_name.name);
//parsertools.create_source_context(id, _function_header1.name.meth_name, _function_header1.name.meth_name);
_function_header1.name.meth_name = id;
}
formal_parameters fps = new PascalABCCompiler.SyntaxTree.formal_parameters();
_function_header1.parameters = _function_lambda_definition.formal_parameters;//fps;
/*SyntaxTree.named_type_reference _named_type_reference = new SyntaxTree.named_type_reference();
SyntaxTree.ident idtype = new SyntaxTree.ident("object");
_named_type_reference.source_context = idtype.source_context;
_named_type_reference.names.Add(idtype);
rt1 = _named_type_reference;
_function_header1.return_type = (SyntaxTree.type_definition)_named_type_reference;*/
_function_header1.return_type = _function_lambda_definition.return_type;
_function_header1.of_object = false;
_function_header1.class_keyword = false;
token_info _token_info = new token_info("function");
//_token_info.source_context = parsertools.GetTokenSourceContext();
//parsertools.create_source_context(_function_header1, _token_info, _token_info);
block _block1 = new block(null, null);
statement_list sl1 = new statement_list();
sl1.subnodes.Add(_function_lambda_definition.proc_body);
_block1.program_code = sl1;
_func_def.proc_header = _function_header1;
_func_def.proc_body = (proc_block)_block1;
if (_function_lambda_definition.defs != null)
{
if (((block)_func_def.proc_body).defs == null)
((block)_func_def.proc_body).defs = new declarations();
for (int l = 0; l < _function_lambda_definition.defs.Count; l++)
((block)_func_def.proc_body).defs.defs.Add(_function_lambda_definition.defs[l] as procedure_definition);
}
_function_lambda_definition.proc_definition = _func_def;
//parsertools.create_source_context(_func_def, _function_header1, _function_header1);
return _func_def;
}
public function_lambda_definition find_pascalABC_lambda_name(string name)
{
int i = 0;
while (i < pascalABC_lambda_definitions.Count && (pascalABC_lambda_definitions[i] == null || ((function_lambda_definition)pascalABC_lambda_definitions[i]).lambda_name != name))
i++;
if (i < pascalABC_lambda_definitions.Count)
return (function_lambda_definition)pascalABC_lambda_definitions[i];
else
return null;
}
public var_def_statement find_var_statements(string name)
{
int i = pascalABC_var_statements.Count - 1;
bool b = false;
while (!b && i >= 0)
{
var_def_statement vds = (var_def_statement)pascalABC_var_statements[i];
int j = 0;
while (j < vds.vars.idents.Count &&
vds.vars.idents[j].name != name)
j++;
if (j < vds.vars.idents.Count)
b = true;
else
i--;
}
if (i >= 0 && i < pascalABC_var_statements.Count &&
((var_def_statement)pascalABC_var_statements[i]).vars_type != null)
return (var_def_statement)pascalABC_var_statements[i];
else
return null;
}
public ident func_decl_lambda(object lr0, object lr2)
{
statement_list _statement_list = (statement_list)lr2;
expression_list _expression_list = new expression_list();
ident_list _i_l = new ident_list();
formal_parameters _formal_parameters = new formal_parameters();
if (lr0 != null)
{
List<object> ar = (List<object>)lr0;
for (int i = 0; i < ar.Count; i++)
if (ar[i] is ident)
_i_l.idents.Add((ident)ar[i]);
else
_i_l.idents.Add(((var_def_statement)ar[i]).vars.idents[0]);
for (int i = 0; i < _i_l.idents.Count; i++)
_expression_list.expressions.Add(_i_l.idents[i]);
for (int i = 0; i < ar.Count; i++)
{
ident_list _ident_list = new ident_list();
ident id = _i_l.idents[i];
_ident_list.idents.Add(id);
string name_param = id.name;
typed_parameters _typed_parameters = null;
int k = 0;
{
named_type_reference _named_type_reference = new named_type_reference();
type_definition t_d = new type_definition();
if (ar[i] is ident)
{
ident idtype = new ident("object");
_named_type_reference.names.Add(idtype);
t_d = (type_definition)_named_type_reference;
}
else
{
t_d = ((var_def_statement)ar[i]).vars_type;
}
_typed_parameters = new typed_parameters(_ident_list, t_d, parametr_kind.none, null);
//parsertools.create_source_context(_typed_parameters, _ident_list, t_d);
}
_formal_parameters.params_list.Add(_typed_parameters);
}
}
//////////////////////////
named_type_reference _named_type_reference1 = new named_type_reference();
ident idtype1 = new ident("object");
_named_type_reference1.source_context = idtype1.source_context;
_named_type_reference1.names.Add(idtype1);
/////////////////////////////
lambda_num++;
function_lambda_definition _procedure_definition = new function_lambda_definition();
_procedure_definition.formal_parameters = _formal_parameters;
_procedure_definition.return_type = (type_definition)_named_type_reference1;
_procedure_definition.ident_list = _i_l;
_procedure_definition.proc_body = null;
_procedure_definition.parameters = _expression_list;
_procedure_definition.lambda_name = "__lambda__" + lambda_num;
//new function_lambda_definition(_formal_parameters, (type_definition)_named_type_reference1, _i_l, null, _expression_list, "lambda" + lambda_num);
object rt = _i_l;
_procedure_definition.proc_body = _statement_list;
//////////////////////////////vnutrennie lambda
if (_procedure_definition.defs == null)
_procedure_definition.defs = new List<object>();
while (pascalABC_lambda_definitions.Count > 0 && pascalABC_lambda_definitions[pascalABC_lambda_definitions.Count - 1] != null)
{
_procedure_definition.defs.Add(lambda((function_lambda_definition)pascalABC_lambda_definitions[pascalABC_lambda_definitions.Count - 1]));
pascalABC_lambda_definitions.RemoveAt(pascalABC_lambda_definitions.Count - 1);
}
if (pascalABC_lambda_definitions.Count > 0 && pascalABC_lambda_definitions[pascalABC_lambda_definitions.Count - 1] == null)
pascalABC_lambda_definitions.RemoveAt(pascalABC_lambda_definitions.Count - 1);
pascalABC_lambda_definitions.Add(_procedure_definition);
///////////////////////////////////////////////
//parsertools.create_source_context(_procedure_definition, _expression_list, rt);
ident _name = new ident(_procedure_definition.lambda_name);
if (lr0 != null)
_name.source_context = _i_l.idents[0].source_context;
return _name;
}
public List<object> ident_list11(object lr1, object lr3)
{
List<object> ar = (List<object>)lr3;
ar.Insert(0, lr1);
return ar;
}
public List<object> ident_list12(object lr0)
{
List<object> ar = new List<object>();
ar.Add(lr0);
return ar;
}
public List<object> ident_list21(object lr0, object lr2)
{
List<object> ar = (List<object>)lr0;
ar.Add(lr2);
return ar;
}
public List<object> ident_list13(object lr1, object lr3, object lr5)
{
List<object> ar = (List<object>)lr5;
//named_type_reference n_t_r = (named_type_reference)lr3;
var_def_statement vds = new var_def_statement();
vds.vars = new ident_list();
vds.vars.idents.Add((ident)lr1);
vds.vars_type = (type_definition)lr3;//n_t_r;
ar.Insert(0, vds);
return ar;
}
public List<object> ident_list14(object lr1, object lr3)
{
List<object> ar = new List<object>();
//named_type_reference n_t_r = (named_type_reference)lr3;
var_def_statement vds = new var_def_statement();
vds.vars = new ident_list();
vds.vars.idents.Add((ident)lr1);
vds.vars_type = (type_definition)lr3;
ar.Add(vds);
return ar;
}
public void add_lambda_to_program_block(block _block)
{
//tasha 16.04.2010
if (pascalABC_lambda_definitions.Count > 0)
{
if (_block.defs == null)
_block.defs = new declarations();
for (int i = 0; i < pascalABC_lambda_definitions.Count; i++)
_block.defs.defs.Add(lambda((function_lambda_definition)pascalABC_lambda_definitions[i]));
pascalABC_lambda_definitions.Clear();
}
}
public void add_lambda(object lr1, procedure_definition _procedure_definition)
{
if (pascalABC_lambda_definitions.Count > 0)//tasha 16.04.2010
{
block _block = (block)lr1;
if (_block.defs == null)
_block.defs = new declarations();
for (int i = 0; i < pascalABC_lambda_definitions.Count; i++)
_block.defs.defs.Add(lambda((function_lambda_definition)pascalABC_lambda_definitions[i]));
pascalABC_lambda_definitions.Clear();
_procedure_definition.proc_body = (proc_block)_block;
}
else
//////////////////////////tasha 16.04.2010
_procedure_definition.proc_body = (proc_block)lr1;
}
public void for_assignment(object lr0, object lr2)
{
if (lr0 is ident && lr2 is ident && ((ident)lr2).name.Contains("__lambda__"))
{
string type_name = "";
var_def_statement vds = find_var_statements(((ident)lr0).name);
if (vds != null)
type_name = ((named_type_reference)vds.vars_type).names[0].name;
if (type_name != "")
{
int ii = 0;
while (ii < pascalABC_type_declarations.Count &&
((type_declaration)pascalABC_type_declarations[ii]).type_name.name != type_name)
ii++;
if (ii < pascalABC_type_declarations.Count)
{
type_definition td = ((type_declaration)pascalABC_type_declarations[ii]).type_def;
function_lambda_definition fld = find_pascalABC_lambda_name(((ident)lr2).name);
fld.return_type = ((function_header)td).return_type;
for (int k = 0; k < fld.formal_parameters.params_list.Count && k < ((function_header)td).parameters.params_list.Count; k++)
fld.formal_parameters.params_list[k].vars_type = ((function_header)td).parameters.params_list[k].vars_type;
}
pascalABC_var_statements.Remove(vds);
}
}
}
public void create_source_context(object to, object left, object right)
{
if (to != null)
((syntax_tree_node)to).source_context = get_source_context(left, right);
}
public SourceContext get_source_context(object left, object right)
{
//debug
/*if (left == null && right!=null)
{
Console.WriteLine("\n\rerror: left is null(create_source_context)!\n\r");
Console.WriteLine(((syntax_tree_node)right).source_context.ToString());
}
if (right == null && left!=null)
{
Console.WriteLine("\n\rerror: right is null(create_source_context)!\n\r");
Console.WriteLine(((syntax_tree_node)left).source_context.ToString());
}
if (((syntax_tree_node)left).source_context == null)
{
Console.WriteLine("\n\rerror: source_context is null!(left)\n\r");
return null;
}
if (((syntax_tree_node)right).source_context == null)
{
Console.WriteLine("\n\rerror: source_context is null!(right)\n\r");
return null;
}
*/
if ((left == null) || (right == null) || (((syntax_tree_node)left).source_context == null) || (((syntax_tree_node)right).source_context == null))
return null;
return new SourceContext(((syntax_tree_node)left).source_context, ((syntax_tree_node)right).source_context);
}
public void create_source_context_left(object to, object left)
{
file_position fp = ((syntax_tree_node)left).source_context.begin_position;
((syntax_tree_node)to).source_context = new SourceContext(fp.line_num, fp.column_num, fp.line_num, fp.column_num, 0, 0);
}
public void create_source_context_right(object to, object right)
{
file_position fp = ((syntax_tree_node)right).source_context.end_position;
((syntax_tree_node)to).source_context = new SourceContext(fp.line_num, fp.column_num, fp.line_num, fp.column_num, 0, 0);
}
public object sc_not_null(object o1, object o2)
{
if (o1 != null)
if (((syntax_tree_node)o1).source_context != null) return o1;
return o2;
}
public object sc_not_null(object o1, object o2, object o3)
{
if (o1 != null)
if (((syntax_tree_node)o1).source_context != null) return o1;
if (o2 != null)
if (((syntax_tree_node)o2).source_context != null) return o2;
return o3;
}
public object sc_not_null(params object[] arr)
{
foreach (object o in arr)
if (o != null)
if (((syntax_tree_node)o).source_context != null) return o;
return null;
}
public void assign_source_context(object to, object from)
{
//debug
//if (((tree_node)from).source_context==null) Console.WriteLine("\n\rerror: from sc is null(assign_source_context)!\n\r");
if (to!=null && from!=null)
((syntax_tree_node)to).source_context = ((syntax_tree_node)from).source_context;
}
}
}