2017-10-25 21:35:32 +03:00
|
|
|
|
using System;
|
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
|
using System.Linq;
|
|
|
|
|
|
using System.Text;
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
|
ProgramScopeSyntax
|
|
|
|
|
|
BlockScopeSyntax
|
|
|
|
|
|
ProcScopeSyntax (name)
|
|
|
|
|
|
ParamsScopeSyntax
|
|
|
|
|
|
BlockScopeSyntax
|
|
|
|
|
|
StatListScopeSyntax (0)
|
|
|
|
|
|
StatListScopeSyntax (1)
|
|
|
|
|
|
StatListScopeSyntax (0)
|
|
|
|
|
|
StatListScopeSyntax (1)
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
namespace PascalABCCompiler.SyntaxTree
|
|
|
|
|
|
{
|
2018-12-14 16:33:59 +03:00
|
|
|
|
// Визитор накопления легковесной синтаксической таблицы символов.
|
|
|
|
|
|
// Не дописан. Имеет большой потенциал применения
|
2017-10-26 19:39:20 +03:00
|
|
|
|
public partial class CollectLightSymInfoVisitor : BaseEnterExitVisitor
|
2017-10-25 21:35:32 +03:00
|
|
|
|
{
|
|
|
|
|
|
public ScopeSyntax Root;
|
2019-06-13 20:41:30 +03:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Текущее пространство имен
|
|
|
|
|
|
/// </summary>
|
2017-10-25 21:35:32 +03:00
|
|
|
|
public ScopeSyntax Current;
|
|
|
|
|
|
|
|
|
|
|
|
public static CollectLightSymInfoVisitor New => new CollectLightSymInfoVisitor();
|
|
|
|
|
|
public override void Enter(syntax_tree_node st)
|
|
|
|
|
|
{
|
|
|
|
|
|
ScopeSyntax t = null;
|
|
|
|
|
|
switch (st)
|
|
|
|
|
|
{
|
|
|
|
|
|
case program_module p:
|
2017-10-26 19:39:20 +03:00
|
|
|
|
case unit_module u:
|
|
|
|
|
|
t = new GlobalScopeSyntax();
|
2017-10-25 21:35:32 +03:00
|
|
|
|
Root = t;
|
|
|
|
|
|
break;
|
|
|
|
|
|
case procedure_definition p:
|
2017-11-16 23:10:30 +03:00
|
|
|
|
var name = p.proc_header?.name?.meth_name;
|
2019-06-15 13:25:44 +03:00
|
|
|
|
if (name == null)
|
|
|
|
|
|
name = "create";
|
2017-11-02 12:21:02 +03:00
|
|
|
|
var attr = p.proc_header.class_keyword ? Attributes.class_attr : 0;
|
2019-06-15 13:25:44 +03:00
|
|
|
|
if (name != null)
|
|
|
|
|
|
if (p.proc_header is function_header)
|
|
|
|
|
|
AddSymbol(name, SymKind.funcname,null, attr);
|
|
|
|
|
|
else AddSymbol(name, SymKind.procname, null, attr);
|
2017-10-26 19:39:20 +03:00
|
|
|
|
t = new ProcScopeSyntax(name);
|
2017-10-25 21:35:32 +03:00
|
|
|
|
break;
|
2019-06-15 13:25:44 +03:00
|
|
|
|
//case formal_parameters p:// Это неправильный Scope - он закрывался при выходе из секции формальных параметров, что неправильно
|
|
|
|
|
|
// t = new ParamsScopeSyntax();
|
|
|
|
|
|
// break;
|
2017-10-25 21:35:32 +03:00
|
|
|
|
case statement_list p:
|
|
|
|
|
|
t = new StatListScopeSyntax();
|
|
|
|
|
|
break;
|
2017-10-26 19:39:20 +03:00
|
|
|
|
case for_node p:
|
|
|
|
|
|
t = new ForScopeSyntax();
|
|
|
|
|
|
break;
|
|
|
|
|
|
case foreach_stmt p:
|
|
|
|
|
|
t = new ForeachScopeSyntax();
|
|
|
|
|
|
break;
|
2017-11-16 23:10:30 +03:00
|
|
|
|
/*case repeat_node p: // не надо т.к. это StatListScope
|
2017-10-26 19:39:20 +03:00
|
|
|
|
t = new RepeatScopeSyntax();
|
|
|
|
|
|
break;*/
|
|
|
|
|
|
case case_node p:
|
|
|
|
|
|
t = new CaseScopeSyntax();
|
|
|
|
|
|
break;
|
|
|
|
|
|
case class_definition p:
|
|
|
|
|
|
var td = p.Parent as type_declaration;
|
2017-11-02 12:21:02 +03:00
|
|
|
|
var tname = td==null ? "NONAME" : td.type_name;
|
|
|
|
|
|
if (p.keyword == class_keyword.Class)
|
|
|
|
|
|
{
|
|
|
|
|
|
AddSymbol(tname, SymKind.classname);
|
|
|
|
|
|
t = new ClassScopeSyntax(tname);
|
|
|
|
|
|
}
|
|
|
|
|
|
else if (p.keyword == class_keyword.Record)
|
|
|
|
|
|
{
|
|
|
|
|
|
AddSymbol(tname, SymKind.recordname);
|
|
|
|
|
|
t = new RecordScopeSyntax(tname);
|
|
|
|
|
|
}
|
|
|
|
|
|
else if (p.keyword == class_keyword.Interface)
|
|
|
|
|
|
{
|
|
|
|
|
|
AddSymbol(tname, SymKind.interfacename);
|
|
|
|
|
|
t = new InterfaceScopeSyntax(tname);
|
|
|
|
|
|
}
|
2017-10-26 19:39:20 +03:00
|
|
|
|
break;
|
|
|
|
|
|
case function_lambda_definition p:
|
|
|
|
|
|
t = new LambdaScopeSyntax();
|
|
|
|
|
|
break;
|
2017-10-25 21:35:32 +03:00
|
|
|
|
}
|
|
|
|
|
|
if (t != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
t.Parent = Current;
|
|
|
|
|
|
if (Current != null)
|
|
|
|
|
|
Current.Children.Add(t);
|
|
|
|
|
|
Current = t;
|
2017-10-26 19:39:20 +03:00
|
|
|
|
if (st is procedure_definition p)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (p.proc_header is function_header fh)
|
|
|
|
|
|
{
|
|
|
|
|
|
AddSymbol(new ident("Result"), SymKind.var, fh.return_type);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2017-10-25 21:35:32 +03:00
|
|
|
|
}
|
2019-06-15 13:25:44 +03:00
|
|
|
|
}
|
|
|
|
|
|
public virtual void PreExitScope(syntax_tree_node st)
|
|
|
|
|
|
{
|
|
|
|
|
|
|
2017-10-25 21:35:32 +03:00
|
|
|
|
}
|
|
|
|
|
|
public override void Exit(syntax_tree_node st)
|
|
|
|
|
|
{
|
|
|
|
|
|
switch (st)
|
|
|
|
|
|
{
|
|
|
|
|
|
case program_module p:
|
|
|
|
|
|
case procedure_definition pd:
|
2019-06-15 13:25:44 +03:00
|
|
|
|
//case formal_parameters fp:
|
2017-10-25 21:35:32 +03:00
|
|
|
|
case statement_list stl:
|
2017-10-26 19:39:20 +03:00
|
|
|
|
case for_node f:
|
|
|
|
|
|
case foreach_stmt fe:
|
|
|
|
|
|
case class_definition cd:
|
|
|
|
|
|
case record_type rt:
|
|
|
|
|
|
case function_lambda_definition fld:
|
|
|
|
|
|
//case repeat_node rep:
|
|
|
|
|
|
case case_node cas:
|
2019-06-15 13:25:44 +03:00
|
|
|
|
PreExitScope(st);
|
2017-10-25 21:35:32 +03:00
|
|
|
|
Current = Current.Parent;
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
public override void visit(var_def_statement vd)
|
|
|
|
|
|
{
|
2017-11-02 12:21:02 +03:00
|
|
|
|
var attr = vd.var_attr == definition_attribute.Static ? Attributes.class_attr : 0;
|
2017-10-25 21:35:32 +03:00
|
|
|
|
if (vd == null || vd.vars == null || vd.vars.list == null)
|
|
|
|
|
|
return;
|
2019-06-13 20:41:30 +03:00
|
|
|
|
AddSymbols(vd.vars.list, SymKind.var, vd.vars_type, attr);
|
2017-10-26 19:39:20 +03:00
|
|
|
|
base.visit(vd);
|
2017-10-25 21:35:32 +03:00
|
|
|
|
}
|
2017-10-26 19:39:20 +03:00
|
|
|
|
public override void visit(formal_parameters fp)
|
2017-10-25 21:35:32 +03:00
|
|
|
|
{
|
2017-10-26 19:39:20 +03:00
|
|
|
|
foreach (var pg in fp.params_list)
|
|
|
|
|
|
{
|
2019-06-13 20:41:30 +03:00
|
|
|
|
AddSymbols(pg.idents.idents, SymKind.param, pg.vars_type);
|
2017-10-26 19:39:20 +03:00
|
|
|
|
}
|
|
|
|
|
|
base.visit(fp);
|
2017-10-25 21:35:32 +03:00
|
|
|
|
}
|
2017-10-26 19:39:20 +03:00
|
|
|
|
|
|
|
|
|
|
public override void visit(for_node f)
|
2017-10-25 21:35:32 +03:00
|
|
|
|
{
|
2017-10-26 19:39:20 +03:00
|
|
|
|
if (f.create_loop_variable || f.type_name != null)
|
|
|
|
|
|
AddSymbol(f.loop_variable, SymKind.var, f.type_name);
|
|
|
|
|
|
base.visit(f);
|
2017-10-25 21:35:32 +03:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|