2024-04-23 10:47:48 +03:00
|
|
|
|
// Copyright (c) Ivan Bondarev, Stanislav Mikhalkovich (for details please see \doc\copyright.txt)
|
|
|
|
|
|
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
|
2015-05-14 22:35:07 +03:00
|
|
|
|
using System;
|
|
|
|
|
|
using System.IO;
|
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
|
using PascalABCCompiler.SyntaxTree;
|
|
|
|
|
|
using PascalABCCompiler.Parsers;
|
2024-05-25 12:26:32 +03:00
|
|
|
|
using PascalABCCompiler;
|
|
|
|
|
|
using Languages.Pascal.Frontend.Core;
|
2024-05-04 20:21:50 +03:00
|
|
|
|
using PascalABCCompiler.ParserTools.Directives;
|
|
|
|
|
|
using static PascalABCCompiler.ParserTools.Directives.DirectiveHelper;
|
2015-05-14 22:35:07 +03:00
|
|
|
|
|
2024-05-25 12:26:32 +03:00
|
|
|
|
namespace Languages.Pascal.Frontend.Wrapping
|
2015-05-14 22:35:07 +03:00
|
|
|
|
{
|
2024-05-09 19:04:31 +03:00
|
|
|
|
// SSM: класс, являющийся обёрткой над GPPG парсером
|
|
|
|
|
|
/*public class GPPGParserHelper
|
2015-05-14 22:35:07 +03:00
|
|
|
|
{
|
|
|
|
|
|
private List<Errors.Error> Errs;
|
2024-05-09 19:04:31 +03:00
|
|
|
|
private List<Errors.CompilerWarning> Warnings;
|
2015-05-14 22:35:07 +03:00
|
|
|
|
private string FileName;
|
2024-05-09 19:04:31 +03:00
|
|
|
|
public bool build_tree_for_formatter = false;
|
|
|
|
|
|
public List<string> DefinesList = null;
|
2015-05-14 22:35:07 +03:00
|
|
|
|
public List<compiler_directive> compilerDirectives;
|
|
|
|
|
|
|
2024-05-09 19:04:31 +03:00
|
|
|
|
public GPPGParserHelper(List<Errors.Error> Errs, List<Errors.CompilerWarning> Warnings, string FileName)
|
2015-05-14 22:35:07 +03:00
|
|
|
|
{
|
|
|
|
|
|
this.Errs = Errs;
|
2024-05-09 19:04:31 +03:00
|
|
|
|
this.Warnings = Warnings;
|
2015-05-14 22:35:07 +03:00
|
|
|
|
this.FileName = FileName;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2024-05-09 19:04:31 +03:00
|
|
|
|
public syntax_tree_node Parse(string Text, List<compiler_directive> compilerDirectives = null)
|
2024-04-23 10:47:48 +03:00
|
|
|
|
{
|
|
|
|
|
|
#if DEBUG
|
|
|
|
|
|
#if _ERR
|
|
|
|
|
|
FileInfo f = new FileInfo(FileName);
|
|
|
|
|
|
var sv = Path.ChangeExtension(FileName,".grmtrack1");
|
|
|
|
|
|
var sw = new StreamWriter(sv);
|
|
|
|
|
|
Console.SetError(sw);
|
|
|
|
|
|
#endif
|
|
|
|
|
|
#endif
|
2024-05-09 19:04:31 +03:00
|
|
|
|
this.compilerDirectives = compilerDirectives;
|
|
|
|
|
|
|
|
|
|
|
|
PT parsertools = new PT(); // контекст сканера и парсера
|
|
|
|
|
|
parsertools.errors = Errs;
|
|
|
|
|
|
parsertools.warnings = Warnings;
|
|
|
|
|
|
parsertools.compilerDirectives = compilerDirectives;
|
|
|
|
|
|
parsertools.CurrentFileName = Path.GetFullPath(FileName);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Scanner scanner = new Scanner();
|
|
|
|
|
|
scanner.SetSource(Text, 0);
|
|
|
|
|
|
scanner.parsertools = parsertools;// передали parsertools в объект сканера
|
|
|
|
|
|
if (DefinesList != null)
|
|
|
|
|
|
scanner.Defines.AddRange(DefinesList);
|
|
|
|
|
|
GPPGParser parser = new GPPGParser(scanner);
|
|
|
|
|
|
parsertools.build_tree_for_formatter = build_tree_for_formatter;
|
|
|
|
|
|
parser.parsertools = parsertools; // передали parsertools в объект парсера
|
|
|
|
|
|
|
|
|
|
|
|
if (!parser.Parse())
|
|
|
|
|
|
if (Errs.Count == 0)
|
|
|
|
|
|
parsertools.AddError("Неопознанная синтаксическая ошибка!", null);
|
2024-04-23 10:47:48 +03:00
|
|
|
|
#if DEBUG
|
|
|
|
|
|
#if _ERR
|
|
|
|
|
|
sw.Close();
|
|
|
|
|
|
#endif
|
|
|
|
|
|
#endif
|
2024-05-09 19:04:31 +03:00
|
|
|
|
return parser.root;
|
2024-04-23 10:47:48 +03:00
|
|
|
|
}
|
2024-05-09 19:04:31 +03:00
|
|
|
|
}*/
|
2024-04-23 10:47:48 +03:00
|
|
|
|
|
2024-05-25 12:26:32 +03:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Основной парсер языка PascalABC.NET. Реализован Саушкиным Романом.
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public class PascalABCNewLanguageParser : BaseParser
|
2024-05-09 19:04:31 +03:00
|
|
|
|
{
|
2015-05-14 22:35:07 +03:00
|
|
|
|
|
|
|
|
|
|
public PascalABCNewLanguageParser()
|
|
|
|
|
|
{
|
2024-05-04 20:21:50 +03:00
|
|
|
|
InitializeValidDirectives();
|
2015-05-14 22:35:07 +03:00
|
|
|
|
}
|
2024-05-04 20:21:50 +03:00
|
|
|
|
|
2015-05-14 22:35:07 +03:00
|
|
|
|
public override void Reset()
|
|
|
|
|
|
{
|
|
|
|
|
|
CompilerDirectives = new List<compiler_directive>();
|
|
|
|
|
|
Errors.Clear();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2024-05-04 20:21:50 +03:00
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Здесь записываются все директивы, поддерживаемые языком, а также правила для проверки их параметров (ограничения, накладываемые со стороны языка)
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
private void InitializeValidDirectives()
|
|
|
|
|
|
{
|
|
|
|
|
|
#region VALID DIRECTIVES
|
|
|
|
|
|
ValidDirectives = new Dictionary<string, DirectiveInfo>(StringComparer.CurrentCultureIgnoreCase)
|
|
|
|
|
|
{
|
|
|
|
|
|
[StringConstants.compiler_directive_apptype] = new DirectiveInfo(SingleAnyOfCheck("console", "windows", "dll", "pcu")),
|
2024-05-05 18:12:35 +03:00
|
|
|
|
[StringConstants.compiler_directive_reference] = new DirectiveInfo(quotesAreSpecialSymbols: true),
|
|
|
|
|
|
[StringConstants.compiler_directive_include_namespace] = new DirectiveInfo(quotesAreSpecialSymbols: true),
|
2024-05-04 20:21:50 +03:00
|
|
|
|
[StringConstants.compiler_directive_savepcu] = new DirectiveInfo(SingleAnyOfCheck("true", "false")),
|
|
|
|
|
|
[StringConstants.compiler_directive_zerobasedstrings] = new DirectiveInfo(SingleAnyOfCheck("on", "off"), paramsNums: new int[2] { 0, 1 }),
|
2024-05-25 12:26:32 +03:00
|
|
|
|
[StringConstants.compiler_directive_zerobasedstrings_ON] = NoParamsDirectiveInfo(),
|
|
|
|
|
|
[StringConstants.compiler_directive_zerobasedstrings_OFF] = NoParamsDirectiveInfo(),
|
|
|
|
|
|
[StringConstants.compiler_directive_nullbasedstrings_ON] = NoParamsDirectiveInfo(),
|
|
|
|
|
|
[StringConstants.compiler_directive_nullbasedstrings_OFF] = NoParamsDirectiveInfo(),
|
|
|
|
|
|
[StringConstants.compiler_directive_initstring_as_empty_ON] = NoParamsDirectiveInfo(),
|
|
|
|
|
|
[StringConstants.compiler_directive_initstring_as_empty_OFF] = NoParamsDirectiveInfo(),
|
2024-05-05 18:12:35 +03:00
|
|
|
|
[StringConstants.compiler_directive_resource] = new DirectiveInfo(quotesAreSpecialSymbols: true),
|
2024-05-04 20:21:50 +03:00
|
|
|
|
[StringConstants.compiler_directive_platformtarget] = new DirectiveInfo(SingleAnyOfCheck("x86", "x64", "anycpu", "dotnet5win", "dotnet5linux", "dotnet5macos", "native")),
|
2024-05-25 12:26:32 +03:00
|
|
|
|
[StringConstants.compiler_directive_faststrings] = NoParamsDirectiveInfo(),
|
2024-05-04 20:21:50 +03:00
|
|
|
|
[StringConstants.compiler_directive_gendoc] = new DirectiveInfo(SingleAnyOfCheck("true", "false")),
|
|
|
|
|
|
[StringConstants.compiler_directive_region] = new DirectiveInfo(checkParamsNumNeeded: false),
|
|
|
|
|
|
[StringConstants.compiler_directive_endregion] = new DirectiveInfo(checkParamsNumNeeded: false),
|
|
|
|
|
|
[StringConstants.compiler_directive_ifdef] = new DirectiveInfo(SingleIsValidIdCheck()),
|
|
|
|
|
|
[StringConstants.compiler_directive_endif] = new DirectiveInfo(SingleIsValidIdCheck(), paramsNums: new int[2] { 0, 1 }),
|
|
|
|
|
|
[StringConstants.compiler_directive_ifndef] = new DirectiveInfo(SingleIsValidIdCheck()),
|
|
|
|
|
|
[StringConstants.compiler_directive_else] = new DirectiveInfo(SingleIsValidIdCheck(), paramsNums: new int[2] { 0, 1 }),
|
|
|
|
|
|
[StringConstants.compiler_directive_undef] = new DirectiveInfo(SingleIsValidIdCheck()),
|
|
|
|
|
|
[StringConstants.compiler_directive_define] = new DirectiveInfo(SingleIsValidIdCheck()),
|
2024-05-05 18:12:35 +03:00
|
|
|
|
[StringConstants.compiler_directive_include] = new DirectiveInfo(quotesAreSpecialSymbols: true),
|
2024-05-04 20:21:50 +03:00
|
|
|
|
[StringConstants.compiler_directive_targetframework] = new DirectiveInfo(),
|
2024-05-25 12:26:32 +03:00
|
|
|
|
[StringConstants.compiler_directive_hidden_idents] = NoParamsDirectiveInfo(),
|
2024-05-05 18:12:35 +03:00
|
|
|
|
[StringConstants.compiler_directive_version_string] = new DirectiveInfo(IsValidVersionCheck()),
|
|
|
|
|
|
[StringConstants.compiler_directive_product_string] = new DirectiveInfo(quotesAreSpecialSymbols: true),
|
|
|
|
|
|
[StringConstants.compiler_directive_company_string] = new DirectiveInfo(quotesAreSpecialSymbols: true),
|
|
|
|
|
|
[StringConstants.compiler_directive_trademark_string] = new DirectiveInfo(quotesAreSpecialSymbols: true),
|
|
|
|
|
|
[StringConstants.compiler_directive_main_resource_string] = new DirectiveInfo(quotesAreSpecialSymbols: true),
|
|
|
|
|
|
[StringConstants.compiler_directive_title_string] = new DirectiveInfo(quotesAreSpecialSymbols: true),
|
|
|
|
|
|
[StringConstants.compiler_directive_description_string] = new DirectiveInfo(quotesAreSpecialSymbols: true),
|
2024-05-04 20:21:50 +03:00
|
|
|
|
[StringConstants.compiler_directive_omp] = new DirectiveInfo(SingleAnyOfCheck("critical", "parallel"), checkParamsNumNeeded: false)
|
|
|
|
|
|
};
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2024-05-25 12:26:32 +03:00
|
|
|
|
protected override void PreBuildTree(string FileName)
|
2015-05-14 22:35:07 +03:00
|
|
|
|
{
|
|
|
|
|
|
CompilerDirectives = new List<compiler_directive>();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2024-05-09 19:04:31 +03:00
|
|
|
|
private syntax_tree_node Parse(string Text, string fileName, bool buildTreeForFormatter = false, List<string> definesList = null)
|
2015-05-14 22:35:07 +03:00
|
|
|
|
{
|
2024-05-09 19:04:31 +03:00
|
|
|
|
#if DEBUG
|
|
|
|
|
|
#if _ERR
|
|
|
|
|
|
FileInfo f = new FileInfo(FileName);
|
|
|
|
|
|
var sv = Path.ChangeExtension(FileName,".grmtrack1");
|
|
|
|
|
|
var sw = new StreamWriter(sv);
|
|
|
|
|
|
Console.SetError(sw);
|
|
|
|
|
|
#endif
|
|
|
|
|
|
#endif
|
2015-05-14 22:35:07 +03:00
|
|
|
|
|
2024-05-25 12:26:32 +03:00
|
|
|
|
PascalParserTools parserTools = new PascalParserTools(this); // контекст сканера и парсера
|
2024-05-09 19:04:31 +03:00
|
|
|
|
parserTools.errors = Errors;
|
|
|
|
|
|
parserTools.warnings = Warnings;
|
|
|
|
|
|
parserTools.compilerDirectives = CompilerDirectives;
|
|
|
|
|
|
parserTools.currentFileName = Path.GetFullPath(fileName);
|
2015-05-14 22:35:07 +03:00
|
|
|
|
|
2024-05-04 20:21:50 +03:00
|
|
|
|
|
2024-05-09 19:04:31 +03:00
|
|
|
|
Scanner scanner = new Scanner();
|
|
|
|
|
|
scanner.SetSource(Text, 0);
|
|
|
|
|
|
scanner.parserTools = parserTools; // передали parserTools в объект сканера
|
|
|
|
|
|
if (definesList != null)
|
|
|
|
|
|
scanner.Defines.AddRange(definesList);
|
2015-05-14 22:35:07 +03:00
|
|
|
|
|
2024-05-09 19:04:31 +03:00
|
|
|
|
GPPGParser parser = new GPPGParser(scanner);
|
|
|
|
|
|
parserTools.buildTreeForFormatter = buildTreeForFormatter;
|
|
|
|
|
|
parser.parserTools = parserTools; // передали parserTools в объект парсера
|
2015-05-14 22:35:07 +03:00
|
|
|
|
|
2024-05-09 19:04:31 +03:00
|
|
|
|
if (!parser.Parse())
|
|
|
|
|
|
if (Errors.Count == 0)
|
|
|
|
|
|
parserTools.AddError("Неопознанная синтаксическая ошибка!", null);
|
|
|
|
|
|
#if DEBUG
|
|
|
|
|
|
#if _ERR
|
|
|
|
|
|
sw.Close();
|
|
|
|
|
|
#endif
|
|
|
|
|
|
#endif
|
|
|
|
|
|
return parser.root;
|
|
|
|
|
|
}
|
2015-05-14 22:35:07 +03:00
|
|
|
|
|
2024-05-25 12:26:32 +03:00
|
|
|
|
protected override syntax_tree_node BuildTreeInNormalMode(string FileName, string Text, List<string> DefinesList = null)
|
2024-05-09 19:04:31 +03:00
|
|
|
|
{
|
|
|
|
|
|
Errors.Clear();
|
|
|
|
|
|
Warnings.Clear();
|
|
|
|
|
|
syntax_tree_node root = Parse(Text, FileName, false, DefinesList);
|
2015-05-14 22:35:07 +03:00
|
|
|
|
|
2024-05-09 19:04:31 +03:00
|
|
|
|
if (Errors.Count > 0)
|
|
|
|
|
|
return null;
|
2015-05-14 22:35:07 +03:00
|
|
|
|
|
|
|
|
|
|
return root;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2024-05-25 12:26:32 +03:00
|
|
|
|
protected override syntax_tree_node BuildTreeInExprMode(string FileName, string Text)
|
2015-05-14 22:35:07 +03:00
|
|
|
|
{
|
2018-04-29 11:02:40 +03:00
|
|
|
|
if (Text == string.Empty)
|
|
|
|
|
|
return null;
|
2024-05-04 20:21:50 +03:00
|
|
|
|
// LineCorrection = -1 не забыть
|
2018-04-15 15:37:22 +03:00
|
|
|
|
string origText = Text;
|
2015-05-14 22:35:07 +03:00
|
|
|
|
Text = String.Concat("<<expression>>", Environment.NewLine, Text);
|
2024-05-09 19:04:31 +03:00
|
|
|
|
|
|
|
|
|
|
syntax_tree_node root = Parse(Text, FileName);
|
|
|
|
|
|
|
2018-04-18 21:26:42 +03:00
|
|
|
|
if (root == null && origText != null && origText.Contains("<"))
|
2018-04-15 15:37:22 +03:00
|
|
|
|
{
|
|
|
|
|
|
Errors.Clear();
|
2024-05-09 19:04:31 +03:00
|
|
|
|
root = Parse(String.Concat("<<expression>>", Environment.NewLine, origText.Replace("<", "&<")), FileName);
|
2018-04-15 15:37:22 +03:00
|
|
|
|
}
|
2015-05-14 22:35:07 +03:00
|
|
|
|
return root as expression;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2024-05-25 12:26:32 +03:00
|
|
|
|
protected override syntax_tree_node BuildTreeInTypeExprMode(string FileName, string Text)
|
2015-05-14 22:35:07 +03:00
|
|
|
|
{
|
|
|
|
|
|
// LineCorrection = -1 не забыть
|
|
|
|
|
|
Text = String.Concat("<<type>>", Environment.NewLine, Text);
|
2024-05-09 19:04:31 +03:00
|
|
|
|
|
|
|
|
|
|
syntax_tree_node root = Parse(Text, FileName);
|
2015-05-14 22:35:07 +03:00
|
|
|
|
return root as expression;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2024-05-25 12:26:32 +03:00
|
|
|
|
protected override syntax_tree_node BuildTreeInStatementMode(string FileName, string Text)
|
2015-05-14 22:35:07 +03:00
|
|
|
|
{
|
|
|
|
|
|
Text = String.Concat("<<statement>>", Environment.NewLine, Text);
|
2024-05-09 19:04:31 +03:00
|
|
|
|
|
|
|
|
|
|
syntax_tree_node root = Parse(Text, FileName);
|
2016-09-20 20:13:47 +03:00
|
|
|
|
return root as statement;
|
2015-05-14 22:35:07 +03:00
|
|
|
|
}
|
|
|
|
|
|
|
2024-05-25 12:26:32 +03:00
|
|
|
|
protected override syntax_tree_node BuildTreeInSpecialMode(string FileName, string Text)
|
2015-05-14 22:35:07 +03:00
|
|
|
|
{
|
|
|
|
|
|
Errors.Clear();
|
2024-05-09 19:04:31 +03:00
|
|
|
|
syntax_tree_node root = Parse(Text, FileName);
|
2015-05-14 22:35:07 +03:00
|
|
|
|
return root;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2024-05-25 12:26:32 +03:00
|
|
|
|
protected override syntax_tree_node BuildTreeInFormatterMode(string FileName, string Text)
|
2015-05-14 22:35:07 +03:00
|
|
|
|
{
|
|
|
|
|
|
Errors.Clear();
|
2024-05-09 19:04:31 +03:00
|
|
|
|
syntax_tree_node root = Parse(Text, FileName, true);
|
2015-05-14 22:35:07 +03:00
|
|
|
|
return root;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|