374 lines
16 KiB
Plaintext
374 lines
16 KiB
Plaintext
"Name" = 'Pascal Preprocessor2'
|
|
"Version" = '0.3'
|
|
"Author" = 'MZ'
|
|
|
|
"Case Sensitive" = True
|
|
|
|
"Start Symbol" = <preprocessor_program>
|
|
|
|
!*
|
|
[TERMINALTEMPLATE]
|
|
{
|
|
%NAME% _%NAME%=new %NAME%(%PARAMS%);
|
|
_%NAME%.source_context=parsertools.GetTokenSourceContext();
|
|
%CODE%
|
|
return _%NAME%;
|
|
}
|
|
*!
|
|
|
|
!*
|
|
[NONTERMINALTEMPLATE0]
|
|
{
|
|
%NAME% _%NAME%=new %NAME%(%PARAMS%);
|
|
parsertools.create_source_context(_%NAME%,%LEFTTOKEN%,%RIGHTTOKEN%);
|
|
%CODE%
|
|
return _%NAME%;
|
|
}
|
|
*!
|
|
|
|
!add to list
|
|
!*
|
|
[NONTERMINALTEMPLATE1]
|
|
{
|
|
%NAME% _%NAME%=(%NAME%)%CODE%
|
|
return _%NAME%;
|
|
}
|
|
*!
|
|
|
|
!*
|
|
[NONTERMINALTEMPLATE2]
|
|
{
|
|
%NAME% _%NAME%;
|
|
%CODE%
|
|
return _%NAME%;
|
|
}
|
|
*!
|
|
|
|
|
|
!*
|
|
[NONTERMINALTEMPLATE3]
|
|
{
|
|
%NAME% _%NAME%=new %NAME%(%PARAMS%);
|
|
%CODE%
|
|
return _%NAME%;
|
|
}
|
|
*!
|
|
|
|
!for list:
|
|
!<el>
|
|
!<list> token <el>
|
|
!*
|
|
[NONTERMINALTEMPLATE6]
|
|
//TemplateList for %NAME% (create)
|
|
{
|
|
%NAME% _%NAME%=new %NAME%();
|
|
_%NAME%.source_context=((%CODE%)$1).source_context;
|
|
_%NAME%.%PARAMS%.Add((%CODE%)$1);
|
|
return _%NAME%;
|
|
}
|
|
*!
|
|
!*
|
|
[NONTERMINALTEMPLATE7]
|
|
//TemplateList for %NAME% (add)
|
|
{
|
|
%NAME% _%NAME%=(%NAME%)$1;
|
|
parsertools.create_source_context(_%NAME%,$$,$3);
|
|
_%NAME%.%PARAMS%.Add($3 as %CODE%);
|
|
return _%NAME%;
|
|
}
|
|
*!
|
|
|
|
|
|
!------------------------------------------Sets
|
|
|
|
Comment Start = '{' !| '(*'
|
|
Comment End = '}' !| '*)'
|
|
Comment Line = '//'
|
|
Whitespace = {Whitespace}+
|
|
!Whitespace = {Whitespace}+ | ('(*' ( {CommentPart2_1} | '*' {CommentPart2_2} )* '*)' )
|
|
|
|
{Id Head} = {Letter} + {Cyrillic} + [_] + ['.'] + [''''] + ['\']
|
|
{Id Tail} = {Id Head} + {Digit} + ['.'] + ['-'] + [','] + ['''']
|
|
{All ASCII} = {#1..#255} + {Cyrillic} + {#8100..#8800}
|
|
|
|
{WS} = {Whitespace} - {CR} - {LF}
|
|
{Program line part} = {All ASCII} - {CR} - {LF} - {WS} - ['{'] - ['}'] - ['/'] - [''] - ["]
|
|
{Comment part slashes} = {All ASCII} - {LF} - {CR} !- {WS} - [' ']
|
|
{Comment line finalization} = {All ASCII} - {LF} - {CR} - ['}'] !- {WS} - [' ']
|
|
{Params} = {Letter} + {Cyrillic} + ['_'] + {Number} + ['.'] + ['():+,-*']
|
|
{CommentPart2_1} = {All ASCII} - [*]
|
|
{CommentPart2_2} = {All ASCII} - [)]
|
|
|
|
{TextPart} = {All ASCII} - {Control Codes}
|
|
{StringChar} = {TextPart} - ['']
|
|
{ILStringChar} = {TextPart} - ["]
|
|
|
|
!------------------------------------------Tokens
|
|
|
|
TK_NEWLINE = {CR}{LF}|{CR}
|
|
TK_SLASH = '/' !* {
|
|
token_info _token_info = new token_info(LRParser.TokenText);
|
|
_token_info.source_context = parsertools.GetTokenSourceContext();
|
|
|
|
return _token_info;
|
|
}*!
|
|
|
|
TK_SLASHEKV = '/' (' ')* '=' !* {
|
|
token_info _token_info = new token_info(LRParser.TokenText);
|
|
_token_info.source_context = parsertools.GetTokenSourceContext();
|
|
|
|
return _token_info;
|
|
}*!
|
|
|
|
TK_AP = '' !* {
|
|
token_info _token_info = new token_info(LRParser.TokenText);
|
|
_token_info.source_context = parsertools.GetTokenSourceContext();
|
|
|
|
return _token_info;
|
|
}*!
|
|
|
|
TK_KAV = '"' !* {
|
|
token_info _token_info = new token_info(LRParser.TokenText);
|
|
_token_info.source_context = parsertools.GetTokenSourceContext();
|
|
|
|
return _token_info;
|
|
}*!
|
|
|
|
TK_PROGRAM_LINE = ( ( {Program line part}+ (' ')* ( ((''({StringChar})*'') | ('"'({ILStringChar})*'"') )* (' ')* ) )+ | ( ( (''({StringChar})*'') | ('"'({ILStringChar})*'"') )+ (' ')* {Program line part}* (' ')* )+ )+ !* {
|
|
token_info _token_info = new token_info(LRParser.TokenText);
|
|
_token_info.source_context = parsertools.GetTokenSourceContext();
|
|
|
|
return _token_info;
|
|
}*!
|
|
|
|
|
|
TK_DIRECTIVE = '{$'{Id Head}{Id Tail}* ( ( (' ')+ {Id Head}{Id Tail}*) | '+' | '-' )? (' ' {Params}*)* '}' !* {
|
|
token_info _token_info = new token_info(LRParser.TokenText);
|
|
_token_info.source_context = parsertools.GetTokenSourceContext();
|
|
|
|
return _token_info;
|
|
}*!
|
|
|
|
|
|
|
|
!------------------------------------------Rules
|
|
|
|
<preprocessor_program>
|
|
::= <preprocessor_lexems> <empty> !* {
|
|
compilation_unit _compilation_unit = new compilation_unit();
|
|
|
|
_compilation_unit.Language = LanguageId.PascalABCNET;
|
|
if (LRParser.GetReductionSyntaxNode(0) != null)
|
|
{
|
|
parsertools.create_source_context(_compilation_unit, LRParser.GetReductionSyntaxNode(0), LRParser.GetReductionSyntaxNode(0));
|
|
CompilerDirectives.AddRange(((compiler_directive_list)LRParser.GetReductionSyntaxNode(0)).directives);
|
|
if (CompilerDirectives.Count != 0)
|
|
prepr.CompilerDirectives.AddRange(CompilerDirectives);
|
|
}
|
|
|
|
return _compilation_unit;
|
|
}*!
|
|
|
|
|
|
<preprocessor_lexems>
|
|
::= <_preprocessor_lexems> !* return LRParser.GetReductionSyntaxNode(0);*!
|
|
|
|
|
|
|
<_preprocessor_lexems>
|
|
::= <preprocessor_lexem> <empty> !* {
|
|
compiler_directive_list _compiler_directive_list = new compiler_directive_list();
|
|
|
|
if (LRParser.GetReductionSyntaxNode(0) is compiler_directive)
|
|
_compiler_directive_list.directives.Add((compiler_directive)LRParser.GetReductionSyntaxNode(0));
|
|
parsertools.create_source_context(_compiler_directive_list, LRParser.GetReductionSyntaxNode(0), LRParser.GetReductionSyntaxNode(0));
|
|
return _compiler_directive_list;
|
|
}*!
|
|
| <preprocessor_lexems> <preprocessor_lexem> !* {
|
|
compiler_directive_list _compiler_directive_list = (compiler_directive_list)LRParser.GetReductionSyntaxNode(0);
|
|
if (LRParser.GetReductionSyntaxNode(1) is compiler_directive)
|
|
_compiler_directive_list.directives.Add((compiler_directive)LRParser.GetReductionSyntaxNode(1));
|
|
parsertools.create_source_context(_compiler_directive_list, LRParser.GetReductionSyntaxNode(0), LRParser.GetReductionSyntaxNode(1));
|
|
return _compiler_directive_list;
|
|
}*!
|
|
|
|
<preprocessor_lexem>
|
|
::= TK_NEWLINE !* return LRParser.GetReductionSyntaxNode(0);*!
|
|
| TK_SLASH !* {
|
|
if (prepr.sm.AllowWrite())
|
|
prepr.WriteToStream(((token_info)LRParser.GetReductionSyntaxNode(0)).source_context, ((token_info)LRParser.GetReductionSyntaxNode(0)).text);
|
|
return LRParser.GetReductionSyntaxNode(0);
|
|
}*!
|
|
| TK_SLASHEKV !* {
|
|
if (prepr.sm.AllowWrite())
|
|
prepr.WriteToStream(((token_info)LRParser.GetReductionSyntaxNode(0)).source_context, ((token_info)LRParser.GetReductionSyntaxNode(0)).text);
|
|
return LRParser.GetReductionSyntaxNode(0);
|
|
}*!
|
|
| TK_AP !* {
|
|
if (prepr.sm.AllowWrite())
|
|
prepr.WriteToStream(((token_info)LRParser.GetReductionSyntaxNode(0)).source_context, ((token_info)LRParser.GetReductionSyntaxNode(0)).text);
|
|
return LRParser.GetReductionSyntaxNode(0);
|
|
}*!
|
|
| TK_KAV !* {
|
|
if (prepr.sm.AllowWrite())
|
|
prepr.WriteToStream(((token_info)LRParser.GetReductionSyntaxNode(0)).source_context, ((token_info)LRParser.GetReductionSyntaxNode(0)).text);
|
|
return LRParser.GetReductionSyntaxNode(0);
|
|
}*!
|
|
| TK_PROGRAM_LINE !* {
|
|
if (prepr.sm.AllowWrite())
|
|
prepr.WriteToStream(((token_info)LRParser.GetReductionSyntaxNode(0)).source_context, ((token_info)LRParser.GetReductionSyntaxNode(0)).text);
|
|
return LRParser.GetReductionSyntaxNode(0);
|
|
}*!
|
|
| TK_DIRECTIVE <empty> !* {
|
|
bool inline = ( ((token_info)LRParser.GetReductionSyntaxNode(0)).source_context.begin_position.line_num - ((token_info)LRParser.GetReductionSyntaxNode(0)).source_context.end_position.line_num == 0 );
|
|
string token_text = ((token_info)LRParser.GetReductionSyntaxNode(0)).text;
|
|
|
|
if (token_text[1] == '$' && inline)
|
|
{
|
|
compiler_directive _compiler_directive = (compiler_directive)pascal_parsertools.MakeDirective((token_info)LRParser.GetReductionSyntaxNode(0));
|
|
_compiler_directive.source_context.FileName = prepr.CurrentFileName;
|
|
prepr.CurrentFileName = _compiler_directive.source_context.FileName;
|
|
|
|
//INCLUDE
|
|
if (_compiler_directive.Name.text == prepr.INCLUDE)
|
|
{
|
|
if (prepr.sm.AllowWrite())
|
|
{
|
|
string IncludeFileName = _compiler_directive.Directive.text;
|
|
if (prepr.ProcessedFileNames.Contains(IncludeFileName) || Path.GetFileName(prepr.CurrentFileName) == Path.GetFileName(IncludeFileName))
|
|
{
|
|
prepr.Errors.Add(new CircularInclude(prepr.CurrentFileName, _compiler_directive.source_context, null, IncludeFileName));
|
|
}
|
|
else
|
|
{
|
|
if (!(bool)prepr.SourceFilesProvider(IncludeFileName, SourceFileOperation.Exists))
|
|
prepr.Errors.Add(new IncludeFileNotFound(prepr.CurrentFileName, _compiler_directive.source_context, null, IncludeFileName));
|
|
string b = prepr.CurrentFileName;
|
|
//string t = prepr.SourceText;
|
|
//string[] sl = prepr.SourceLines;
|
|
prepr.ProcessFile(IncludeFileName);
|
|
prepr.CurrentFileName = b;
|
|
//prepr.SourceText = t;
|
|
//prepr.SourceLines = sl;
|
|
prepr.ProcessedFileNames.Remove(IncludeFileName);
|
|
}
|
|
}
|
|
return _compiler_directive;
|
|
}
|
|
//DEFINE
|
|
if (_compiler_directive.Name.text == prepr.DEFINE)
|
|
{
|
|
if (prepr.sm.AllowWrite())
|
|
{
|
|
string directive = _compiler_directive.Directive.text;
|
|
string name = prepr.getFirstIdent(directive);
|
|
string text = prepr.getSecondIdent(directive);
|
|
prepr.AddDefineDirective(name, text, _compiler_directive);
|
|
}
|
|
return _compiler_directive;
|
|
}
|
|
//UNDEF
|
|
if (_compiler_directive.Name.text == prepr.UNDEF)
|
|
{
|
|
if (prepr.sm.AllowWrite())
|
|
{
|
|
string directive = _compiler_directive.Directive.text;
|
|
string name = prepr.getFirstIdent(directive);
|
|
if (name != null)
|
|
if (prepr.DefineDirectiveDefinded(name))
|
|
prepr.DeleteDefineDirective(name, _compiler_directive);
|
|
}
|
|
return _compiler_directive;
|
|
}
|
|
//IFDEF
|
|
if (_compiler_directive.Name.text == prepr.IFDEF)
|
|
{
|
|
string directive = _compiler_directive.Directive.text;
|
|
if (prepr.sm.AllowWrite())
|
|
{
|
|
|
|
if (directive != null)
|
|
{
|
|
if (!prepr.DefineDirectiveDefinded(directive))
|
|
prepr.sm.ChangeState(false, 1);
|
|
else
|
|
prepr.sm.ChangeState(true, 1);
|
|
}
|
|
|
|
}
|
|
else
|
|
prepr.sm.ChangeState(false, -1);
|
|
return _compiler_directive;
|
|
}
|
|
//IFNDEF
|
|
if (_compiler_directive.Name.text == prepr.IFNDEF)
|
|
{
|
|
string directive = _compiler_directive.Directive.text;
|
|
if (prepr.sm.AllowWrite())
|
|
{
|
|
|
|
if (directive != null)
|
|
{
|
|
if (prepr.DefineDirectiveDefinded(directive))
|
|
prepr.sm.ChangeState(false, 1);
|
|
else
|
|
prepr.sm.ChangeState(true, 1);
|
|
}
|
|
|
|
}
|
|
else
|
|
prepr.sm.ChangeState(false, -1);
|
|
return _compiler_directive;
|
|
}
|
|
//ELSE
|
|
if (_compiler_directive.Name.text == prepr.ELSE)
|
|
{
|
|
if (prepr.sm.GetEndifCount() == 0 || prepr.sm.AllowElse() == false)
|
|
{
|
|
prepr.Errors.Add(new UnexpectedElse(prepr.CurrentFileName, _compiler_directive.source_context));
|
|
}
|
|
else
|
|
{
|
|
if (prepr.sm.AllowWrite())
|
|
prepr.sm.ChangeState(false, false);
|
|
else
|
|
{
|
|
if (prepr.sm.LastCondition() == 1)
|
|
prepr.sm.ChangeState(true, false);
|
|
else
|
|
prepr.sm.ChangeState(false, false);
|
|
}
|
|
}
|
|
return _compiler_directive;
|
|
}
|
|
//ENDIF
|
|
if (_compiler_directive.Name.text == prepr.ENDIF)
|
|
{
|
|
if (prepr.sm.GetEndifCount() == 0)
|
|
{
|
|
prepr.Errors.Add(new UnexpectedEndif(prepr.CurrentFileName, _compiler_directive.source_context));
|
|
}
|
|
else
|
|
{
|
|
if (prepr.sm.AllowWrite())
|
|
prepr.sm.ChangeState(true, true);
|
|
else
|
|
{
|
|
if (prepr.sm.LastEndifCondition() == 1)
|
|
prepr.sm.ChangeState(true, true);
|
|
else
|
|
prepr.sm.ChangeState(false, true);
|
|
}
|
|
}
|
|
return _compiler_directive;
|
|
}
|
|
return _compiler_directive;
|
|
}
|
|
return LRParser.GetReductionSyntaxNode(0);
|
|
}*!
|
|
|
|
|
|
|
|
<empty> ::=
|
|
|
|
|