fix index

This commit is contained in:
Sun Serega 2023-08-14 00:32:18 +03:00
parent 7132c64f1e
commit 3e48c33ae7
438 changed files with 20275 additions and 105954 deletions

27
.gitignore vendored
View file

@ -4,19 +4,6 @@
# general ignore
*.pcu
*.pdb
*.csproj.user
#TODO Что то старое. Там, кроме всего прочего, зачем то копия древней версии инсталята паскаля
# - удалить
!Grammars/Oberon10Independent (by Juliet)/**/*.pcu
#TODO Тут тоже копия древних примеров, но зачем то ещё примеры на BrainFuck и PL/0
# - удалить паскалевские примеры
!ReleaseGenerators/Samples/_SVN/**/*.pcu
#TODO NodesGenerator ещё используется?
# - удалить pdb
!Utils/NodesGeneratorNew/**/*.pdb
#TODO Это папка с тем тестом ML. Стоит её хотя бы в отдельную ветку. А по хорошему отдельным репозиторием...
# - убрать целиком
!W/**/*.pdb
# vs internal files
**/.vs/*
@ -35,7 +22,10 @@
!/Utils/Old/NodesGeneratorOld0/bin/*
!/YMC/bin/*
#
# local user files
*.csproj.user
/bin/CompilerController.ini
@ -80,8 +70,6 @@
**/PascalABCNET.exe.config
**/PascalABCNETLinux.exe
**/PascalABCNETLinux.exe.config
#TODO
!Grammars/Oberon10Independent (by Juliet)/**/*.dll
@ -108,7 +96,7 @@
/bin/WeifenLuo.WinFormsUI.Docking.ThemeVS2005.dll
/bin/WeifenLuo.WinFormsUI.Docking.ThemeVS2005Linux.dll
#TODO копируется только при сборке pabcnetc.sln - это норм?
# - Этот проект, получается, подключён только к консольным компиляторам
# - в самом проекте написано что его надо удалить...
/bin/YieldConversionSyntax.dll
# Debug-only intellisense problems
@ -129,11 +117,6 @@
#TODO Часть в индексе, часть нет
# - все добавить в индекс
/bin/**/*.xml
!/bin/Lib/en/*.xml
#TODO Метаданные .dll, наверное их забывает удалить после тестирования их генерации?
/bin/mscorlib.txt
/bin/System.Data.dll.txt

File diff suppressed because one or more lines are too long

View file

@ -1,623 +0,0 @@
//
// Experimental embedded frame
// Version 1.1.3 of 18-April-2010
//
## Derived from gplex.frame version of 2-September-2006.
## Code page support for files without a BOM.
## Left and Right Anchored state support.
## Start condition stack. Two generic params.
## Using fixed length context handling for right anchors
//
##-->defines
using System;
using System.IO;
using System.Text;
using System.Globalization;
using System.Collections.Generic;
using System.Runtime.Serialization;
using System.Diagnostics.CodeAnalysis;
##-->version290
##-->usingDcl
{
/// <summary>
/// Summary Canonical example of GPLEX automaton
/// </summary>
#if STANDALONE
//
// These are the dummy declarations for stand-alone GPLEX applications
// normally these declarations would come from the parser.
// If you declare /noparser, or %option noparser then you get this.
//
##-->translate $public enum $Tokens
{
EOF = 0, maxParseToken = int.MaxValue
// must have at least these two, values are almost arbitrary
}
##-->translate $public abstract class $ScanBase
{
[SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "yylex")]
[SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "yylex")]
public abstract int yylex();
[SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "yywrap")]
[SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "yywrap")]
protected virtual bool yywrap() { return true; }
#if BABEL
protected abstract int CurrentSc { get; set; }
// EolState is the 32-bit of state data persisted at
// the end of each line for Visual Studio colorization.
// The default is to return CurrentSc. You must override
// this if you want more complicated behavior.
public virtual int EolState {
get { return CurrentSc; }
set { CurrentSc = value; }
}
}
##-->translate $public interface IColorScan
{
void SetSource(string source, int offset);
int GetNext(ref int state, out int start, out int end);
#endif // BABEL
}
#endif // STANDALONE
// If the compiler can't find the scanner base class maybe you
// need to run GPPG with the /gplex option, or GPLEX with /noparser
#if BABEL
##-->translate $public sealed partial class $Scanner : $ScanBase, IColorScan
{
private ScanBuff buffer;
int currentScOrd; // start condition ordinal
protected override int CurrentSc
{
// The current start state is a property
// to try to avoid the user error of setting
// scState but forgetting to update the FSA
// start state "currentStart"
//
get { return currentScOrd; } // i.e. return YY_START;
set { currentScOrd = value; // i.e. BEGIN(value);
currentStart = startState[value]; }
}
#else // BABEL
##-->translate $public sealed partial class $Scanner : $ScanBase
{
private ScanBuff buffer;
int currentScOrd; // start condition ordinal
#endif // BABEL
/// <summary>
/// The input buffer for this scanner.
/// </summary>
[SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
public ScanBuff Buffer { get { return buffer; } }
private static int GetMaxParseToken() {
##-->translate System.Reflection.FieldInfo f = typeof($Tokens).GetField("maxParseToken");
return (f == null ? int.MaxValue : (int)f.GetValue(null));
}
static int parserMax = GetMaxParseToken();
enum Result {accept, noMatch, contextFound};
##-->consts
#region user code
##-->codeIncl
#endregion user code
int state;
int currentStart = startState[0];
int code; // last code read
int cCol; // column number of code
int lNum; // current line number
//
// The following instance variables are used, among other
// things, for constructing the yylloc location objects.
//
int tokPos; // buffer position at start of token
int tokCol; // zero-based column number at start of token
int tokLin; // line number at start of token
int tokEPos; // buffer position at end of token
int tokECol; // column number at end of token
int tokELin; // line number at end of token
string tokTxt; // lazily constructed text of token
#if STACK
private Stack<int> scStack = new Stack<int>();
#endif // STACK
##-->tableDef
#if BACKUP
// ==============================================================
// == Nested struct used for backup in automata that do backup ==
// ==============================================================
struct Context // class used for automaton backup.
{
public int bPos;
public int rPos; // scanner.readPos saved value
public int cCol;
public int lNum; // Need this in case of backup over EOL.
public int state;
public int cChr;
}
private Context ctx = new Context();
#endif // BACKUP
// ==============================================================
// ==== Nested struct to support input switching in scanners ====
// ==============================================================
struct BufferContext {
internal ScanBuff buffSv;
internal int chrSv;
internal int cColSv;
internal int lNumSv;
}
// ==============================================================
// ===== Private methods to save and restore buffer contexts ====
// ==============================================================
/// <summary>
/// This method creates a buffer context record from
/// the current buffer object, together with some
/// scanner state values.
/// </summary>
[SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
BufferContext MkBuffCtx()
{
BufferContext rslt;
rslt.buffSv = this.buffer;
rslt.chrSv = this.code;
rslt.cColSv = this.cCol;
rslt.lNumSv = this.lNum;
return rslt;
}
/// <summary>
/// This method restores the buffer value and allied
/// scanner state from the given context record value.
/// </summary>
[SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
void RestoreBuffCtx(BufferContext value)
{
this.buffer = value.buffSv;
this.code = value.chrSv;
this.cCol = value.cColSv;
this.lNum = value.lNumSv;
}
// =================== End Nested classes =======================
#if !NOFILES
##-->translate $public $Scanner(Stream file) {
##-->bufferCtor
}
#endif // !NOFILES
##-->translate $public $Scanner() { }
private int readPos;
void GetCode()
{
if (code == '\n') // This needs to be fixed for other conventions
// i.e. [\r\n\205\u2028\u2029]
{
cCol = -1;
lNum++;
}
readPos = buffer.Pos;
// Now read new codepoint.
code = buffer.Read();
if (code > ScanBuff.EndOfFile)
{
#if (!BYTEMODE)
if (code >= 0xD800 && code <= 0xDBFF)
{
int next = buffer.Read();
if (next < 0xDC00 || next > 0xDFFF)
code = ScanBuff.UnicodeReplacementChar;
else
code = (0x10000 + (code & 0x3FF << 10) + (next & 0x3FF));
}
#endif
cCol++;
}
}
void MarkToken()
{
#if (!PERSIST)
buffer.Mark();
#endif
tokPos = readPos;
tokLin = lNum;
tokCol = cCol;
}
void MarkEnd()
{
tokTxt = null;
tokEPos = readPos;
tokELin = lNum;
tokECol = cCol;
}
[SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
int Peek()
{
int rslt, codeSv = code, cColSv = cCol, lNumSv = lNum, bPosSv = buffer.Pos;
GetCode(); rslt = code;
lNum = lNumSv; cCol = cColSv; code = codeSv; buffer.Pos = bPosSv;
return rslt;
}
// ==============================================================
// ===== Initialization of string-based input buffers ====
// ==============================================================
/// <summary>
/// Create and initialize a StringBuff buffer object for this scanner
/// </summary>
/// <param name="source">the input string</param>
/// <param name="offset">starting offset in the string</param>
[SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
public void SetSource(string source, int offset)
{
this.buffer = ScanBuff.GetBuffer(source);
this.buffer.Pos = offset;
this.lNum = 0;
this.code = '\n'; // to initialize yyline, yycol and lineStart
GetCode();
}
#if !NOFILES
// ================ LineBuffer Initialization ===================
/// <summary>
/// Create and initialize a LineBuff buffer object for this scanner
/// </summary>
/// <param name="source">the list of input strings</param>
[SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
public void SetSource(IList<string> source)
{
this.buffer = ScanBuff.GetBuffer(source);
this.code = '\n'; // to initialize yyline, yycol and lineStart
this.lNum = 0;
GetCode();
}
// =============== StreamBuffer Initialization ==================
/// <summary>
/// Create and initialize a StreamBuff buffer object for this scanner.
/// StreamBuff is buffer for 8-bit byte files.
/// </summary>
/// <param name="source">the input byte stream</param>
[SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
public void SetSource(Stream source)
{
this.buffer = ScanBuff.GetBuffer(source);
this.lNum = 0;
this.code = '\n'; // to initialize yyline, yycol and lineStart
GetCode();
}
#if !BYTEMODE
// ================ TextBuffer Initialization ===================
/// <summary>
/// Create and initialize a TextBuff buffer object for this scanner.
/// TextBuff is a buffer for encoded unicode files.
/// </summary>
/// <param name="source">the input text file</param>
/// <param name="fallbackCodePage">Code page to use if file has
/// no BOM. For 0, use machine default; for -1, 8-bit binary</param>
[SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
public void SetSource(Stream source, int fallbackCodePage)
{
this.buffer = ScanBuff.GetBuffer(source, fallbackCodePage);
this.lNum = 0;
this.code = '\n'; // to initialize yyline, yycol and lineStart
GetCode();
}
#endif // !BYTEMODE
#endif // !NOFILES
// ==============================================================
#if BABEL
//
// Get the next token for Visual Studio
//
// "state" is the inout mode variable that maintains scanner
// state between calls, using the EolState property. In principle,
// if the calls of EolState are costly set could be called once
// only per line, at the start; and get called only at the end
// of the line. This needs more infrastructure ...
//
public int GetNext(ref int state, out int start, out int end)
{
##-->translate $Tokens next;
int s, e;
s = state; // state at start
EolState = state;
##-->translate next = ($Tokens)Scan();
state = EolState;
e = state; // state at end;
start = tokPos;
end = tokEPos - 1; // end is the index of last char.
return (int)next;
}
#endif // BABEL
// ======== AbstractScanner<> Implementation =========
[SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
[SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "yylex")]
[SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "yylex")]
public override int yylex()
{
// parserMax is set by reflecting on the Tokens
// enumeration. If maxParseToken is defined
// that is used, otherwise int.MaxValue is used.
int next;
do { next = Scan(); } while (next >= parserMax);
return next;
}
[SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
int yypos { get { return tokPos; } }
[SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
int yyline { get { return tokLin; } }
[SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
int yycol { get { return tokCol; } }
[SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
[SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "yytext")]
[SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "yytext")]
public string yytext
{
get
{
if (tokTxt == null)
tokTxt = buffer.GetString(tokPos, tokEPos);
return tokTxt;
}
}
[SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
void yyless(int n)
{
buffer.Pos = tokPos;
// Must read at least one char, so set before start.
cCol = tokCol - 1;
GetCode();
// Now ensure that line counting is correct.
lNum = tokLin;
// And count the rest of the text.
for (int i = 0; i < n; i++) GetCode();
MarkEnd();
}
//
// It would be nice to count backward in the text
// but it does not seem possible to re-establish
// the correct column counts except by going forward.
//
[SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
void _yytrunc(int n) { yyless(yyleng - n); }
//
// This is painful, but we no longer count
// codepoints. For the overwhelming majority
// of cases the single line code is fast, for
// the others, well, at least it is all in the
// buffer so no files are touched. Note that we
// can't use (tokEPos - tokPos) because of the
// possibility of surrogate pairs in the token.
//
[SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
[SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "yyleng")]
[SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "yyleng")]
public int yyleng
{
get {
#if BYTEMODE
return tokEPos - tokPos;
#else
if (tokELin == tokLin)
return tokECol - tokCol;
else {
int ch;
int count = 0;
int save = buffer.Pos;
buffer.Pos = tokPos;
do {
ch = buffer.Read();
if (!char.IsHighSurrogate((char)ch)) count++;
} while (buffer.Pos < tokEPos && ch != ScanBuff.EndOfFile);
buffer.Pos = save;
return count;
}
#endif // BYTEMODE
}
}
// ============ methods available in actions ==============
[SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
internal int YY_START {
get { return currentScOrd; }
set { currentScOrd = value;
currentStart = startState[value];
}
}
[SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
internal void BEGIN(int next) {
currentScOrd = next;
currentStart = startState[next];
}
// ============== The main tokenizer code =================
int Scan()
{
##-->prolog
for (; ; )
{
int next; // next state to enter
#if BACKUP
Result rslt = Result.noMatch;
#endif // BACKUP
#if LEFTANCHORS
for (;;)
{
// Discard characters that do not start any pattern.
// Must check the left anchor condition after *every* GetCode!
state = ((cCol == 0) ? anchorState[currentScOrd] : currentStart);
if ((next = NextState()) != goStart)
break; // LOOP EXIT HERE...
GetCode();
}
#else // !LEFTANCHORS
state = currentStart;
while ((next = NextState()) == goStart)
// At this point, the current character has no
// transition from the current state. We discard
// the "no-match" char. In traditional LEX such
// characters are echoed to the console.
GetCode();
#endif // LEFTANCHORS
// At last, a valid transition ...
MarkToken();
state = next;
GetCode();
while ((next = NextState()) > eofNum) // Exit for goStart AND for eofNum
#if BACKUP
if (state <= maxAccept && next > maxAccept) // need to prepare backup data
{
// ctx is an object. The fields may be
// mutated by the call to Recurse2.
// On return the data in ctx is the
// *latest* accept state that was found.
rslt = Recurse2(ref ctx, next);
if (rslt == Result.noMatch)
RestoreStateAndPos(ref ctx);
break;
}
else
#endif // BACKUP
{
state = next;
GetCode();
}
if (state <= maxAccept)
{
MarkEnd();
##-->actionCases
}
}
##-->epilog
}
#if BACKUP
Result Recurse2(ref Context ctx, int next)
{
// Assert: at entry "state" is an accept state AND
// NextState(state, code) != goStart AND
// NextState(state, code) is not an accept state.
//
SaveStateAndPos(ref ctx);
state = next;
GetCode();
while ((next = NextState()) > eofNum)
{
if (state <= maxAccept && next > maxAccept) // need to update backup data
SaveStateAndPos(ref ctx);
state = next;
if (state == eofNum) return Result.accept;
GetCode();
}
return (state <= maxAccept ? Result.accept : Result.noMatch);
}
void SaveStateAndPos(ref Context ctx)
{
ctx.bPos = buffer.Pos;
ctx.rPos = readPos;
ctx.cCol = cCol;
ctx.lNum = lNum;
ctx.state = state;
ctx.cChr = code;
}
void RestoreStateAndPos(ref Context ctx)
{
buffer.Pos = ctx.bPos;
readPos = ctx.rPos;
cCol = ctx.cCol;
lNum = ctx.lNum;
state = ctx.state;
code = ctx.cChr;
}
#endif // BACKUP
// ============= End of the tokenizer code ================
#if STACK
[SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
internal void yy_clear_stack() { scStack.Clear(); }
[SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
internal int yy_top_state() { return scStack.Peek(); }
internal void yy_push_state(int state)
{
scStack.Push(currentScOrd);
BEGIN(state);
}
internal void yy_pop_state()
{
// Protect against input errors that pop too far ...
if (scStack.Count > 0) {
int newSc = scStack.Pop();
BEGIN(newSc);
} // Otherwise leave stack unchanged.
}
#endif // STACK
[SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
internal void ECHO() { Console.Out.Write(yytext); }
##-->userCode
} // end class $Scanner
##-->embeddedBuffers
} // end namespace

View file

@ -1,77 +0,0 @@
##
## DO NOT EDIT THIS FILE CARELESSLY!
## THE CONTENTS OF THIS FILE ARE STRONGLY LINKED TO THE
## CODE OF Dfsa.cs, AND ALL MUST VARY TOGETHER
##
## This frame file produces an include file for gplex
## C# output. It does not produce a stand-alone scanner
## and uses not defined symbols, or "using" declarations.
## This only works for automata with no backup states!
##
//
// Guesser.frame version 1.1.0 of 30-January-2009
//
##-->version255
##-->usingDcl
{
public enum Tokens { EndToken = 0, MaxParseToken = int.MaxValue }
public class Scanner
{
ScanBuff buffer;
enum Result {accept, noMatch, contextFound};
bool yywrap() { return true; }
public int GuessCodePage() { return Scan(); }
##-->consts
#region user code
##-->codeIncl
#endregion user code
int state;
int currentStart = startState[0];
int code;
##-->tableDef
public Scanner(System.IO.Stream file) { SetSource(file); }
public void SetSource(System.IO.Stream source)
{
this.buffer = new BuildBuffer(source);
code = buffer.Read();
}
int Scan()
{
##-->prolog
for (; ; )
{
int next;
state = currentStart;
while ((next = NextState()) == goStart)
code = buffer.Read();
state = next;
code = buffer.Read();
while ((next = NextState()) > eofNum)
{
state = next;
code = buffer.Read();
}
if (state <= maxAccept)
{
##-->actionCases
}
}
##-->epilog
}
##-->userCode
} // end class Scanner
} // end namespace

View file

@ -1,112 +0,0 @@
<?xml version="1.0"?>
<!-- syntaxdefinition for Oberon00ABC (c) Mikst, Juliet 2010 -->
<SyntaxDefinition name = "Oberon00ABC" extensions = ".obr">
<Properties>
<Property name="LineComment" value="//"/>
</Properties>
<Digits name = "Digits" bold = "false" italic = "false" color = "DarkGreen"/>
<RuleSets>
<RuleSet ignorecase="false">
<Delimiters>&amp;&lt;&gt;~!%^*()-+=|\#/{}[]:;"' , .?</Delimiters>
<Span name = "LineComment" rule = "CommentMarkerSet" bold = "false" italic = "false" color = "Green" stopateol = "true">
<Begin>//@!/@</Begin>
</Span>
<Span name = "BlockComment" rule = "CommentMarkerSet" bold = "false" italic = "false" color = "Green" stopateol = "false">
<Begin>(*</Begin>
<End>*)</End>
</Span>
<Span name = "BlockComment2" rule = "CommentMarkerSet" bold = "false" italic = "false" color = "Green" stopateol = "false">
<Begin>/*</Begin>
<End>*/</End>
</Span>
<Span name = "String1" bold = "false" italic = "false" color = "Maroon" stopateol = "true">
<Begin>'</Begin>
<End>'</End>
</Span>
<Span name = "String2" bold = "false" italic = "false" color = "Maroon" stopateol = "true">
<Begin>"</Begin>
<End>"</End>
</Span>
<KeyWords name = "KeyWords" bold = "true" italic = "false" color = "Black">
<Key word = "CONST" />
<Key word = "IF" />
<Key word = "FOR" />
<Key word = "TO" />
<Key word = "THEN" />
<Key word = "ELSE" />
<Key word = "OR" />
<Key word = "VAR" />
<Key word = "WHILE" />
<Key word = "BEGIN" />
<Key word = "END" />
<Key word = "TYPE" />
<Key word = "MODULE" />
<Key word = "DO" />
<Key word = "PROCEDURE" />
<Key word = "DIV" />
<Key word = "MOD" />
</KeyWords>
<KeyWords name = "TypesAndTypedeal" bold = "false" italic = "false" color = "Blue">
<Key word = "TRUE" />
<Key word = "FALSE" />
<Key word = "BOOLEAN" />
<Key word = "SHORTINT" />
<Key word = "INTEGER" />
<Key word = "LONGINT" />
<Key word = "REAL" />
<Key word = "LONGREAL" />
<Key word = "CHAR" />
<Key word = "SET" />
</KeyWords>
<KeyWords name = "StandartMethods" bold = "false" italic = "false" color = "DarkGreen">
<Key word = "ODD" />
</KeyWords>
<KeyWords name = "Punctuation" bold = "false" italic = "false" color = "Black">
<Key word = ":=" />
<Key word = "," />
<Key word = "." />
<Key word = ";" />
<Key word = "(" />
<Key word = ")" />
<Key word = "+" />
<Key word = "-" />
<Key word = "/" />
<Key word = "*" />
<Key word = "&lt;" />
<Key word = "&gt;" />
<Key word = "&lt;=" />
<Key word = "&gt;=" />
<Key word = "~" />
<Key word = "#" />
<Key word = "=" />
</KeyWords>
</RuleSet>
<RuleSet name = "CommentMarkerSet" ignorecase = "true">
<Delimiters>&lt;&gt;~!@%^*()-+=|\#/{}[]:;"' , .?</Delimiters>
<KeyWords name = "ErrorWords" bold="true" italic="false" color="Red">
<Key word = "TODO" />
<Key word = "FIXME" />
</KeyWords>
<KeyWords name = "WarningWords" bold="true" italic="false" color="#EEE0E000">
<Key word = "HACK" />
<Key word = "UNDONE" />
</KeyWords>
</RuleSet>
</RuleSets>
</SyntaxDefinition>

View file

@ -1,58 +0,0 @@
// (c) Mikst, Juliet 2010
/// Системный модуль для языка Oberon
unit Oberon00System;
interface
type
/// Логический тип (TRUE | FALSE)
BOOLEAN = System.boolean;
/// Целое число
INTEGER = System.Int32;
/// Короткое целое число
SHORTINT = System.byte;
/// Длинное целое число
LONGINT = System.int64;
/// Вещественное число
REAL = System.double;
/// Длинное вещественное число
LONGREAL = System.double;
/// Символ
CHAR = System.char;
/// Строка
STRING = System.string;
/// Множество целых
iset = array of integer;
procedure Print(o: object);
procedure Println(o: object);
procedure Println(o1,o2: integer);
procedure Println;
implementation
uses System;
procedure Print(o: object);
begin
Console.Write(o);
end;
/// Вывести значение
procedure Println(o: object);
begin
Console.WriteLine(o);
end;
procedure Println(o1,o2: integer);
begin
Print(o1);
Println(o2);
end;
procedure Println;
begin
Console.WriteLine;
end;
end.

View file

@ -1,134 +0,0 @@
using System.Collections.Generic;
using PascalABCCompiler.SyntaxTree;
using PascalABCCompiler.Errors;
using QUT.Gppg;
using GPPGParserScanner;
namespace PascalABCCompiler.Oberon00Parser
{
// Класс глобальных описаний и статических методов
// для использования различными подсистемами парсера и сканера
public static class PT // PT - parser tools
{
public static List<Error> Errors;
/// Последний прочтенный идентификатор
public static string LastIdentificator = "";
//public static int max_errors;
public static string CurrentFileName;
/// Словарь стандартных типов с соответствующими внутренними именами
public static Dictionary<string, string> standartTypes = new Dictionary<string, string>();
/// Статический конструктор
static PT() {
standartTypes.Add("BOOLEAN", "boolean");
standartTypes.Add("INTEGER", "integer");
standartTypes.Add("SHORTINT", "byte");
standartTypes.Add("LONGINT", "int64");
standartTypes.Add("REAL", "real");
standartTypes.Add("LONGREAL", "double");
standartTypes.Add("CHAR", "char");
standartTypes.Add("STRING", "string");
}
public static SourceContext ToSourceContext(LexLocation loc)
{
if (loc != null)
return new SourceContext(loc.StartLine, loc.StartColumn + 1, loc.EndLine, loc.EndColumn);
return null;
}
public static string CreateErrorString(params object[] args)
{
string[] ww = new string[args.Length - 1];
for (int i = 1; i < args.Length; i++)
ww[i - 1] = GetStrByTokenName((string)args[i]);
string w = string.Join(" или ", ww);
System.Collections.Generic.List<int> l = new List<int>();
string got = (string)args[0];
if (got.Equals("ID"))
got = "'" + LastIdentificator + "'";
else
got = GetStrByTokenName(got);
return string.Format("Синтаксическая ошибка: встречено {0}, а ожидалось {1}", got, w);
}
public static void AddError(string message, LexLocation loc)
{
Errors.Add(new SyntaxError(message, CurrentFileName, ToSourceContext(loc), null));
}
/// Определяет содержимое строки по ее представлению в тексте программы
/// <param name="sourceStr">Строка с кавычками</param>
/// <returns>Содержимое строки без кавычек</returns>
public static string GetStringContent(string sourceStr) {
bool hasStrType = (sourceStr.IndexOf('\'') != -1) ||
(sourceStr.IndexOf('"') != -1);
if (hasStrType)
return sourceStr.Substring(1, sourceStr.Length - 2);
else { // символ представлен 16ным кодом
string hexCode = sourceStr.Remove(sourceStr.Length - 1);
int tryParseHex;
if (int.TryParse(hexCode, System.Globalization.NumberStyles.AllowHexSpecifier, null, out tryParseHex))
return ((char)tryParseHex).ToString();
else
throw new System.ArgumentException("Некорректный шестнадцатеричный код символа");
}
}
/// Преобразует вещественный литерал, принятый в Обероне, к виду .NET
/// <param name="sourceDoubleStr">Исходная строка вещественного числа</param>
/// <returns>Корректную строку - вещественное число</returns>
public static string GetCorrectDoubleStr(string sourceDoubleStr) {
string correct = sourceDoubleStr.Replace(".",
System.Globalization.NumberFormatInfo.CurrentInfo.NumberDecimalSeparator);
correct = correct.Replace('D', 'E');
return correct;
}
/// Определяет внутреннее имя типа по типу в программе
/// <param name="typeName">Имя типа в программе</param>
/// <returns>Корректное внутреннее имя типа</returns>
public static string InternalTypeName(string typeName) {
if (standartTypes.ContainsKey(typeName))
return standartTypes[typeName];
else
return typeName;
}
// -----------------------------------------------------------------------------
// Вспомогательные методы
// -----------------------------------------------------------------------------
/// Возвращает по имени токена представляющую его строку
private static string GetStrByTokenName(string tokenName) {
switch (tokenName) {
case "ASSIGN": return "':='";
case "SEMICOLUMN": return "';'";
case "COLON": return "':'";
case "COMMA": return "'.'";
case "COLUMN": return "','";
case "LPAREN": return "'('";
case "RPAREN": return "')'";
case "PLUS": return "'+'";
case "MINUS": return "'-'";
case "MULT": return "'*'";
case "DIVIDE": return "'/'";
case "LT": return "'<'";
case "GT": return "'>'";
case "LE": return "'<='";
case "GE": return "'>='";
case "EQ": return "'='";
case "NE": return "'#'";
case "NOT": return "'~'";
case "AND": return "'&'";
case "EXCLAMATION": return "'!'";
case "ID": return "идентификатор";
case "EOF": return "конец программы";
case "INTNUM": return "целое число";
case "ASTERISK": return "'*'";
default: return tokenName;
}
}
}
}

View file

@ -1,91 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProductVersion>9.0.30729</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{D215937C-36EA-4E60-B3EB-A2527DE39D19}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>Oberon00Parser</RootNamespace>
<AssemblyName>Oberon00Parser</AssemblyName>
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<StartupObject>
</StartupObject>
<FileUpgradeFlags>
</FileUpgradeFlags>
<UpgradeBackupLocation>
</UpgradeBackupLocation>
<OldToolsVersion>3.5</OldToolsVersion>
<TargetFrameworkProfile />
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Core">
<RequiredTargetFramework>3.5</RequiredTargetFramework>
</Reference>
<Reference Include="System.Xml.Linq">
<RequiredTargetFramework>3.5</RequiredTargetFramework>
</Reference>
<Reference Include="System.Data.DataSetExtensions">
<RequiredTargetFramework>3.5</RequiredTargetFramework>
</Reference>
<Reference Include="System.Data" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="oberon00.cs" />
<Compile Include="Oberon00ParserTools.cs" />
<Compile Include="oberon00yacc.cs" />
<Compile Include="Parser.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="ShiftReduceParserCode.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\Errors\Errors.csproj">
<Project>{44a01f9e-dce7-470c-aae5-c3de0ccbee3b}</Project>
<Name>Errors</Name>
</ProjectReference>
<ProjectReference Include="..\..\Localization\Localization.csproj">
<Project>{2de2842f-0912-4251-bc0f-480854c44a13}</Project>
<Name>Localization</Name>
</ProjectReference>
<ProjectReference Include="..\..\ParserTools\ParserTools.csproj">
<Project>{af2efd7b-69dd-4b43-af65-b59b29349c23}</Project>
<Name>ParserTools</Name>
</ProjectReference>
<ProjectReference Include="..\..\SyntaxTree\SyntaxTree.csproj">
<Project>{c2cac65a-b2ae-4ccc-b067-e6b8e75df73a}</Project>
<Name>SyntaxTree</Name>
</ProjectReference>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>

View file

@ -1,44 +0,0 @@

Microsoft Visual Studio Solution File, Format Version 11.00
# Visual Studio 2010
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ObrProba", "ObrProba.csproj", "{D215937C-36EA-4E60-B3EB-A2527DE39D19}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Errors", "..\..\Errors\Errors.csproj", "{44A01F9E-DCE7-470C-AAE5-C3DE0CCBEE3B}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ParserTools", "..\..\ParserTools\ParserTools.csproj", "{AF2EFD7B-69DD-4B43-AF65-B59B29349C23}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Localization", "..\..\Localization\Localization.csproj", "{2DE2842F-0912-4251-BC0F-480854C44A13}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SyntaxTree", "..\..\SyntaxTree\SyntaxTree.csproj", "{C2CAC65A-B2AE-4CCC-B067-E6B8E75DF73A}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{D215937C-36EA-4E60-B3EB-A2527DE39D19}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{D215937C-36EA-4E60-B3EB-A2527DE39D19}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D215937C-36EA-4E60-B3EB-A2527DE39D19}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D215937C-36EA-4E60-B3EB-A2527DE39D19}.Release|Any CPU.Build.0 = Release|Any CPU
{44A01F9E-DCE7-470C-AAE5-C3DE0CCBEE3B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{44A01F9E-DCE7-470C-AAE5-C3DE0CCBEE3B}.Debug|Any CPU.Build.0 = Debug|Any CPU
{44A01F9E-DCE7-470C-AAE5-C3DE0CCBEE3B}.Release|Any CPU.ActiveCfg = Release|Any CPU
{44A01F9E-DCE7-470C-AAE5-C3DE0CCBEE3B}.Release|Any CPU.Build.0 = Release|Any CPU
{AF2EFD7B-69DD-4B43-AF65-B59B29349C23}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{AF2EFD7B-69DD-4B43-AF65-B59B29349C23}.Debug|Any CPU.Build.0 = Debug|Any CPU
{AF2EFD7B-69DD-4B43-AF65-B59B29349C23}.Release|Any CPU.ActiveCfg = Release|Any CPU
{AF2EFD7B-69DD-4B43-AF65-B59B29349C23}.Release|Any CPU.Build.0 = Release|Any CPU
{2DE2842F-0912-4251-BC0F-480854C44A13}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{2DE2842F-0912-4251-BC0F-480854C44A13}.Debug|Any CPU.Build.0 = Debug|Any CPU
{2DE2842F-0912-4251-BC0F-480854C44A13}.Release|Any CPU.ActiveCfg = Release|Any CPU
{2DE2842F-0912-4251-BC0F-480854C44A13}.Release|Any CPU.Build.0 = Release|Any CPU
{C2CAC65A-B2AE-4CCC-B067-E6B8E75DF73A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{C2CAC65A-B2AE-4CCC-B067-E6B8E75DF73A}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C2CAC65A-B2AE-4CCC-B067-E6B8E75DF73A}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C2CAC65A-B2AE-4CCC-B067-E6B8E75DF73A}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

View file

@ -1,59 +0,0 @@
using System;
using System.IO;
using System.Text;
using System.Reflection;
using PascalABCCompiler;
using PascalABCCompiler.SyntaxTree;
using PascalABCCompiler.Parsers;
using PascalABCCompiler.Errors;
using System.Collections.Generic;
using GPPGParserScanner;
namespace PascalABCCompiler.Oberon00Parser
{
public class Oberon00LanguageParser : BaseParser
{
public Oberon00LanguageParser()
: base("Oberon00", "0.1", "(c) Stanislav Mikhalkovich, 2010", true, new string[] { ".obr" })
{
}
public override syntax_tree_node BuildTreeInNormalMode(string FileName, string Text)
{
PT.Errors = Errors;
PT.CurrentFileName = FileName;
Scanner scanner = new Scanner();
scanner.SetSource(Text, 0);
GPPGParser parser = new GPPGParser(scanner);
if (!parser.Parse())
if (Errors.Count == 0)
PT.AddError("Неопознанная синтаксическая ошибка!", null);
return parser.root;
}
public override syntax_tree_node BuildTreeInExprMode(string FileName, string Text)
{
PT.Errors = Errors;
PT.CurrentFileName = FileName;
Scanner scanner = new Scanner();
// Добавление в начало текста символа с кодом 1. Используется для парсинга выражений с последующим использованием в Intellisense
Text = String.Concat((char)1, Text);
scanner.SetSource(Text, 0);
GPPGParser parser = new GPPGParser(scanner);
if (!parser.Parse())
if (Errors.Count == 0)
PT.AddError("Не разобрали выражение", null);
return parser.root;
}
}
}

View file

@ -1,36 +0,0 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("ObrProba")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("ObrProba")]
[assembly: AssemblyCopyright("Copyright © 2010")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("517903e0-51c4-49d1-bc84-2f833a408b60")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]

View file

@ -1,950 +0,0 @@
// Gardens Point Parser Generator
// Copyright (c) Wayne Kelly, QUT 2005-2009
// (see accompanying GPPGcopyright.rtf)
#define EXPORT_GPPG
using System;
using System.Text;
using System.Globalization;
using System.Collections.Generic;
using System.Runtime.Serialization;
using System.Diagnostics.CodeAnalysis;
using PascalABCCompiler.SyntaxTree;
namespace QUT.Gppg
{
/// <summary>
/// Abstract class for GPPG shift-reduce parsers.
/// Parsers generated by GPPG derive from this base
/// class, overriding the abstract Initialize() and
/// DoAction() methods.
/// </summary>
/// <typeparam name="TValue">Semantic value type</typeparam>
/// <typeparam name="TSpan">Location type</typeparam>
#if EXPORT_GPPG
public abstract class ShiftReduceParser<TValue, TSpan>
#else
internal abstract class ShiftReduceParser<TValue, TSpan>
#endif
where TSpan : IMerge<TSpan>, new()
{
public AbstractScanner<TValue, TSpan> scanner;
/// <summary>
/// The abstract scanner for this parser.
/// </summary>
protected AbstractScanner<TValue, TSpan> Scanner {
get { return scanner; }
set { scanner = value; }
}
/// <summary>
/// Constructor for base class
/// </summary>
/// <param name="scanner">Scanner instance for this parser</param>
protected ShiftReduceParser(AbstractScanner<TValue, TSpan> scanner)
{
this.scanner = scanner;
}
// ==============================================================
// TECHNICAL EXPLANATION.
// Why the next two fields are not exposed via properties.
// ==============================================================
// These fields are of the generic parameter types, and are
// frequently instantiated as struct types in derived classes.
// Semantic actions are defined in the derived classes and refer
// to instance fields of these structs. Is such cases the code
// "get_CurrentSemanticValue().myField = blah;" will fail since
// the getter pushes the value of the field, not the reference.
// So, in the presence of properties, gppg would need to encode
// such field accesses as ...
// "tmp = get_CurrentSemanticValue(); // Fetch value
// tmp.myField = blah; // update
// set_CurrentSemanticValue(tmp); " // Write update back.
// There is no issue if TValue is restricted to be a ref type.
// The same explanation applies to scanner.yylval.
// ==============================================================
/// <summary>
/// The current value of the "$$" symbolic variable in the parser
/// </summary>
[SuppressMessage("Microsoft.Design", "CA1051:DoNotDeclareVisibleInstanceFields")]
protected TValue CurrentSemanticValue;
/// <summary>
/// The current value of the "@$" symbolic variable in the parser
/// </summary>
[SuppressMessage("Microsoft.Design", "CA1051:DoNotDeclareVisibleInstanceFields")]
protected TSpan CurrentLocationSpan;
private TSpan LastSpan;
private int NextToken;
private State FsaState;
private bool recovering;
private int tokensSinceLastError;
private PushdownPrefixState<State> StateStack = new PushdownPrefixState<State>();
private PushdownPrefixState<TValue> valueStack = new PushdownPrefixState<TValue>();
private PushdownPrefixState<TSpan> locationStack = new PushdownPrefixState<TSpan>();
/// <summary>
/// The stack of semantic value (YYSTYPE) values.
/// </summary>
protected PushdownPrefixState<TValue> ValueStack { get { return valueStack; } }
/// <summary>
/// The stack of location value (YYLTYPE) varlues.
/// </summary>
protected PushdownPrefixState<TSpan> LocationStack { get { return locationStack; } }
private int errorToken;
private int endOfFileToken;
private string[] nonTerminals;
private State[] states;
private Rule[] rules;
/// <summary>
/// Initialization method to allow derived classes
/// to insert the rule list into this base class.
/// </summary>
/// <param name="rules">The array of Rule objects</param>
protected void InitRules(Rule[] rules) { this.rules = rules; }
/// <summary>
/// Initialization method to allow derived classes to
/// insert the states table into this base class.
/// </summary>
/// <param name="states">The pre-initialized states table</param>
protected void InitStates(State[] states) { this.states = states; }
/// <summary>
/// OBSOLETE FOR VERSION 1.4.0
/// </summary>
/// <param name="size"></param>
protected void InitStateTable(int size) { states = new State[size]; }
/// <summary>
/// Initialization method to allow derived classes
/// to insert the special value for the error and EOF tokens.
/// </summary>
/// <param name="err">The error state ordinal</param>
/// <param name="end">The EOF stat ordinal</param>
protected void InitSpecialTokens(int err, int end)
{
errorToken = err;
endOfFileToken = end;
}
/// <summary>
/// Initialization method to allow derived classes to
/// insert the non-terminal symbol names into this base class.
/// </summary>
/// <param name="names">Non-terminal symbol names</param>
protected void InitNonTerminals(string[] names) { nonTerminals = names; }
#region YYAbort, YYAccept etcetera.
[Serializable]
[SuppressMessage("Microsoft.Design", "CA1064:ExceptionsShouldBePublic")]
// Reason for FxCop message suppression -
// This exception cannot escape from the local context
private class AcceptException : Exception
{
internal AcceptException() { }
protected AcceptException(SerializationInfo i, StreamingContext c) : base(i, c) { }
}
[Serializable]
[SuppressMessage("Microsoft.Design", "CA1064:ExceptionsShouldBePublic")]
// Reason for FxCop message suppression -
// This exception cannot escape from the local context
private class AbortException : Exception
{
internal AbortException() { }
protected AbortException(SerializationInfo i, StreamingContext c) : base(i, c) { }
}
[Serializable]
[SuppressMessage("Microsoft.Design", "CA1064:ExceptionsShouldBePublic")]
// Reason for FxCop message suppression -
// This exception cannot escape from the local context
private class ErrorException : Exception
{
internal ErrorException() { }
protected ErrorException(SerializationInfo i, StreamingContext c) : base(i, c) { }
}
// The following methods are only called from within
// a semantic action. The thrown exceptions can never
// propagate outside the ShiftReduceParser class in
// which they are nested.
/// <summary>
/// Force parser to terminate, returning "true"
/// </summary>
protected static void YYAccept() { throw new AcceptException(); }
/// <summary>
/// Force parser to terminate, returning "false"
/// </summary>
protected static void YYAbort() { throw new AbortException(); }
/// <summary>
/// Force parser to terminate, returning
/// "false" if error recovery fails.
/// </summary>
protected static void YYError() { throw new ErrorException(); }
/// <summary>
/// Check if parser in error recovery state.
/// </summary>
protected bool YYRecovering { get { return recovering; } }
#endregion
/// <summary>
/// Abstract base method. ShiftReduceParser calls this
/// to initialize the base class data structures. Concrete
/// parser classes must override this method.
/// </summary>
protected abstract void Initialize();
/// <summary>
/// Main entry point of the Shift-Reduce Parser.
/// </summary>
/// <returns>True if parse succeeds, else false for
/// unrecoverable errors</returns>
public bool Parse()
{
Initialize(); // allow derived classes to instantiate rules, states and nonTerminals
NextToken = 0;
FsaState = states[0];
StateStack.Push(FsaState);
valueStack.Push(CurrentSemanticValue);
LocationStack.Push(CurrentLocationSpan);
while (true)
{
#if TRACE_ACTIONS
Console.Error.WriteLine("Entering state {0} ", FsaState.number);
#endif
int action = FsaState.defaultAction;
if (FsaState.ParserTable != null)
{
if (NextToken == 0)
{
#if TRACE_ACTIONS
Console.Error.Write("Reading a token: ");
#endif
// We save the last token span, so that the location span
// of production right hand sides that begin or end with a
// nullable production will be correct.
LastSpan = scanner.yylloc;
NextToken = scanner.yylex();
}
#if TRACE_ACTIONS
Console.Error.WriteLine("Next token is {0}", TerminalToString(NextToken));
#endif
if (FsaState.ParserTable.ContainsKey(NextToken))
action = FsaState.ParserTable[NextToken];
}
if (action > 0) // shift
{
Shift(action);
}
else if (action < 0) // reduce
{
try
{
Reduce(-action);
if (action == -1) // accept
return true;
}
catch (Exception x)
{
if (x is AbortException)
return false;
else if (x is AcceptException)
return true;
else if (x is ErrorException && !ErrorRecovery())
return false;
else
throw; // Rethrow x, preserving information.
}
}
else if (action == 0) // error
if (!ErrorRecovery())
return false;
}
}
private void Shift(int stateIndex)
{
#if TRACE_ACTIONS
Console.Error.Write("Shifting token {0}, ", TerminalToString(NextToken));
#endif
FsaState = states[stateIndex];
valueStack.Push(scanner.yylval);
StateStack.Push(FsaState);
LocationStack.Push(scanner.yylloc);
if (recovering)
{
if (NextToken != errorToken)
tokensSinceLastError++;
if (tokensSinceLastError > 5)
recovering = false;
}
if (NextToken != endOfFileToken)
NextToken = 0;
}
private void Reduce(int ruleNumber)
{
#if TRACE_ACTIONS
DisplayRule(ruleNumber);
#endif
Rule rule = rules[ruleNumber];
//
// Default actions for unit productions.
//
if (rule.RightHandSide.Length == 1)
{
CurrentSemanticValue = valueStack.TopElement(); // Default action: $$ = $1;
CurrentLocationSpan = LocationStack.TopElement(); // Default action "@$ = @1;
}
else
{
if (rule.RightHandSide.Length == 0)
{
// Create a new blank value.
// Explicit semantic action may mutate this value
CurrentSemanticValue = default(TValue);
// The location span for an empty production will start with the
// beginning of the next lexeme, and end with the finish of the
// previous lexeme. This gives the correct behaviour when this
// nonsense value is used in later Merge operations.
CurrentLocationSpan = (scanner.yylloc != null && LastSpan != null ?
scanner.yylloc.Merge(LastSpan) :
default(TSpan));
}
else
{
// Default action: $$ = $1;
CurrentSemanticValue = valueStack.TopElement();
// Default action "@$ = @1.Merge(@N)" for location info.
TSpan at1 = LocationStack[LocationStack.Depth - rule.RightHandSide.Length];
TSpan atN = LocationStack[LocationStack.Depth - 1];
CurrentLocationSpan =
((at1 != null && atN != null) ? at1.Merge(atN) : default(TSpan));
}
}
DoAction(ruleNumber);
for (int i = 0; i < rule.RightHandSide.Length; i++)
{
StateStack.Pop();
valueStack.Pop();
LocationStack.Pop();
}
#if TRACE_ACTIONS
DisplayStack();
#endif
FsaState = StateStack.TopElement();
if (FsaState.Goto.ContainsKey(rule.LeftHandSide))
FsaState = states[FsaState.Goto[rule.LeftHandSide]];
StateStack.Push(FsaState);
valueStack.Push(CurrentSemanticValue);
LocationStack.Push(CurrentLocationSpan);
}
/// <summary>
/// Execute the selected action from array.
/// Must be overriden in derived classes.
/// </summary>
/// <param name="actionNumber">Index of the action to perform</param>
protected abstract void DoAction(int actionNumber);
private bool ErrorRecovery()
{
bool discard;
if (!recovering) // if not recovering from previous error
ReportError();
if (!FindErrorRecoveryState())
return false;
//
// The interim fix for the "looping in error recovery"
// artifact involved moving the setting of the recovering
// bool until after invalid tokens have been discarded.
//
ShiftErrorToken();
discard = DiscardInvalidTokens();
recovering = true;
tokensSinceLastError = 0;
return discard;
}
private void ReportError1()
{
StringBuilder errorMsg = new StringBuilder();
errorMsg.AppendFormat("Syntax error, unexpected {0}", TerminalToString(NextToken));
if (FsaState.ParserTable.Count < 7)
{
bool first = true;
foreach (int terminal in FsaState.ParserTable.Keys)
{
if (first)
errorMsg.Append(", expecting ");
else
errorMsg.Append(", or ");
errorMsg.Append(TerminalToString(terminal));
first = false;
}
}
scanner.yyerror(errorMsg.ToString());
}
private void ReportError()
{
object[] args = new object[FsaState.ParserTable.Keys.Count+1];
args[0] = TerminalToString(NextToken);
int i=1;
foreach (int terminal in FsaState.ParserTable.Keys)
{
args[i] = TerminalToString(terminal);
i++;
}
scanner.yyerror("",args);
}
private void ShiftErrorToken()
{
int old_next = NextToken;
NextToken = errorToken;
Shift(FsaState.ParserTable[NextToken]);
#if TRACE_ACTIONS
Console.Error.WriteLine("Entering state {0} ", FsaState.number);
#endif
NextToken = old_next;
}
private bool FindErrorRecoveryState()
{
while (true) // pop states until one found that accepts error token
{
if (FsaState.ParserTable != null &&
FsaState.ParserTable.ContainsKey(errorToken) &&
FsaState.ParserTable[errorToken] > 0) // shift
return true;
#if TRACE_ACTIONS
Console.Error.WriteLine("Error: popping state {0}", StateStack.Top().number);
#endif
StateStack.Pop();
valueStack.Pop();
LocationStack.Pop();
#if TRACE_ACTIONS
DisplayStack();
#endif
if (StateStack.IsEmpty())
{
#if TRACE_ACTIONS
Console.Error.Write("Aborting: didn't find a state that accepts error token");
#endif
return false;
}
else
FsaState = StateStack.TopElement();
}
}
private bool DiscardInvalidTokens()
{
int action = FsaState.defaultAction;
if (FsaState.ParserTable != null)
{
// Discard tokens until find one that works ...
while (true)
{
if (NextToken == 0)
{
#if TRACE_ACTIONS
Console.Error.Write("Reading a token: ");
#endif
NextToken = scanner.yylex();
}
#if TRACE_ACTIONS
Console.Error.WriteLine("Next token is {0}", TerminalToString(NextToken));
#endif
if (NextToken == endOfFileToken)
return false;
if (FsaState.ParserTable.ContainsKey(NextToken))
action = FsaState.ParserTable[NextToken];
if (action != 0)
return true;
else
{
#if TRACE_ACTIONS
Console.Error.WriteLine("Error: Discarding {0}", TerminalToString(NextToken));
#endif
NextToken = 0;
}
}
}
else if (recovering && tokensSinceLastError == 0)
{
//
// Boolean recovering is not set until after the first
// error token has been shifted. Thus if we get back
// here with recovering set and no tokens read we are
// looping on the same error recovery action. This
// happens if current_state.ParserTable is null because
// the state has an LR(0) reduction, but not all
// lookahead tokens are valid. This only occurs for
// error productions that *end* on "error".
//
// This action discards tokens one at a time until
// the looping stops. Another attack would be to always
// use the LALR(1) table if a production ends on "error"
//
#if TRACE_ACTIONS
Console.Error.WriteLine("Error: panic discard of {0}", TerminalToString(NextToken));
#endif
if (NextToken == endOfFileToken)
return false;
NextToken = 0;
return true;
}
else
return true;
}
/// <summary>
/// Traditional YACC method. Discards the next input token.
/// </summary>
[SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "yyclearin")]
[SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "yyclearin")]
// Reason for FxCop message suppression -
// This is a traditional name for YACC-like functionality
protected void yyclearin() { NextToken = 0; }
/// <summary>
/// Tradional YACC method. Clear the "recovering" flag.
/// </summary>
[SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "yyerrok")]
[SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "yyerrok")]
// Reason for FxCop message suppression -
// This is a traditional name for YACC-like functionality
protected void yyerrok()
{
recovering = false;
}
/// <summary>
/// OBSOLETE FOR VERSION 1.4.0
/// Method used by derived types to insert new
/// state instances in the "states" array.
/// </summary>
/// <param name="stateNumber">index of the state</param>
/// <param name="state">data for the state</param>
protected void AddState(int stateNumber, State state)
{
states[stateNumber] = state;
state.number = stateNumber;
}
private void DisplayStack()
{
Console.Error.Write("State now");
for (int i = 0; i < StateStack.Depth; i++)
Console.Error.Write(" {0}", StateStack[i].number);
Console.Error.WriteLine();
}
private void DisplayRule(int ruleNumber)
{
Console.Error.Write("Reducing stack by rule {0}, ", ruleNumber);
DisplayProduction(rules[ruleNumber]);
}
private void DisplayProduction(Rule rule)
{
if (rule.RightHandSide.Length == 0)
Console.Error.Write("/* empty */ ");
else
foreach (int symbol in rule.RightHandSide)
Console.Error.Write("{0} ", SymbolToString(symbol));
Console.Error.WriteLine("-> {0}", SymbolToString(rule.LeftHandSide));
}
/// <summary>
/// Abstract state class naming terminal symbols.
/// This is overridden by derived classes with the
/// name (or alias) to be used in error messages.
/// </summary>
/// <param name="terminal">The terminal ordinal</param>
/// <returns></returns>
protected abstract string TerminalToString(int terminal);
private string SymbolToString(int symbol)
{
if (symbol < 0)
return nonTerminals[-symbol];
else
return TerminalToString(symbol);
}
/// <summary>
/// Return text representation of argument character
/// </summary>
/// <param name="input">The character to convert</param>
/// <returns>String representation of the character</returns>
protected static string CharToString(char input)
{
switch (input)
{
case '\a': return @"'\a'";
case '\b': return @"'\b'";
case '\f': return @"'\f'";
case '\n': return @"'\n'";
case '\r': return @"'\r'";
case '\t': return @"'\t'";
case '\v': return @"'\v'";
case '\0': return @"'\0'";
default: return string.Format(CultureInfo.InvariantCulture, "'{0}'", input);
}
}
}
/// <summary>
/// Classes implementing this interface must supply a
/// method that merges two location objects to return
/// a new object of the same type.
/// GPPG-generated parsers have the default location
/// action equivalent to "@$ = @1.Merge(@N);" where N
/// is the right-hand-side length of the production.
/// </summary>
/// <typeparam name="TSpan">The Location type</typeparam>
#if EXPORT_GPPG
public interface IMerge<TSpan>
#else
internal interface IMerge<TSpan>
#endif
{
/// <summary>
/// Interface method that creates a location object from
/// the current and last object. Typically used to create
/// a location object extending from the start of the @1
/// object to the end of the @N object.
/// </summary>
/// <param name="last">The lexically last object to merge</param>
/// <returns>The merged location object</returns>
TSpan Merge(TSpan last);
}
/// <summary>
/// This is the default class that carries location
/// information from the scanner to the parser.
/// If you don't declare "%YYLTYPE Foo" the parser
/// will expect to deal with this type.
/// </summary>
#if EXPORT_GPPG
public class LexLocation : IMerge<LexLocation>
#else
[SuppressMessage("Microsoft.Performance", "CA1812:AvoidUninstantiatedInternalClasses")]
internal class LexLocation : IMerge<LexLocation>
#endif
{
private int startLine; // start line
private int startColumn; // start column
private int endLine; // end line
private int endColumn; // end column
/// <summary>
/// The line at which the text span starts.
/// </summary>
public int StartLine { get { return startLine; } }
/// <summary>
/// The column at which the text span starts.
/// </summary>
public int StartColumn { get { return startColumn; } }
/// <summary>
/// The line on which the text span ends.
/// </summary>
public int EndLine { get { return endLine; } }
/// <summary>
/// The column of the first character
/// beyond the end of the text span.
/// </summary>
public int EndColumn { get { return endColumn; } }
/// <summary>
/// Default no-arg constructor.
/// </summary>
public LexLocation()
{ }
/// <summary>
/// Constructor for text-span with given start and end.
/// </summary>
/// <param name="sl">start line</param>
/// <param name="sc">start column</param>
/// <param name="el">end line </param>
/// <param name="ec">end column</param>
public LexLocation(int sl, int sc, int el, int ec)
{ startLine = sl; startColumn = sc; endLine = el; endColumn = ec; }
/// <summary>
/// Create a text location which spans from the
/// start of "this" to the end of the argument "last"
/// </summary>
/// <param name="last">The last location in the result span</param>
/// <returns>The merged span</returns>
public LexLocation Merge(LexLocation last)
{ return new LexLocation(this.startLine, this.startColumn, last.endLine, last.endColumn); }
public static implicit operator SourceContext(LexLocation loc)
{
return new SourceContext(loc.StartLine, loc.StartColumn + 1, loc.EndLine, loc.EndColumn);
}
}
/// <summary>
/// Abstract scanner class that GPPG expects its scanners to
/// extend.
/// </summary>
/// <typeparam name="TValue">Semantic value type YYSTYPE</typeparam>
/// <typeparam name="TSpan">Source location type YYLTYPE</typeparam>
#if EXPORT_GPPG
public abstract class AbstractScanner<TValue, TSpan>
#else
internal abstract class AbstractScanner<TValue, TSpan>
#endif
where TSpan : IMerge<TSpan>
{
/// <summary>
/// Lexical value optionally set by the scanner. The value
/// is of the %YYSTYPE type declared in the parser spec.
/// </summary>
[SuppressMessage("Microsoft.Design", "CA1051:DoNotDeclareVisibleInstanceFields")]
[SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "yylval")]
[SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "yylval")]
// Reason for FxCop message suppression -
// This is a traditional name for YACC-like functionality
// A field must be declared for this value of parametric type,
// since it may be instantiated by a value struct. If it were
// implemented as a property, machine generated code in derived
// types would not be able to select on the returned value.
public TValue yylval; // Lexical value: set by scanner
/// <summary>
/// Current scanner location property. The value is of the
/// type declared by %YYLTYPE in the parser specification.
/// </summary>
[SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "yylloc")]
[SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "yylloc")]
// Reason for FxCop message suppression -
// This is a traditional name for YACC-like functionality
public virtual TSpan yylloc
{
get { return default(TSpan); } // Empty implementation allowing
set { /* skip */ } // yylloc to be ignored entirely.
}
/// <summary>
/// Main call point for LEX-like scanners. Returns an int
/// corresponding to the token recognized by the scanner.
/// </summary>
/// <returns>An int corresponding to the token</returns>
[SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "yylex")]
[SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "yylex")]
// Reason for FxCop message suppression -
// This is a traditional name for YACC-like functionality
public abstract int yylex();
/// <summary>
/// Traditional error reporting provided by LEX-like scanners
/// to their YACC-like clients.
/// </summary>
/// <param name="format">Message format string</param>
/// <param name="args">Optional array of args</param>
[SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "yyerror")]
[SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "yyerror")]
// Reason for FxCop message suppression -
// This is a traditional name for YACC-like functionality
public virtual void yyerror(string format, params object[] args) { }
}
/// <summary>
/// Encapsulated state for the parser.
/// Opaque to users, visible to the tool-generated code.
/// </summary>
#if EXPORT_GPPG
public class State
#else
internal class State
#endif
{
internal int number;
internal Dictionary<int, int> ParserTable; // Terminal -> ParseAction
internal Dictionary<int, int> Goto; // NonTerminal -> State;
internal int defaultAction; // = 0; // ParseAction
/// <summary>
/// State transition data for this state. Pairs of elements of the
/// goto array associate symbol ordinals with next state indices.
/// The actions array is passed to another constructor.
/// </summary>
/// <param name="actions">The action list</param>
/// <param name="goToList">Next state data</param>
public State(int[] actions, int[] goToList)
: this(actions)
{
Goto = new Dictionary<int, int>();
for (int i = 0; i < goToList.Length; i += 2)
Goto.Add(goToList[i], goToList[i + 1]);
}
/// <summary>
/// Action data for this state. Pairs of elements of the
/// action array associate action ordinals with each of
/// those symbols that have actions in the current state.
/// </summary>
/// <param name="actions">The action array</param>
public State(int[] actions)
{
ParserTable = new Dictionary<int, int>();
for (int i = 0; i < actions.Length; i += 2)
ParserTable.Add(actions[i], actions[i + 1]);
}
/// <summary>
/// Set the default action for this state.
/// </summary>
/// <param name="defaultAction">Ordinal of the default action</param>
public State(int defaultAction)
{
this.defaultAction = defaultAction;
}
/// <summary>
/// Set the default action and the state transition table.
/// </summary>
/// <param name="defaultAction">The default action</param>
/// <param name="goToList">Transitions from this state</param>
public State(int defaultAction, int[] goToList)
: this(defaultAction)
{
Goto = new Dictionary<int, int>();
for (int i = 0; i < goToList.Length; i += 2)
Goto.Add(goToList[i], goToList[i + 1]);
}
}
/// <summary>
/// Rule representation at runtime.
/// </summary>
#if EXPORT_GPPG
public class Rule
#else
internal class Rule
#endif
{
internal int LeftHandSide; // symbol
internal int[] RightHandSide; // symbols
/// <summary>
/// Rule constructor. This holds the ordinal of
/// the left hand side symbol, and the list of
/// right hand side symbols, in lexical order.
/// </summary>
/// <param name="left">The LHS non-terminal</param>
/// <param name="right">The RHS symbols, in lexical order</param>
public Rule(int left, int[] right)
{
this.LeftHandSide = left;
this.RightHandSide = right;
}
}
/// <summary>
/// Stack utility for the shift-reduce parser.
/// GPPG parsers have three instances:
/// (1) The parser state stack, T = QUT.Gppg.State,
/// (2) The semantic value stack, T = TValue,
/// (3) The location stack, T = TSpan.
/// </summary>
/// <typeparam name="T"></typeparam>
#if EXPORT_GPPG
public class PushdownPrefixState<T>
#else
internal class PushdownPrefixState<T>
#endif
{
// Note that we cannot use the BCL Stack<T> class
// here as derived types need to index into stacks.
//
private T[] array = new T[8];
private int tos = 0;
/// <summary>
/// Indexer for values of the stack below the top.
/// </summary>
/// <param name="index">index of the element, starting from the bottom</param>
/// <returns>the selected element</returns>
public T this[int index] { get { return array[index]; } }
/// <summary>
/// The current depth of the stack.
/// </summary>
public int Depth { get { return tos; } }
internal void Push(T value)
{
if (tos >= array.Length)
{
T[] newarray = new T[array.Length * 2];
System.Array.Copy(array, newarray, tos);
array = newarray;
}
array[tos++] = value;
}
internal T Pop()
{
T rslt = array[--tos];
array[tos] = default(T);
return rslt;
}
internal T TopElement() { return array[tos - 1]; }
internal bool IsEmpty() { return tos == 0; }
}
}

View file

@ -1,3 +0,0 @@
cls
GPLex_GPPG\gplex.exe /unicode oberon00.lex
GPLex_GPPG\gppg.exe /no-lines /gplex oberon00.y

View file

@ -1,9 +0,0 @@
cls
GPLex_GPPG\gplex.exe /unicode oberon00.lex
GPLex_GPPG\gppg.exe /no-lines /gplex oberon00.y
copy ..\..\bin\SyntaxTree.dll DLL\SyntaxTree.dll
%windir%\microsoft.net\framework\v3.5\msbuild /t:rebuild /property:Configuration=Release ObrProba.sln
copy bin\Release\Oberon00Parser.dll Install\PascalABC.NET\Oberon00Parser.dll
copy bin\Release\Oberon00Parser.dll ..\..\bin\Oberon00Parser.dll

File diff suppressed because it is too large Load diff

View file

@ -1,190 +0,0 @@
%namespace GPPGParserScanner
%using PascalABCCompiler.Oberon00Parser;
Digit [0-9]
HexDigit {Digit}|[A-F]
Alpha [a-zA-Z_]
EndLine \n // Êîíåö ñòðîêè
AlphaDigit {Alpha}|{Digit}
ScaleFactor [ED][\+\-]?{Digit}+
HEXINTNUM {Digit}{HexDigit}*H
INTNUM {Digit}+
REALNUM {Digit}+\.{Digit}*{ScaleFactor}?
ID {Alpha}{AlphaDigit}*
CHARACTER '[^'\n]'|\"[^\"\n]\"|{Digit}{HexDigit}*X
STRING '[^'\n]*'|\"[^\"\n]*\"
%x COMMENT // Ñîñòîÿíèå äëÿ êîììåíòàðèåâ
%x COMMENT_S // Ñîñòîÿíèå äëÿ îäíîñòðî÷íûõ êîììåíòàðèåâ
%%
":=" { return (int)Tokens.ASSIGN; }
";" { return (int)Tokens.SEMICOLUMN; }
"-" { return (int)Tokens.MINUS; }
"+" { return (int)Tokens.PLUS; }
"*" { return (int)Tokens.MULT; }
"/" { return (int)Tokens.DIVIDE; }
"<" { return (int)Tokens.LT; }
">" { return (int)Tokens.GT; }
"<=" { return (int)Tokens.LE; }
">=" { return (int)Tokens.GE; }
"=" { return (int)Tokens.EQ; }
"#" { return (int)Tokens.NE; }
"(" { return (int)Tokens.LPAREN; }
")" { return (int)Tokens.RPAREN; }
"," { return (int)Tokens.COLUMN; }
"~" { return (int)Tokens.NOT; }
"&" { return (int)Tokens.AND; }
"." { return (int)Tokens.COMMA; }
":" { return (int)Tokens.COLON; }
"!" { return (int)Tokens.EXCLAMATION; }
"{" { return (int)Tokens.LBRACE; }
"}" { return (int)Tokens.RBRACE; }
"[" { return (int)Tokens.LBRACKET; }
"]" { return (int)Tokens.RBRACKET; }
".." { return (int)Tokens.DOUBLEPOINT; }
"|" { return (int)Tokens.PIPE; }
\x01 { return (int)Tokens.INVISIBLE; }
"//" { BEGIN(COMMENT_S);} // Îäíîñòðî÷íûå êîììåíòàðèè
<COMMENT_S> {EndLine} { BEGIN(INITIAL);}
"(*" { // Ìíîãîñòðî÷íûå âëîæåííûå êîììåíòàðèè
BEGIN(COMMENT);
mlCommentCnt = 1;
}
<COMMENT> "(*" { ++mlCommentCnt; }
<COMMENT> "*)" {
--mlCommentCnt;
if (mlCommentCnt == 0)
BEGIN(INITIAL);
}
<COMMENT> <<EOF>> {
PT.AddError("Êîììåíòàðèé íå çàêðûò", yylloc);
}
{ID} {
int res = Keywords.KeywordOrIDToken(yytext);
if (res == (int)Tokens.ID){
yylval.sVal = yytext;
PT.LastIdentificator = yytext;
}
return res;
}
{INTNUM} {
int tryParseInt;
if (int.TryParse(yytext, out tryParseInt)){
yylval.iVal = tryParseInt;
return (int)Tokens.INTNUM;
}
System.Int64 tryParseLong;
if (System.Int64.TryParse(yytext, out tryParseLong)){
yylval.lVal = tryParseLong;
return (int)Tokens.LONGINTNUM;
}
PT.AddError("Ñëèøêîì äëèííîå öåëîå", yylloc);
}
{HEXINTNUM} {
var _yytext = yytext.Substring(0, yytext.Length - 1);
int tryParseHexInt;
if (int.TryParse(_yytext, System.Globalization.NumberStyles.AllowHexSpecifier, null, out tryParseHexInt)){
yylval.iVal = tryParseHexInt;
return (int)Tokens.INTNUM;
}
System.Int64 tryParseHexLong;
if (System.Int64.TryParse(_yytext, System.Globalization.NumberStyles.AllowHexSpecifier, null, out tryParseHexLong)){
yylval.lVal = tryParseHexLong;
return (int)Tokens.LONGINTNUM;
}
PT.AddError("Ñëèøêîì äëèííîå øåñòíàäöàòåðè÷íîå öåëîå", yylloc);
}
{REALNUM} {
double tryParseDouble;
var correctDouble = PT.GetCorrectDoubleStr(yytext);
if (double.TryParse(correctDouble, out tryParseDouble)){
yylval.rVal = tryParseDouble;
return (int)Tokens.REALNUM;
}
PT.AddError("Ñëèøêîì äëèííîå âåùåñòâåííîå", yylloc);
}
{CHARACTER} {
try{
yylval.cVal = PT.GetStringContent(yytext)[0];
return (int)Tokens.CHAR_CONST;
}
catch (System.ArgumentException){
PT.AddError("Íåêîððåêòíûé êîä ñèìâîëà", yylloc);
}
}
{STRING} {
yylval.sVal = PT.GetStringContent(yytext);
return (int)Tokens.STRING_CONST;
}
%{
yylloc = new QUT.Gppg.LexLocation(tokLin, tokCol, tokELin, tokECol);
%}
%%
// Ñ÷åò÷èê âëîæåííîñòè äëÿ ìíîãîñòðî÷íûõ âëîæåííûõ êîììåíòàðèåâ
static int mlCommentCnt = 0;
public override void yyerror(string format, params object[] args)
{
string errorMsg = PT.CreateErrorString(args);
PT.AddError(errorMsg,yylloc);
}
// Ñòàòè÷åñêèé êëàññ, îïðåäåëÿþùèé êëþ÷åâûå ñëîâà ÿçûêà
public static class Keywords
{
private static Dictionary<string, int> keywords = new Dictionary<string, int>();
static Keywords()
{
keywords.Add("TRUE", (int)Tokens.TRUE);
keywords.Add("FALSE", (int)Tokens.FALSE);
keywords.Add("ODD", (int)Tokens.ODD);
keywords.Add("OR", (int)Tokens.OR);
keywords.Add("DIV", (int)Tokens.DIV);
keywords.Add("MOD", (int)Tokens.MOD);
keywords.Add("BEGIN", (int)Tokens.BEGIN);
keywords.Add("END", (int)Tokens.END);
keywords.Add("MODULE", (int)Tokens.MODULE);
keywords.Add("CONST", (int)Tokens.CONST);
keywords.Add("VAR", (int)Tokens.VAR);
keywords.Add("TYPE", (int)Tokens.TYPE);
keywords.Add("ARRAY", (int)Tokens.ARRAY);
keywords.Add("OF", (int)Tokens.OF);
keywords.Add("RECORD", (int)Tokens.RECORD);
keywords.Add("POINTER", (int)Tokens.POINTER);
keywords.Add("IF", (int)Tokens.IF);
keywords.Add("THEN", (int)Tokens.THEN);
keywords.Add("ELSE", (int)Tokens.ELSE);
keywords.Add("ELSEIF", (int)Tokens.ELSEIF);
keywords.Add("WHILE", (int)Tokens.WHILE);
keywords.Add("DO", (int)Tokens.DO);
keywords.Add("REPEAT", (int)Tokens.REPEAT);
keywords.Add("UNTIL", (int)Tokens.UNTIL);
keywords.Add("FOR", (int)Tokens.FOR);
keywords.Add("TO", (int)Tokens.TO);
keywords.Add("BY", (int)Tokens.BY);
keywords.Add("CASE", (int)Tokens.CASE);
keywords.Add("PROCEDURE", (int)Tokens.PROCEDURE);
}
public static int KeywordOrIDToken(string s)
{
if (keywords.ContainsKey(s))
return keywords[s];
else
return (int)Tokens.ID;
}
}

View file

@ -1,906 +0,0 @@
// ==========================================================================
// GPPG error listing for yacc source file <oberon00.y>
// ==========================================================================
// Version: 1.3.6
// Machine: SSM
// DateTime: 13.03.2013 16:49:30
// UserName: Станислав
// ==========================================================================
%{
// Ýòè îáúÿâëåíèÿ äîáàâëÿþòñÿ â êëàññ GPPGParser, ïðåäñòàâëÿþùèé ñîáîé ïàðñåð, ãåíåðèðóåìûé ñèñòåìîé gppg
public syntax_tree_node root; // Êîðíåâîé óçåë ñèíòàêñè÷åñêîãî äåðåâà
public GPPGParser(AbstractScanner<ValueType, LexLocation> scanner) : base(scanner) { }
%}
%output=oberon00yacc.cs
%parsertype GPPGParser
%union
{
public bool bVal;
public string sVal;
public int iVal;
public long lVal; // Äëèííîå öåëîå
public char cVal;
public double rVal;
public pascal_set_constant sc; // Êîíñòàíòà - ìíîæåñòâî
public named_type_reference ntr; // Èìåíîâàííîå îïðåäåëåíèå òèïà
public type_definition tdef; // Ñàì òèï
public diapason dpsn; // Òèï äèàïàçîí
public array_type arrt; // Òèï ìàññèâ
public class_definition cldef; // Îïðåäåëåíèå çàïèñè
public indexers_types indts; // Òèï òèïû èíäåêñîâ ìàññèâà
public ref_type rft; // Òèï óêàçàòåëü
public ident_list il; // Ñïèñîê èäåíòèôèêàòîðîâ
public ident id; // Èäåíòèôèêàòîð
public oberon_ident_with_export_marker obrid; // Îáåðîíîâñêèé óòî÷íåííûé èäåíòèôèêàòîð
public oberon_export_marker obrem; // Îáåðîíîâñêàÿ ýêñïîðòíàÿ ìåòêà
public var_def_statement vds; // Îïèñàíèå ïåðåìåííûõ
public variable_definitions vdss; // Ñåêöèÿ îïèñàíèÿ ïåðåìåííûõ
public type_declarations td; // Ñåêöèÿ îïðåäåëåíèÿ òèïîâ
public type_declaration tdec; // Îïèñàíèå òèïà
public expression ex; // Âûðàæåíèå
public expression_list el; // Ñïèñîê âûðàæåíèé
public Operators ops; // Îïåðàòîðû (îïåðàöèè)
public block bl; // Ïðîãðàììíûé áëîê
public statement st; // Îïåðàòîð ïðîãðàììíûé
public statement_list sl; // Ñïèñîê îïåðàòîðîâ
public case_variants cvars; // Ñïèñîê âàðèàíòîâ îïåðàòîðà CASE
public case_variant cvar; // Âàðèàíò îïåðàòîðà CASE
public declaration decsec; // Îïèñàíèå
public declarations decl; // Ñïèñîê îïèñàíèé
public simple_const_definition scd; // Îïðåäåëåíèå êîíñòàíòû
public consts_definitions_list cdl; // Ñïèñîê îïèñàíèé êîíñòàíò
public procedure_definition pd; // Îïèñàíèå ïðîöåäóðû
public dot_node dn; // Óçåë â òî÷å÷íîé íîòàöèè
public addressed_value adrv; // Àäðåñîâàííîå çíà÷åíèå
}
%using PascalABCCompiler.SyntaxTree
%using PascalABCCompiler.Errors
%using PascalABCCompiler.Oberon00Parser
%namespace GPPGParserScanner
%start module // Ñòàðòîâûé ñèìâîë - ïðîãðàììíûé ìîäóëü
%token <sVal> ID STRING_CONST
%token <iVal> INTNUM
%token <rVal> REALNUM
%token <lVal> LONGINTNUM
%token <bVal> TRUE FALSE
%token <cVal> CHAR_CONST
%token <op> PLUS MINUS MULT DIVIDE AND OR LT GT LE GE EQ NE DIV MOD
%token NOT
%token ASSIGN SEMICOLUMN LPAREN RPAREN COLUMN COMMA COLON EXCLAMATION
%token LBRACE RBRACE DOUBLEPOINT LBRACKET RBRACKET PIPE
%token TRUE FALSE
%token IF THEN ELSE ELSEIF BEGIN END WHILE DO MODULE CONST VAR TYPE
%token INVISIBLE
%token PROCEDURE ARRAY OF RECORD REPEAT UNTIL FOR TO BY CASE POINTER
%token ODD
%type <id> ident specifiedIdent identDef
%type <obrid> identDef
%type <obrem> ExportLabel
%type <il> IDList
%type <ntr> complexTypeIdent
%type <sc> SetConstant SetElemList
%type <ex> expr ConstExpr SetElem SimpleExpr ForStep CaseVariantLabels
%type <ex> term signedTerm factor AddList FactorList
%type <st> Assignment IfStatement ElseIfStatements ElseStatements WhileStatement WriteStatement
%type <st> RepeatStatement Statement ForStatement CaseStatement ElseBranch
%type <st> EmptyStatement ProcCallStatement
%type <sl> StatementSequence
%type <cvars> CaseVariantList
%type <cvar> CaseVariant
%type <decl> Declarations
%type <decsec> DeclarationsSect
%type <vds> VarDecl
%type <vdss> VarDeclarations VarDeclarationsSect
%type <scd> ConstDecl
%type <cdl> ConstDeclarations ConstDeclarationsSect
%type <td> TypeDeclarationsSect TypeDeclarations
%type <tdec> TypeDecl
%type <tdef> TypeDef ArrayType
%type <rft> PointerType
%type <cldef> RecordType
%type <pd> ProcedureDeclarationSect
%type <bl> mainblock
%type <el> factparams ExprList CaseVariantLabelList
%type <dpsn> Length
%type <indts> LengthList
%type <ops> AddOperator MultOperator Relation
%type <adrv> specifiedIdent ComplexDesignator Designator
%type <bVal> maybevar
%left LT GT LE GE EQ NE
%left PLUS MINUS OR
%left MULT DIVIDE AND
%left NOT
%left UMINUS UPLUS
%%
// Warning: NonTerminal symbol "EmptyStatement" is unreachable
// -----------------------------------------------------------
module // Ïðîãðàììíûé ìîäóëü
: MODULE ident SEMICOLUMN mainblock ident COMMA
{
if ($2.name != $5.name)
PT.AddError("Èìÿ " + $5.name + " äîëæíî ñîâïàäàòü ñ èìåíåì ìîäóëÿ " + $2.name, @5);
// Ïîäêëþ÷åíèå ñòàíäàðòíîãî ìîäóëÿ Oberon00System, íàïèñàííîãî íà PascalABC.NET
var ul = new uses_list("Oberon00System");
// Ôîðìèðîâàíèå ìîäóëÿ îñíîâíîé ïðîãðàììû (èñïîëüçóåòñÿ ôàáðè÷íûé ìåòîä âìåñòî êîíñòðóêòîðà)
root = program_module.create($2, ul, $4, @$);
}
| INVISIBLE expr { // Äëÿ Intellisense
root = $2;
}
;
ident // Èäåíòèôèêàòîð
: ID {
$$ = new ident($1,@$);
}
;
specifiedIdent // Óòî÷íåííûé èäåíòèôèêàòîð
: ident COMMA ident {
$$ = new dot_node($1, $3, @$);
}
| ident {
$$ = $1;
}
;
identDef // Îïðåäåëåííûé èäåíòèôèêàòîð (âîçìîæíà ýêñïîðòíàÿ ìåòêà) TODO
: ident ExportLabel {
$$ = new oberon_ident_with_export_marker($1.name, $2, @$);
}
;
ExportLabel // Ýêñïîðòíàÿ ìåòêà TODO
: MULT {
$$ = oberon_export_marker.export;
}
| MINUS {
$$ = oberon_export_marker.export_readonly;
}
| {
//$$ = oberon_export_marker.nonexport;
$$ = oberon_export_marker.export;
}
;
mainblock // Ïðîãðàììíûé áëîê
: Declarations BEGIN StatementSequence END
{
$$ = new block($1, $3, @$);
}
;
SetConstant // Âûðàæåíèå-êîíñòàíòà ìíîæåñòâî TODO
: LBRACE SetElemList RBRACE {
$$ = $2;
$$.source_context = @$;
}
;
SetElemList // Ñïèñîê ýëåìåíòîâ ìíîæåñòâà TODO
: SetElem {
$$ = new pascal_set_constant();
$$.Add($1);
$$.source_context = @$;
}
| SetElemList COLUMN SetElem {
$$ = $1;
$$.Add($3);
$$.source_context = @$;
}
| {
$$ = new pascal_set_constant();
}
;
SetElem // Ýëåìåíò ìíîæåñòâà TODO
: expr
| expr DOUBLEPOINT expr {
$$ = new diapason_expr($1, $3, @$);
}
;
expr // Âûðàæåíèå
: SimpleExpr {
$$ = $1;
}
| SimpleExpr Relation SimpleExpr {
$$ = new bin_expr($1, $3, $2, @$);
}
;
Relation // Îòíîøåíèå
: EQ {
$$ = Operators.Equal;
}
| NE {
$$ = Operators.NotEqual;
}
| LT {
$$ = Operators.Less;
}
| LE {
$$ = Operators.LessEqual;
}
| GT {
$$ = Operators.Greater;
}
| GE {
$$ = Operators.GreaterEqual;
}
;
SimpleExpr // Ïðîñòîå âûðàæåíèå
: signedTerm {
$$ = $1;
$$.source_context = @$;
}
| signedTerm AddOperator AddList {
$$ = new bin_expr($1, $3, $2, @$);
}
;
signedTerm // Ñëàãàåìîå ñî çíàêîì
: term
| MINUS term %prec UMINUS {
$$ = new un_expr($2, Operators.Minus, @$);
}
| PLUS term %prec UPLUS {
$$ = new un_expr($2, Operators.Plus, @$);
}
;
AddList // Ñïèñîê ñî ñëàãàåìûìè
: term
| AddList AddOperator term {
$$ = new bin_expr($1, $3, $2, @$);
}
;
term // Ñëàãàåìîå
: factor
| factor MultOperator FactorList {
$$ = new bin_expr($1, $3, $2, @$);
}
;
FactorList // Ñïèñîê ñî ìíîæèòåëÿìè
: factor
| FactorList MultOperator factor {
$$ = new bin_expr($1, $3, $2, @$);
}
;
factor // Ìíîæèòåëü
: Designator {
$$ = $1;
}
| INTNUM {
$$ = new int32_const($1,@$);
}
| LONGINTNUM{
$$ = new int64_const($1, @$);
}
| REALNUM {
$$ = new double_const($1, @$);
}
| TRUE {
$$ = new bool_const(true,@$);
}
| FALSE {
$$ = new bool_const(false,@$);
}
| CHAR_CONST {
$$ = new char_const($1, @$);
}
| STRING_CONST {
$$ = new string_const($1, @$);
}
| LPAREN expr RPAREN {
$$ = $2;
}
| NOT factor {
$$ = new un_expr($2,Operators.LogicalNOT,@$);
}
| SetConstant
;
Designator // Îáîçíà÷åíèå (îáðàùåíèå ó ýëåìåòó ìàññèâà, ...) TODO
: specifiedIdent {
$$ = $1;
}
| ComplexDesignator {
$$ = $1;
}
;
ComplexDesignator // Ñîñòàâíîå îáîçíà÷åíèå TODO
: specifiedIdent COMMA ident {
$$ = new dot_node($1, $3, @$);
}
| specifiedIdent LBRACKET ExprList RBRACKET {
indexer indxr = new indexer();
indxr.dereferencing_value = $1;
indxr.indexes = $3;
$$ = indxr;
$$.source_context = @$;
}
| ComplexDesignator COMMA ident {
$$ = new dot_node($1, $3, @$);
}
| ComplexDesignator LBRACKET ExprList RBRACKET {
indexer indxr = new indexer();
indxr.dereferencing_value = $1;
indxr.indexes = $3;
$$ = indxr;
$$.source_context = @$;
}
;
ExprList // Ñïèñîê âûðàæåíèé
: expr {
$$ = new expression_list($1, @$);
}
| ExprList COLUMN expr {
$$ = $1;
$$.Add($3, @3);
$$.source_context = @$;
}
;
AddOperator // Îïåðàöèÿ ñëîæåíèÿ
: MINUS {
$$ = Operators.Minus;
}
| PLUS {
$$ = Operators.Plus;
}
| OR {
$$ = Operators.LogicalOR;
}
;
MultOperator // Îïåðàöèÿ óìíîæåíèÿ
: MULT {
$$ = Operators.Multiplication;
}
| DIVIDE {
$$ = Operators.Division;
}
| DIV {
$$ = Operators.IntegerDivision;
}
| MOD {
$$ = Operators.ModulusRemainder;
}
| AND {
$$ = Operators.LogicalAND;
}
;
Statement // Îïåðàòîð TODO
: Assignment
| IfStatement
| WhileStatement
| RepeatStatement
| ForStatement
| CaseStatement
| WriteStatement
| ProcCallStatement
;
StatementSequence // Ïîñëåäîâàòåëüíîñòü (áëîê) îïåðàòîðîâ
: Statement {
$$ = new statement_list($1,@$);
}
| StatementSequence SEMICOLUMN Statement {
$1.Add($3,@$);
$$ = $1;
}
;
Assignment // Ïðèñâàèâàíèå
: Designator ASSIGN expr {
$$ = new assign($1, $3, Operators.Assignment, @$);
}
;
IfStatement // Óñëîâíûé îïåðàòîð
: IF expr THEN StatementSequence ElseStatements END {
$$ = new if_node($2, $4, $5, @$);
}
| IF expr THEN StatementSequence ElseIfStatements END{
$$ = new if_node($2, $4, $5, @$);
}
;
ElseStatements // Else-÷àñòü óñëîâíîãî îïåðàòîðà
: ELSE StatementSequence {
$$ = $2;
$$.source_context = @$;
}
| {
$$ = null;
}
;
ElseIfStatements // ElseIf-÷àñòü óñëîâíîãî îïåðàòîðà
: ELSEIF expr THEN StatementSequence ElseStatements {
$$ = new if_node($2, $4, $5, @$);
}
| ELSEIF expr THEN StatementSequence ElseIfStatements{
$$ = new if_node($2, $4, $5, @$);
}
;
WhileStatement // Öèêë ñ ïðåäóñëîâèåì
: WHILE expr DO StatementSequence END {
$$ = new while_node($2, $4, WhileCycleType.While, @$);
}
;
RepeatStatement // Öèêë ñ ïîñòóñëîâèåì
: REPEAT StatementSequence UNTIL expr {
$$ = new repeat_node($2, $4, @$);
}
;
ForStatement // Öèêë
: FOR ident ASSIGN expr TO expr ForStep DO StatementSequence END {
expression step;
if ($7 != null) step = $7;
else step = new int32_const(1, @7);
// Áóäåì ìîäåëèðîâàòü öèêë ÷åðåç while
statement_list forStmnt = GetForThroughWhile($2, $4, $6, $9, step, @3, @$);
$$ = forStmnt;
$$.source_context = @$;
}
;
ForStep // Øàã öèêëà
: BY ConstExpr {
int32_const step32 = $2 as int32_const;
if (step32 != null) { // øàã ÿâëÿåòñÿ ïðîñòî öåëûì ÷èñëîì (áåç çíàêà)
if (step32.val == 0) PT.AddError("Øàã öèêëà íå ìîæåò áûòü íóëåâûì", @1);
else $$ = new int32_const(step32.val, @$);
}
else { // â çíà÷åíèè øàãà ëèáî ïðèñóòñòâóåò çíàê, ëèáî ýòî âîîáùå íå öåëîå
un_expr stepMinus = $2 as un_expr;
int32_const stepMinusTerm = stepMinus.subnode as int32_const;
bool signMinus = (stepMinusTerm != null) && (stepMinus.operation_type == Operators.Minus);
if (signMinus)
if (stepMinusTerm.val == 0)
PT.AddError("Øàã öèêëà íå ìîæåò áûòü íóëåâûì", @1);
else
$$ = new un_expr(stepMinusTerm, Operators.Minus, @2);
else
PT.AddError("Øàã öèêëà äîëæåí áûòü öåëûì ÷èñëîì", @1);
}
}
| {
$$ = null;
}
;
CaseStatement // Îïåðàòîð âûáîðà
: CASE expr OF CaseVariantList ElseBranch END {
$$ = new case_node($2, $4, $5, @$);
}
;
CaseVariantList // Ñïèñîê âàðèàíòîâ îïåðàòîðà CASE
: CaseVariant {
$$ = new case_variants();
$$.Add($1);
$$.source_context = @$;
}
| CaseVariantList PIPE CaseVariant {
$$ = $1;
$$.Add($3);
$$.source_context = @$;
}
| {
$$ = new case_variants();
}
;
CaseVariant // Âàðèàíò îïåðàòîðà CASE
: CaseVariantLabelList COLON StatementSequence {
$$ = new case_variant($1, $3, @$);
}
;
CaseVariantLabelList // Ñïèñîê ìåòîê âàðèàíòà
: CaseVariantLabels {
$$ = new expression_list($1, @$);
}
| CaseVariantLabelList COLUMN CaseVariantLabels {
$$ = $1;
$$.Add($3, @3);
$$.source_context = @$;
}
;
CaseVariantLabels // Ìåòêè âàðèàíòà
: ConstExpr {
$$ = $1;
}
| ConstExpr DOUBLEPOINT ConstExpr {
$$ = new diapason_expr($1, $3, @$);
}
;
ElseBranch // Âåòêà ELSE îïåðàòîðà CASE
: ELSE StatementSequence {
$$ = $2;
$$.source_context = @$;
}
| {
$$ = null;
}
;
WriteStatement
: EXCLAMATION expr {
expression_list el = new expression_list($2);
method_call mc = new method_call(el);
mc.dereferencing_value = new ident("print");
$$ = mc;
}
;
factparams
: expr {
$$ = new expression_list($1,@$);
}
| factparams COLUMN expr {
$1.Add($3,@$);
$$ = $1;
}
;
ProcCallStatement
: ident LPAREN factparams RPAREN {
$$ = new method_call($1,$3,@$);
}
;
EmptyStatement // Ïóñòîé îïåðàòîð
: {
$$ = new empty_statement();
}
;
IDList // Ñïèñîê èäåíòèôèêàòîðîâ
: identDef {
$$=new ident_list($1,@$);
}
| IDList COLUMN identDef {
$1.Add($3,@$);
$$ = $1;
}
;
VarDecl // Îïèñàíèå ïåðåìåííûõ îäíîãî òèïà
: IDList COLON TypeDef SEMICOLUMN {
$$ = new var_def_statement($1, $3, null, definition_attribute.None, false, @$);
}
;
VarDeclarations // Ñïèñîê îïèñàíèé ïåðåìåííûõ
: VarDecl {
$$ = new variable_definitions($1,@$);
}
| VarDeclarations VarDecl {
$1.Add($2,@$);
$$ = $1;
}
;
ConstDecl // Îïèñàíèå îäíîé êîíñòàíòû
: identDef EQ ConstExpr SEMICOLUMN {
$$ = new simple_const_definition($1,$3,@$);
}
;
ConstExpr // Êîíñòàíòíîå âûðàæåíèå
: expr
;
ConstDeclarations // Ñïèñîê îïèñàíèé êîíñòàíò
: ConstDecl {
$$ = new consts_definitions_list($1,@$);
}
| ConstDeclarations ConstDecl {
$1.Add($2,@$);
$$ = $1;
}
;
ConstDeclarationsSect // Áëîê îïèñàíèÿ êîíñòàíò
: CONST ConstDeclarations {
$$ = $2;
$$.source_context = @$;
}
;
VarDeclarationsSect // Áëîê îïèñàíèÿ ïåðåìåííûõ
: VAR VarDeclarations {
$$ = $2;
$$.source_context = @$;
}
;
TypeDeclarationsSect // Áëîê îïðåäåëåíèÿ òèïîâ òèïîâ
: TYPE TypeDeclarations {
$$ = $2;
$$.source_context = @$;
}
;
TypeDeclarations // Ñïèñîê îïðåäåëåíèé òèïîâ
: TypeDecl {
$$ = new type_declarations();
$$.Add($1);
$$.source_context = @$;
}
| TypeDeclarations TypeDecl {
$$ = $1;
$$.Add($2);
$$.source_context = @$;
}
;
TypeDecl // Îïðåäåëåíèå òèïà
: identDef EQ TypeDef SEMICOLUMN {
$$ = new type_declaration($1, $3, @$);
}
;
TypeDef // Òèï TODO
: complexTypeIdent {
$$ = $1;
}
| ArrayType {
$$ = $1;
$$.source_context = @$;
}
| RecordType {
$$ = $1;
$$.source_context = @$;
}
| PointerType {
$$ = $1;
$$.source_context = @$;
}
;
ArrayType // Òèï ìàññèâ TODO
: ARRAY OF TypeDef {
// îòêðûòûé ìàññèâ
diapason dp = new diapason(new int32_const(0), new int32_const(0));
indexers_types inxr = new indexers_types();
inxr.Add(dp);
$$ = new array_type(inxr, $3, @$);
}
| ARRAY LengthList OF TypeDef {
// Áóäåì èñêàòü array n of char, ÷òîáû çàìåíèòü íà ñòðîêó
named_type_reference ntr = $4 as named_type_reference;
bool complexArr = (ntr != null) && (ntr.names.Count == 1) &&
(ntr.names[0].name == "char");
if (complexArr)
$$ = GetArrWithStrInsteadCharArr($2, @2, @$);
else
$$ = new array_type($2, $4, @$);
}
;
RecordType // Çàïèñü TODO
: RECORD END COLUMN {
}
;
LengthList // Ñïèñîê ðàçìåðîâ ìàññèâà
: Length {
$$ = new indexers_types();
$$.source_context = @$;
$$.Add($1);
}
| LengthList COLUMN Length {
$$ = $1;
$$.source_context = @$;
$$.Add($3);
}
;
Length // Äëèíà ìàññèâà
: ConstExpr {
//  îáåðîíå â ìàññèâå óêàçûâàåòñÿ öåëî÷èñëåííàÿ äëèíà
// Ïîýòîìó íàäî ïðîâåðèòü, ÷òî âûðàæåíèå îòíîñèòñÿ ê öåëîìó òèïó
object[] types = {$1};
bool isLength = typeof(int32_const) == System.Type.GetTypeArray(types)[0];
if (isLength)
$$ = GetDiapasonByArrLength($1, @$);
else
PT.AddError("Äëèíà äîëæíà áûòü öåëûì ÷èñëîì", @1);
}
;
PointerType // Òèï óêàçàòåëü
: POINTER TO TypeDef {
$$ = new ref_type($3, @$);
}
;
complexTypeIdent // Ñîñòàâíîé èäåíòèôèêàòîð òèïà (id1.id2.id3)
: ident {
$$ = new named_type_reference(PT.InternalTypeName($1.name), @$);
}
| complexTypeIdent COMMA ident {
$$ = $1;
$$.Add(PT.InternalTypeName($3.name));
$$.source_context = @$;
}
;
DeclarationsSect // Áëîê îïèñàíèé TODO
: VarDeclarationsSect {
$$ = $1;
}
| ConstDeclarationsSect {
$$ = $1;
}
| TypeDeclarationsSect {
$$ = $1;
}
| ProcedureDeclarationSect {
$$ = $1;
}
;
Declarations // Ñïèñîê áëîêîâ îïèñàíèé
: {
$$ = new declarations();
}
| Declarations DeclarationsSect {
if ($2 != null)
$1.Add($2);
$$ = $1;
$$.source_context = @$; // Íåîáõîäèìî ïîêàçàòü ìåñòî â ïðîãðàììå, ò.ê. íåÿâíî ýòî íå ñäåëàíî
// (íàïðèìåð, â êîíñòðóêòîðå)
}
;
ProcedureDeclarationSect
: PROCEDURE ident maybeformalparams maybereturn SEMICOLUMN mainblock ident SEMICOLUMN {
}
;
maybeformalparams
: {
//$$ = null;
}
| LPAREN FPList RPAREN {
//$$ = $2;
}
;
maybereturn // TODO
: {
}
| COLUMN TypeDef {
}
;
FPList
: FPSect {
}
| FPList SEMICOLUMN FPSect {
}
;
FPSect
: maybevar IDList COLON TypeDef {
}
;
maybevar
: {
$$ = false;
}
| VAR {
$$ = true;
}
;
%%
/* Âîçâðàùàåò ïîñëåäîâàòåëüíîñòü îïåðàòîðîâ, ñîîòâåòñâóþùóþ
öèêëó for, ìîäåëèðóåìîìó ÷åðåç while */
public static statement_list GetForThroughWhile(ident id, expression expr, expression endExpr, statement_list stmnts,
expression step, SourceContext assignSC, SourceContext wholeSC){
// Áóäåì ìîäåëèðîâàòü öèêë ÷åðåç while
statement_list forStmnt = new statement_list();
ident endFor = new ident("_oberon_for_end_");
forStmnt.Add(new var_statement(new var_def_statement(
new ident_list("_oberon_for_end_"),
new named_type_reference("integer", null),
endExpr,
definition_attribute.None,
false))
);
forStmnt.Add( new assign(id, expr, Operators.Assignment, assignSC) );
statement_list posStatementList = new statement_list(); // ïðè ïîëîæèòåëüíîì øàãå
posStatementList.Add(stmnts);
posStatementList.Add( new assign(id, step, Operators.AssignmentAddition) );
while_node posWhile = new while_node(
new bin_expr(id, endFor, Operators.LessEqual),
posStatementList,
WhileCycleType.While);
statement_list negStatementList = new statement_list(); // ïðè îòðèöàòåëüíîì øàãå
negStatementList.Add(stmnts);
negStatementList.Add( new assign(id, step, Operators.AssignmentAddition) );
while_node negWhile = new while_node(
new bin_expr(id, endFor, Operators.GreaterEqual),
negStatementList,
WhileCycleType.While);
forStmnt.Add( new if_node(
new bin_expr(step, new int32_const(0), Operators.Greater),
posWhile,
negWhile,
wholeSC));
return forStmnt;
}
/* Âîçâðàùàåò ìíîãîìåðíûé ìàññèâ, â êîòîðîì ïðè íåîáõîäèìîñòè
ìàññèâ ñèìâîëîâ çàìåíåí íà ñòðîêó */
public static type_definition GetArrWithStrInsteadCharArr(indexers_types lenList,
SourceContext lenListSC, SourceContext wholeSC){
List<type_definition> indxrs = lenList.indexers;
diapason dp = indxrs[indxrs.Count - 1] as diapason;
int32_const len = new int32_const();
len.val = (dp.right as int32_const).val + 1;
type_definition result = new string_num_definition(len, new ident("string", lenListSC), wholeSC);
if (indxrs.Count > 1) { // íàäî äåëàòü ìàññèâ ìàññèâîâ ... ñòðîê
indxrs.RemoveAt(indxrs.Count - 1);
result = new array_type(lenList, result, wholeSC);
}
return result;
}
/* Âîçâðàùàåò äèàïàçîí 0..Length-1, ïîëó÷åííûé ïî îáåðîíîâñêîé äëèíå
ìàññèâà, è íåîáõîäèìûé äëÿ ïàñêàëåâñêîãî ñèíòàêñè÷åñêîãî óçëà */
public static diapason GetDiapasonByArrLength(expression lenExpr, SourceContext lenSC){
int32_const zero = new int32_const();
zero.val = 0;
int32_const max = (int32_const)lenExpr;
max.val = max.val - 1;
return new diapason(zero, max, lenSC);
}
// ==========================================================================

View file

@ -1,892 +0,0 @@
%{
// Ýòè îáúÿâëåíèÿ äîáàâëÿþòñÿ â êëàññ GPPGParser, ïðåäñòàâëÿþùèé ñîáîé ïàðñåð, ãåíåðèðóåìûé ñèñòåìîé gppg
public syntax_tree_node root; // Êîðíåâîé óçåë ñèíòàêñè÷åñêîãî äåðåâà
public GPPGParser(AbstractScanner<ValueType, LexLocation> scanner) : base(scanner) { }
%}
%output=oberon00yacc.cs
%parsertype GPPGParser
%union
{
public bool bVal;
public string sVal;
public int iVal;
public long lVal; // Äëèííîå öåëîå
public char cVal;
public double rVal;
public pascal_set_constant sc; // Êîíñòàíòà - ìíîæåñòâî
public named_type_reference ntr; // Èìåíîâàííîå îïðåäåëåíèå òèïà
public type_definition tdef; // Ñàì òèï
public diapason dpsn; // Òèï äèàïàçîí
public array_type arrt; // Òèï ìàññèâ
public class_definition cldef; // Îïðåäåëåíèå çàïèñè
public indexers_types indts; // Òèï òèïû èíäåêñîâ ìàññèâà
public ref_type rft; // Òèï óêàçàòåëü
public ident_list il; // Ñïèñîê èäåíòèôèêàòîðîâ
public ident id; // Èäåíòèôèêàòîð
public oberon_ident_with_export_marker obrid; // Îáåðîíîâñêèé óòî÷íåííûé èäåíòèôèêàòîð
public oberon_export_marker obrem; // Îáåðîíîâñêàÿ ýêñïîðòíàÿ ìåòêà
public var_def_statement vds; // Îïèñàíèå ïåðåìåííûõ
public variable_definitions vdss; // Ñåêöèÿ îïèñàíèÿ ïåðåìåííûõ
public type_declarations td; // Ñåêöèÿ îïðåäåëåíèÿ òèïîâ
public type_declaration tdec; // Îïèñàíèå òèïà
public expression ex; // Âûðàæåíèå
public expression_list el; // Ñïèñîê âûðàæåíèé
public Operators ops; // Îïåðàòîðû (îïåðàöèè)
public block bl; // Ïðîãðàììíûé áëîê
public statement st; // Îïåðàòîð ïðîãðàììíûé
public statement_list sl; // Ñïèñîê îïåðàòîðîâ
public case_variants cvars; // Ñïèñîê âàðèàíòîâ îïåðàòîðà CASE
public case_variant cvar; // Âàðèàíò îïåðàòîðà CASE
public declaration decsec; // Îïèñàíèå
public declarations decl; // Ñïèñîê îïèñàíèé
public simple_const_definition scd; // Îïðåäåëåíèå êîíñòàíòû
public consts_definitions_list cdl; // Ñïèñîê îïèñàíèé êîíñòàíò
public procedure_definition pd; // Îïèñàíèå ïðîöåäóðû
public dot_node dn; // Óçåë â òî÷å÷íîé íîòàöèè
public addressed_value adrv; // Àäðåñîâàííîå çíà÷åíèå
}
%using PascalABCCompiler.SyntaxTree
%using PascalABCCompiler.Errors
%using PascalABCCompiler.Oberon00Parser
%namespace GPPGParserScanner
%start module // Ñòàðòîâûé ñèìâîë - ïðîãðàììíûé ìîäóëü
%token <sVal> ID STRING_CONST
%token <iVal> INTNUM
%token <rVal> REALNUM
%token <lVal> LONGINTNUM
%token <bVal> TRUE FALSE
%token <cVal> CHAR_CONST
%token <op> PLUS MINUS MULT DIVIDE AND OR LT GT LE GE EQ NE DIV MOD
%token NOT
%token ASSIGN SEMICOLUMN LPAREN RPAREN COLUMN COMMA COLON EXCLAMATION
%token LBRACE RBRACE DOUBLEPOINT LBRACKET RBRACKET PIPE
%token TRUE FALSE
%token IF THEN ELSE ELSEIF BEGIN END WHILE DO MODULE CONST VAR TYPE
%token INVISIBLE
%token PROCEDURE ARRAY OF RECORD REPEAT UNTIL FOR TO BY CASE POINTER
%token ODD
%type <id> ident specifiedIdent identDef
%type <obrid> identDef
%type <obrem> ExportLabel
%type <il> IDList
%type <ntr> complexTypeIdent
%type <sc> SetConstant SetElemList
%type <ex> expr ConstExpr SetElem SimpleExpr ForStep CaseVariantLabels
%type <ex> term signedTerm factor AddList FactorList
%type <st> Assignment IfStatement ElseIfStatements ElseStatements WhileStatement WriteStatement
%type <st> RepeatStatement Statement ForStatement CaseStatement ElseBranch
%type <st> EmptyStatement ProcCallStatement
%type <sl> StatementSequence
%type <cvars> CaseVariantList
%type <cvar> CaseVariant
%type <decl> Declarations
%type <decsec> DeclarationsSect
%type <vds> VarDecl
%type <vdss> VarDeclarations VarDeclarationsSect
%type <scd> ConstDecl
%type <cdl> ConstDeclarations ConstDeclarationsSect
%type <td> TypeDeclarationsSect TypeDeclarations
%type <tdec> TypeDecl
%type <tdef> TypeDef ArrayType
%type <rft> PointerType
%type <cldef> RecordType
%type <pd> ProcedureDeclarationSect
%type <bl> mainblock
%type <el> factparams ExprList CaseVariantLabelList
%type <dpsn> Length
%type <indts> LengthList
%type <ops> AddOperator MultOperator Relation
%type <adrv> specifiedIdent ComplexDesignator Designator
%type <bVal> maybevar
%left LT GT LE GE EQ NE
%left PLUS MINUS OR
%left MULT DIVIDE AND
%left NOT
%left UMINUS UPLUS
%%
module // Ïðîãðàììíûé ìîäóëü
: MODULE ident SEMICOLUMN mainblock ident COMMA
{
if ($2.name != $5.name)
PT.AddError("Èìÿ " + $5.name + " äîëæíî ñîâïàäàòü ñ èìåíåì ìîäóëÿ " + $2.name, @5);
// Ïîäêëþ÷åíèå ñòàíäàðòíîãî ìîäóëÿ Oberon00System, íàïèñàííîãî íà PascalABC.NET
var ul = new uses_list("Oberon00System");
// Ôîðìèðîâàíèå ìîäóëÿ îñíîâíîé ïðîãðàììû (èñïîëüçóåòñÿ ôàáðè÷íûé ìåòîä âìåñòî êîíñòðóêòîðà)
root = program_module.create($2, ul, $4, @$);
}
| INVISIBLE expr { // Äëÿ Intellisense
root = $2;
}
;
ident // Èäåíòèôèêàòîð
: ID {
$$ = new ident($1,@$);
}
;
specifiedIdent // Óòî÷íåííûé èäåíòèôèêàòîð
: ident COMMA ident {
$$ = new dot_node($1, $3, @$);
}
| ident {
$$ = $1;
}
;
identDef // Îïðåäåëåííûé èäåíòèôèêàòîð (âîçìîæíà ýêñïîðòíàÿ ìåòêà) TODO
: ident ExportLabel {
$$ = new oberon_ident_with_export_marker($1.name, $2, @$);
}
;
ExportLabel // Ýêñïîðòíàÿ ìåòêà TODO
: MULT {
$$ = oberon_export_marker.export;
}
| MINUS {
$$ = oberon_export_marker.export_readonly;
}
| {
//$$ = oberon_export_marker.nonexport;
$$ = oberon_export_marker.export;
}
;
mainblock // Ïðîãðàììíûé áëîê
: Declarations BEGIN StatementSequence END
{
$$ = new block($1, $3, @$);
}
;
SetConstant // Âûðàæåíèå-êîíñòàíòà ìíîæåñòâî TODO
: LBRACE SetElemList RBRACE {
$$ = $2;
$$.source_context = @$;
}
;
SetElemList // Ñïèñîê ýëåìåíòîâ ìíîæåñòâà TODO
: SetElem {
$$ = new pascal_set_constant();
$$.Add($1);
$$.source_context = @$;
}
| SetElemList COLUMN SetElem {
$$ = $1;
$$.Add($3);
$$.source_context = @$;
}
| {
$$ = new pascal_set_constant();
}
;
SetElem // Ýëåìåíò ìíîæåñòâà TODO
: expr
| expr DOUBLEPOINT expr {
$$ = new diapason_expr($1, $3, @$);
}
;
expr // Âûðàæåíèå
: SimpleExpr {
$$ = $1;
}
| SimpleExpr Relation SimpleExpr {
$$ = new bin_expr($1, $3, $2, @$);
}
;
Relation // Îòíîøåíèå
: EQ {
$$ = Operators.Equal;
}
| NE {
$$ = Operators.NotEqual;
}
| LT {
$$ = Operators.Less;
}
| LE {
$$ = Operators.LessEqual;
}
| GT {
$$ = Operators.Greater;
}
| GE {
$$ = Operators.GreaterEqual;
}
;
SimpleExpr // Ïðîñòîå âûðàæåíèå
: signedTerm {
$$ = $1;
$$.source_context = @$;
}
| signedTerm AddOperator AddList {
$$ = new bin_expr($1, $3, $2, @$);
}
;
signedTerm // Ñëàãàåìîå ñî çíàêîì
: term
| MINUS term %prec UMINUS {
$$ = new un_expr($2, Operators.Minus, @$);
}
| PLUS term %prec UPLUS {
$$ = new un_expr($2, Operators.Plus, @$);
}
;
AddList // Ñïèñîê ñî ñëàãàåìûìè
: term
| AddList AddOperator term {
$$ = new bin_expr($1, $3, $2, @$);
}
;
term // Ñëàãàåìîå
: factor
| factor MultOperator FactorList {
$$ = new bin_expr($1, $3, $2, @$);
}
;
FactorList // Ñïèñîê ñî ìíîæèòåëÿìè
: factor
| FactorList MultOperator factor {
$$ = new bin_expr($1, $3, $2, @$);
}
;
factor // Ìíîæèòåëü
: Designator {
$$ = $1;
}
| INTNUM {
$$ = new int32_const($1,@$);
}
| LONGINTNUM{
$$ = new int64_const($1, @$);
}
| REALNUM {
$$ = new double_const($1, @$);
}
| TRUE {
$$ = new bool_const(true,@$);
}
| FALSE {
$$ = new bool_const(false,@$);
}
| CHAR_CONST {
$$ = new char_const($1, @$);
}
| STRING_CONST {
$$ = new string_const($1, @$);
}
| LPAREN expr RPAREN {
$$ = $2;
}
| NOT factor {
$$ = new un_expr($2,Operators.LogicalNOT,@$);
}
| SetConstant
;
Designator // Îáîçíà÷åíèå (îáðàùåíèå ó ýëåìåòó ìàññèâà, ...) TODO
: specifiedIdent {
$$ = $1;
}
| ComplexDesignator {
$$ = $1;
}
;
ComplexDesignator // Ñîñòàâíîå îáîçíà÷åíèå TODO
: specifiedIdent COMMA ident {
$$ = new dot_node($1, $3, @$);
}
| specifiedIdent LBRACKET ExprList RBRACKET {
indexer indxr = new indexer();
indxr.dereferencing_value = $1;
indxr.indexes = $3;
$$ = indxr;
$$.source_context = @$;
}
| ComplexDesignator COMMA ident {
$$ = new dot_node($1, $3, @$);
}
| ComplexDesignator LBRACKET ExprList RBRACKET {
indexer indxr = new indexer();
indxr.dereferencing_value = $1;
indxr.indexes = $3;
$$ = indxr;
$$.source_context = @$;
}
;
ExprList // Ñïèñîê âûðàæåíèé
: expr {
$$ = new expression_list($1, @$);
}
| ExprList COLUMN expr {
$$ = $1;
$$.Add($3, @3);
$$.source_context = @$;
}
;
AddOperator // Îïåðàöèÿ ñëîæåíèÿ
: MINUS {
$$ = Operators.Minus;
}
| PLUS {
$$ = Operators.Plus;
}
| OR {
$$ = Operators.LogicalOR;
}
;
MultOperator // Îïåðàöèÿ óìíîæåíèÿ
: MULT {
$$ = Operators.Multiplication;
}
| DIVIDE {
$$ = Operators.Division;
}
| DIV {
$$ = Operators.IntegerDivision;
}
| MOD {
$$ = Operators.ModulusRemainder;
}
| AND {
$$ = Operators.LogicalAND;
}
;
Statement // Îïåðàòîð TODO
: Assignment
| IfStatement
| WhileStatement
| RepeatStatement
| ForStatement
| CaseStatement
| WriteStatement
| ProcCallStatement
| EmptyStatement
;
StatementSequence // Ïîñëåäîâàòåëüíîñòü (áëîê) îïåðàòîðîâ
: Statement {
$$ = new statement_list($1,@$);
}
| StatementSequence SEMICOLUMN Statement {
$1.Add($3,@$);
$$ = $1;
}
;
Assignment // Ïðèñâàèâàíèå
: Designator ASSIGN expr {
$$ = new assign($1, $3, Operators.Assignment, @$);
}
;
IfStatement // Óñëîâíûé îïåðàòîð
: IF expr THEN StatementSequence ElseStatements END {
$$ = new if_node($2, $4, $5, @$);
}
| IF expr THEN StatementSequence ElseIfStatements END {
$$ = new if_node($2, $4, $5, @$);
}
;
ElseStatements // Else-÷àñòü óñëîâíîãî îïåðàòîðà
: ELSE StatementSequence {
$$ = $2;
$$.source_context = @$;
}
| {
$$ = null;
}
;
ElseIfStatements // ElseIf-÷àñòü óñëîâíîãî îïåðàòîðà
: ELSEIF expr THEN StatementSequence ElseStatements {
$$ = new if_node($2, $4, $5, @$);
}
| ELSEIF expr THEN StatementSequence ElseIfStatements{
$$ = new if_node($2, $4, $5, @$);
}
;
WhileStatement // Öèêë ñ ïðåäóñëîâèåì
: WHILE expr DO StatementSequence END {
$$ = new while_node($2, $4, WhileCycleType.While, @$);
}
;
RepeatStatement // Öèêë ñ ïîñòóñëîâèåì
: REPEAT StatementSequence UNTIL expr {
$$ = new repeat_node($2, $4, @$);
}
;
ForStatement // Öèêë
: FOR ident ASSIGN expr TO expr ForStep DO StatementSequence END {
expression step;
if ($7 != null) step = $7;
else step = new int32_const(1, @7);
// Áóäåì ìîäåëèðîâàòü öèêë ÷åðåç while
statement_list forStmnt = GetForThroughWhile($2, $4, $6, $9, step, @3, @$);
$$ = forStmnt;
$$.source_context = @$;
}
;
ForStep // Øàã öèêëà
: BY ConstExpr {
int32_const step32 = $2 as int32_const;
if (step32 != null) { // øàã ÿâëÿåòñÿ ïðîñòî öåëûì ÷èñëîì (áåç çíàêà)
if (step32.val == 0) PT.AddError("Øàã öèêëà íå ìîæåò áûòü íóëåâûì", @1);
else $$ = new int32_const(step32.val, @$);
}
else { // â çíà÷åíèè øàãà ëèáî ïðèñóòñòâóåò çíàê, ëèáî ýòî âîîáùå íå öåëîå
un_expr stepMinus = $2 as un_expr;
int32_const stepMinusTerm = stepMinus.subnode as int32_const;
bool signMinus = (stepMinusTerm != null) && (stepMinus.operation_type == Operators.Minus);
if (signMinus)
if (stepMinusTerm.val == 0)
PT.AddError("Øàã öèêëà íå ìîæåò áûòü íóëåâûì", @1);
else
$$ = new un_expr(stepMinusTerm, Operators.Minus, @2);
else
PT.AddError("Øàã öèêëà äîëæåí áûòü öåëûì ÷èñëîì", @1);
}
}
| {
$$ = null;
}
;
CaseStatement // Îïåðàòîð âûáîðà
: CASE expr OF CaseVariantList ElseBranch END {
$$ = new case_node($2, $4, $5, @$);
}
;
CaseVariantList // Ñïèñîê âàðèàíòîâ îïåðàòîðà CASE
: CaseVariant {
$$ = new case_variants();
$$.Add($1);
$$.source_context = @$;
}
| CaseVariantList PIPE CaseVariant {
$$ = $1;
$$.Add($3);
$$.source_context = @$;
}
| {
$$ = new case_variants();
}
;
CaseVariant // Âàðèàíò îïåðàòîðà CASE
: CaseVariantLabelList COLON StatementSequence {
$$ = new case_variant($1, $3, @$);
}
;
CaseVariantLabelList // Ñïèñîê ìåòîê âàðèàíòà
: CaseVariantLabels {
$$ = new expression_list($1, @$);
}
| CaseVariantLabelList COLUMN CaseVariantLabels {
$$ = $1;
$$.Add($3, @3);
$$.source_context = @$;
}
;
CaseVariantLabels // Ìåòêè âàðèàíòà
: ConstExpr {
$$ = $1;
}
| ConstExpr DOUBLEPOINT ConstExpr {
$$ = new diapason_expr($1, $3, @$);
}
;
ElseBranch // Âåòêà ELSE îïåðàòîðà CASE
: ELSE StatementSequence {
$$ = $2;
$$.source_context = @$;
}
| {
$$ = null;
}
;
WriteStatement
: EXCLAMATION expr {
expression_list el = new expression_list($2,@$);
method_call mc = new method_call(el);
mc.dereferencing_value = new ident("print");
$$ = mc;
}
;
factparams
: expr {
$$ = new expression_list($1,@$);
}
| factparams COLUMN expr {
$1.Add($3,@$);
$$ = $1;
}
;
ProcCallStatement
: ident LPAREN factparams RPAREN {
$$ = new method_call($1,$3,@$);
}
;
EmptyStatement // Ïóñòîé îïåðàòîð
: {
$$ = new empty_statement();
}
;
IDList // Ñïèñîê èäåíòèôèêàòîðîâ
: identDef {
$$=new ident_list($1,@$);
}
| IDList COLUMN identDef {
$1.Add($3,@$);
$$ = $1;
}
;
VarDecl // Îïèñàíèå ïåðåìåííûõ îäíîãî òèïà
: IDList COLON TypeDef SEMICOLUMN {
$$ = new var_def_statement($1, $3, null, definition_attribute.None, false, @$);
}
;
VarDeclarations // Ñïèñîê îïèñàíèé ïåðåìåííûõ
: VarDecl {
$$ = new variable_definitions($1,@$);
}
| VarDeclarations VarDecl {
$1.Add($2,@$);
$$ = $1;
}
;
ConstDecl // Îïèñàíèå îäíîé êîíñòàíòû
: identDef EQ ConstExpr SEMICOLUMN {
$$ = new simple_const_definition($1,$3,@$);
}
;
ConstExpr // Êîíñòàíòíîå âûðàæåíèå
: expr
;
ConstDeclarations // Ñïèñîê îïèñàíèé êîíñòàíò
: ConstDecl {
$$ = new consts_definitions_list($1,@$);
}
| ConstDeclarations ConstDecl {
$1.Add($2,@$);
$$ = $1;
}
;
ConstDeclarationsSect // Áëîê îïèñàíèÿ êîíñòàíò
: CONST ConstDeclarations {
$$ = $2;
$$.source_context = @$;
}
;
VarDeclarationsSect // Áëîê îïèñàíèÿ ïåðåìåííûõ
: VAR VarDeclarations {
$$ = $2;
$$.source_context = @$;
}
;
TypeDeclarationsSect // Áëîê îïðåäåëåíèÿ òèïîâ òèïîâ
: TYPE TypeDeclarations {
$$ = $2;
$$.source_context = @$;
}
;
TypeDeclarations // Ñïèñîê îïðåäåëåíèé òèïîâ
: TypeDecl {
$$ = new type_declarations();
$$.Add($1);
$$.source_context = @$;
}
| TypeDeclarations TypeDecl {
$$ = $1;
$$.Add($2);
$$.source_context = @$;
}
;
TypeDecl // Îïðåäåëåíèå òèïà
: identDef EQ TypeDef SEMICOLUMN {
$$ = new type_declaration($1, $3, @$);
}
;
TypeDef // Òèï TODO
: complexTypeIdent {
$$ = $1;
}
| ArrayType {
$$ = $1;
$$.source_context = @$;
}
| RecordType {
$$ = $1;
$$.source_context = @$;
}
| PointerType {
$$ = $1;
$$.source_context = @$;
}
;
ArrayType // Òèï ìàññèâ TODO
: ARRAY OF TypeDef {
// îòêðûòûé ìàññèâ
diapason dp = new diapason(new int32_const(0), new int32_const(0));
indexers_types inxr = new indexers_types();
inxr.Add(dp);
$$ = new array_type(inxr, $3, @$);
}
| ARRAY LengthList OF TypeDef {
// Áóäåì èñêàòü array n of char, ÷òîáû çàìåíèòü íà ñòðîêó
named_type_reference ntr = $4 as named_type_reference;
bool complexArr = (ntr != null) && (ntr.names.Count == 1) &&
(ntr.names[0].name == "char");
if (complexArr)
$$ = GetArrWithStrInsteadCharArr($2, @2, @$);
else
$$ = new array_type($2, $4, @$);
}
;
RecordType // Çàïèñü TODO
: RECORD END COLUMN {
}
;
LengthList // Ñïèñîê ðàçìåðîâ ìàññèâà
: Length {
$$ = new indexers_types();
$$.source_context = @$;
$$.Add($1);
}
| LengthList COLUMN Length {
$$ = $1;
$$.source_context = @$;
$$.Add($3);
}
;
Length // Äëèíà ìàññèâà
: ConstExpr {
//  îáåðîíå â ìàññèâå óêàçûâàåòñÿ öåëî÷èñëåííàÿ äëèíà
// Ïîýòîìó íàäî ïðîâåðèòü, ÷òî âûðàæåíèå îòíîñèòñÿ ê öåëîìó òèïó
object[] types = {$1};
bool isLength = typeof(int32_const) == System.Type.GetTypeArray(types)[0];
if (isLength)
$$ = GetDiapasonByArrLength($1, @$);
else
PT.AddError("Äëèíà äîëæíà áûòü öåëûì ÷èñëîì", @1);
}
;
PointerType // Òèï óêàçàòåëü
: POINTER TO TypeDef {
$$ = new ref_type($3, @$);
}
;
complexTypeIdent // Ñîñòàâíîé èäåíòèôèêàòîð òèïà (id1.id2.id3)
: ident {
$$ = new named_type_reference(PT.InternalTypeName($1.name), @$);
}
| complexTypeIdent COMMA ident {
$$ = $1;
$$.Add(PT.InternalTypeName($3.name));
$$.source_context = @$;
}
;
DeclarationsSect // Áëîê îïèñàíèé TODO
: VarDeclarationsSect {
$$ = $1;
}
| ConstDeclarationsSect {
$$ = $1;
}
| TypeDeclarationsSect {
$$ = $1;
}
| ProcedureDeclarationSect {
$$ = $1;
}
;
Declarations // Ñïèñîê áëîêîâ îïèñàíèé
: {
$$ = new declarations();
}
| Declarations DeclarationsSect {
if ($2 != null)
$1.Add($2);
$$ = $1;
$$.source_context = @$; // Íåîáõîäèìî ïîêàçàòü ìåñòî â ïðîãðàììå, ò.ê. íåÿâíî ýòî íå ñäåëàíî
// (íàïðèìåð, â êîíñòðóêòîðå)
}
;
ProcedureDeclarationSect
: PROCEDURE ident maybeformalparams maybereturn SEMICOLUMN mainblock ident SEMICOLUMN {
}
;
maybeformalparams
: {
//$$ = null;
}
| LPAREN FPList RPAREN {
//$$ = $2;
}
;
maybereturn // TODO
: {
}
| COLUMN TypeDef {
}
;
FPList
: FPSect {
}
| FPList SEMICOLUMN FPSect {
}
;
FPSect
: maybevar IDList COLON TypeDef {
}
;
maybevar
: {
$$ = false;
}
| VAR {
$$ = true;
}
;
%%
/* Âîçâðàùàåò ïîñëåäîâàòåëüíîñòü îïåðàòîðîâ, ñîîòâåòñâóþùóþ
öèêëó for, ìîäåëèðóåìîìó ÷åðåç while */
public static statement_list GetForThroughWhile(ident id, expression expr, expression endExpr, statement_list stmnts,
expression step, SourceContext assignSC, SourceContext wholeSC){
// Áóäåì ìîäåëèðîâàòü öèêë ÷åðåç while
statement_list forStmnt = new statement_list();
ident endFor = new ident("_oberon_for_end_");
forStmnt.Add(new var_statement(new var_def_statement(
new ident_list("_oberon_for_end_"),
new named_type_reference("integer", null),
endExpr,
definition_attribute.None,
false))
);
forStmnt.Add( new assign(id, expr, Operators.Assignment, assignSC) );
statement_list posStatementList = new statement_list(); // ïðè ïîëîæèòåëüíîì øàãå
posStatementList.Add(stmnts);
posStatementList.Add( new assign(id, step, Operators.AssignmentAddition) );
while_node posWhile = new while_node(
new bin_expr(id, endFor, Operators.LessEqual),
posStatementList,
WhileCycleType.While);
statement_list negStatementList = new statement_list(); // ïðè îòðèöàòåëüíîì øàãå
negStatementList.Add(stmnts);
negStatementList.Add( new assign(id, step, Operators.AssignmentAddition) );
while_node negWhile = new while_node(
new bin_expr(id, endFor, Operators.GreaterEqual),
negStatementList,
WhileCycleType.While);
forStmnt.Add( new if_node(
new bin_expr(step, new int32_const(0), Operators.Greater),
posWhile,
negWhile,
wholeSC));
return forStmnt;
}
/* Âîçâðàùàåò ìíîãîìåðíûé ìàññèâ, â êîòîðîì ïðè íåîáõîäèìîñòè
ìàññèâ ñèìâîëîâ çàìåíåí íà ñòðîêó */
public static type_definition GetArrWithStrInsteadCharArr(indexers_types lenList,
SourceContext lenListSC, SourceContext wholeSC){
List<type_definition> indxrs = lenList.indexers;
diapason dp = indxrs[indxrs.Count - 1] as diapason;
int32_const len = new int32_const();
len.val = (dp.right as int32_const).val + 1;
type_definition result = new string_num_definition(len, new ident("string", lenListSC), wholeSC);
if (indxrs.Count > 1) { // íàäî äåëàòü ìàññèâ ìàññèâîâ ... ñòðîê
indxrs.RemoveAt(indxrs.Count - 1);
result = new array_type(lenList, result, wholeSC);
}
return result;
}
/* Âîçâðàùàåò äèàïàçîí 0..Length-1, ïîëó÷åííûé ïî îáåðîíîâñêîé äëèíå
ìàññèâà, è íåîáõîäèìûé äëÿ ïàñêàëåâñêîãî ñèíòàêñè÷åñêîãî óçëà */
public static diapason GetDiapasonByArrLength(expression lenExpr, SourceContext lenSC){
int32_const zero = new int32_const();
zero.val = 0;
int32_const max = (int32_const)lenExpr;
max.val = max.val - 1;
return new diapason(zero, max, lenSC);
}

File diff suppressed because it is too large Load diff

View file

@ -3,14 +3,4 @@
/RebuildStandartModules.exe
#TODO Вместо утого удалить устаревшие .pas тесты, оставив остальное без игнора
/Samples/*
!/Samples/_SVN/
!/Samples/ExportSamples.bat
!/Samples/GetSamples.exe
!/Samples/GetSamples.pnet

View file

@ -1,9 +0,0 @@
// Пример иллюстрирует использование значка & для снятия атрибута ключевого слова
var
&begin,&end: integer;
begin
&begin := 1;
&end := 2;
var t: System.Type := &begin.GetType; // в System.Type использовать & не надо
write(&begin,' ',&end,' ',t);
end.

View file

@ -1,18 +0,0 @@
// Присваивания += -= *= /=
var
i: integer;
r: real;
begin
i := 1;
writeln('i := 1; i = ',i);
i += 2; // Увеличение на 2
writeln('i += 2; i = ',i);
i *= 3; // Умножение на 3
writeln('i *= 3; i = ',i);
writeln;
r := 6;
writeln('r := 6; r = ',r);
r /= 2;
writeln('r /= 2; r = ',r);
end.

View file

@ -1,10 +0,0 @@
// Автоопределение типа переменной
// Описание переменной в заголовке цикла for
begin
var x := 2;
for var i:=1 to 10 do
begin
write(x,' ');
x += 2;
end;
end.

View file

@ -1,11 +0,0 @@
// Перемена местами значений двух переменных с использованием третьей
var x,y: real;
begin
write('Введите x,y: ');
readln(x,y);
var v: real := x; // вспомогательная переменная
x := y;
y := v;
writeln('Новые значения x,y: ',x,' ',y);
end.

View file

@ -1,26 +0,0 @@
// Пример иллюстрирует возможности оператора foreach
uses System.Collections.Generic;
var
a: array [1..5] of integer := (1,3,5,7,9);
s: set of integer;
l: List<integer>;
begin
write('foreach по обычному массиву: ':35);
foreach x: integer in a do
write(x,' ');
writeln;
s := [2..5,10..14];
write('foreach по множеству: ':35);
foreach x: integer in s do
write(x,' ');
writeln;
l := new List<integer>;
l.Add(7); l.Add(2); l.Add(5);
write('foreach по динамическому массиву: ':35);
foreach x: integer in l do
write(x,' ');
end.

View file

@ -1,5 +0,0 @@
// Генерация случайного числа в заданном диапазоне
begin
var i := Random(2,5);
writeln('Случайное целое в диапазоне 2..5: ',i);
end.

View file

@ -1,5 +0,0 @@
// При работе с вещественными числами невозможно получить ошибку выполнения
begin
writeln(1/0);
writeln(sqrt(-1));
end.

View file

@ -1,27 +0,0 @@
// Простейшие новые возможности языка PascalABC.NET
// Инициализация переменной при описании
var i: integer := 1;
// Автоопределение типа переменной при инициализации
var r := 2.5;
begin
// Внутриблочные описания переменных
var s: real := 1.0;
// Описание переменной в заголовке цикла (время жизни переменной - до конца тела цикла)
for j: integer := 1 to 10 do
s += j; // Операция += для чисел
var p := 1;
// Описание переменной в заголовке цикла с автоопределением типа
for var j := 1 to 10 do
p *= j; // Операция *=
var str := '';
for c: char := 'a' to 'z' do
str += c; // Операция += для строк
end.

View file

@ -1,33 +0,0 @@
/// Стандартные размерные типы данных и их размер
var
i: integer;
j: shortint;
k: smallint;
l: longint; // синоним integer
i64: int64;
b: byte;
w: word;
lw: longword;
car: cardinal; // синоним longword
ui64: uint64;
r: real;
d: double; // синоним real
sn: single;
c: char;
begin
writeln('sizeof(integer) = ':20, sizeof(integer));
writeln('sizeof(shortint) = ':20,sizeof(shortint));
writeln('sizeof(smallint) = ':20,sizeof(smallint));
writeln('sizeof(longint) = ':20, sizeof(longint));
writeln('sizeof(int64) = ':20, sizeof(int64));
writeln('sizeof(byte) = ':20, sizeof(byte));
writeln('sizeof(word) = ':20, sizeof(word));
writeln('sizeof(longword) = ':20,sizeof(longword));
writeln('sizeof(cardinal) = ':20,sizeof(cardinal));
writeln('sizeof(uint64) = ':20, sizeof(uint64));
writeln('sizeof(real) = ':20, sizeof(real));
writeln('sizeof(double) = ':20, sizeof(double));
writeln('sizeof(single) = ':20, sizeof(single));
writeln('sizeof(char) = ':20, sizeof(char));
end.

View file

@ -1,12 +0,0 @@
/// Вывод различных типов процедурой write
begin
// Вывод, целого, строки, вещественного
Writeln(1,' ',2.5);
// Вывод множества
Writeln([1..10]);
// Вывод логического
Writeln(True);
var a: array [1..10] of integer;
// Вывод массива (выводится его тип)
Writeln(a);
end.

View file

@ -1,11 +0,0 @@
/// Использование процедуры WritelnFormat
begin
// Вывод в обратном порядке
WritelnFormat('{2},{1},{0}',1,2,3);
// Вывод фигурных скобочек
WritelnFormat('{{}}{0}','Вывод фигурных скобочек в форматной строке');
// Задание ширины поля вывода
WritelnFormat('{0,10:f}',3.1415);
// Задание количества знаков после запятой для вещественного числа
WritelnFormat('{0:f3}',3.1415);
end.

View file

@ -1,19 +0,0 @@
// Стандартные функции Ord, Chr, OrdUnicode, ChrUnicode
var
c: char;
i: integer;
begin
writeln('sizeof(char) = ',sizeof(char));
writeln;
c := 'Ж';
i := Ord(c);
writelnFormat('Код символа {0} в кодировке Windows равен {1}',c,i);
c := Chr(i);
writelnFormat('Символ с кодом {0} в кодировке Windows - это {1}',i,c);
writeln;
i := OrdUnicode(c);
writelnFormat('Код символа {0} в кодировке Unicode равен {1}',c,i);
c := ChrUnicode(i);
writelnFormat('Символ с кодом {0} в кодировке Unicode - это {1}',i,c);
end.

View file

@ -1,40 +0,0 @@
// Процедуры и методы работы с динамическим массивом
uses System;
procedure Print(a: array of integer);
begin
foreach v: integer in a do
Write(v, ' ');
Writeln;
end;
var a: array of integer;
begin
SetLength(a,10); // выделение памяти. А можно так: a := new integer[10];
// Заполнение массива
for var i:=0 to a.Length-1 do
a[i] := PABCSystem.Random(100);
// Вывод всех элементов массива
Print(a);
// Сортировка массива (знак & используется для того,
// чтобы воспользоваться ключевым словом array при обозначении
// класса Array)
&Array.Sort(a);
Print(a);
// Обращение массива
&Array.Reverse(a);
Print(a);
// Изменение размерамассиав с сохранением элементов. То же делает SetLength
&Array.Resize(a,a.Length+2);
Print(a);
// Поиск вхождения элемента в массив
var i := &Array.IndexOf(a, 50);
Writeln(i);
end.

View file

@ -1,25 +0,0 @@
// Перечислимый тип
type Months = (January,February,March,April,May,June,July,August,September,October,November,December);
var m: Months;
begin
m := February;
writeln(m);
// Использование констант перечислимого типа после имени типа удобно: после точки intellisense показывает список констант
m := Months.April;
writeln('Следующий месяц: ',m);
Inc(m);
writeln('Следующий месяц: ',m);
m := Succ(m);
writeln('Следующий месяц: ',m);
m := Pred(m);
writeln('Предыдующий месяц: ',m);
Dec(m);
writeln('Предыдующий месяц: ',m);
writeln('Его порядковый номер (нумерация - с нуля): ',Ord(m));
// Ошибки нет
writeln('Месяц перед январем - выход за границы: ',pred(Months.January));
// Ошибки нет
writeln('Месяц после декабря - выход за границы: ',succ(Months.December));
end.

View file

@ -1,15 +0,0 @@
// Инициализаторы полей записи
type
Frac = record
num: integer := 0;
denom := 1; // автоопределеине типа - denom: integer
end;
var
f: Frac;
f1: Frac := (num: 2; denom: 3);
begin
writeln(f.num,'/',f.denom);
writeln(f1.num,'/',f1.denom);
end.

View file

@ -1,10 +0,0 @@
// Указатели на ссылочные типы запрещены. Исключение: указатели на строки и динамические массивы
type
A = class
i: integer;
end;
var p: ^record field: A; end;
begin
end.

View file

@ -1,43 +0,0 @@
// Выделение динамической памяти
// Использование указателей для создания односвязного списка
type
PNode = ^TNode;
TNode = record
data: integer;
next: PNode;
end;
function NewNode(d: integer; n: PNode): PNode;
begin
New(Result);
Result^.data := d;
Result^.next := n;
end;
var first: PNode;
begin
first := nil;
// Добавляем в начало односвязного списка
first := NewNode(3,first);
first := NewNode(7,first);
first := NewNode(5,first);
// Вывод односвязного списка
writeln('Содержимое односвязного списка: ');
var p := first;
while p<>nil do
begin
write(p^.data,' ');
p := p^.next;
end;
// Разрушение односвязного списка
p := first;
while p<>nil do
begin
var p1 := p;
p := p^.next;
Dispose(p1); // Память обязательно возвращать
end;
end.

View file

@ -1,35 +0,0 @@
// Использование ссылок вместо указателей для создания односвязного списка
// Мы рекомендуем именно этот способ
type
Node = class
data: integer;
next: Node;
constructor (d: integer; n: Node);
begin
data := d;
next := n;
end;
end;
// Переменная типа "класс" представляет собой ссылку на объект, выделяемый конструктором
var first: Node;
begin
first := nil;
// Добавляем в начало односвязного списка
first := new Node(3,first);
first := new Node(7,first);
first := new Node(5,first);
// Вывод односвязного списка. ^ отсутствуют
writeln('Содержимое односвязного списка (использование ссылок вместо указателей): ');
var p := first;
while p<>nil do
begin
write(p.data,' ');
p := p.next;
end;
// Разрушение односвязного списка
first := nil; // Сборщик мусора соберет память, на которую никто больше не указывает
end.

View file

@ -1,15 +0,0 @@
// Работа с множествами
// Базовый тип для множества может быть произвольным
var
s1: set of string := ['Иванов','Попов','Сидорова','Петров'];
s2: set of string := ['Козлов','Петров','Иванов'];
begin
writeln('Множество s1: ',s1);
writeln('Множество s2: ',s2);
writeln('Объединение множеств s1 и s2: ',s1+s2);
writeln('Пересечение множеств s1 и s2: ',s1*s2);
writeln('Разность множеств s1 и s2: ',s1-s2);
Include(s1,'Умнов');
Exclude(s1,'Иванов');
writeln('Множество s1: ',s1);
end.

View file

@ -1,16 +0,0 @@
// Преобразование целое <-> строка в новом стиле
var
s: string;
i: integer;
begin
// Преобразование целого в строку
i := 234;
s := i.ToString;
writelnFormat('Целое: {0}. После преобразования к строке: ''{1}''',i,s);
// Преобразование строки в целое
s := '567';
if integer.TryParse(s,i) then
writelnFormat('Строка: ''{0}''. После преобразования к целому: {1}',s,i);
end.

View file

@ -1,18 +0,0 @@
// Строки. Методы класса string
var
s: string := ' Pascal__NET ';
s1: string := 'NET';
begin
writeln('Исходная строка: ''',s,'''');
s := s.Trim;
writeln('После вызова s.Trim: ''',s,'''');
var p := s.IndexOf(s1); // Индексация - с нуля
writelnFormat('Позиция подстроки ''{0}'' в строке ''{1}'' равна {2}',s1,s,p);
s := s.Remove(6,2);
writeln('После удаления символов __: ',s);
s := s.Insert(6,'ABC.');
writeln('После вставки подстроки ''ABC.'': ',s);
writeln('Первая часть строки: ',s.Substring(0,9));
writeln('Последняя часть строки: ',s.Substring(10,3));
end.

View file

@ -1,17 +0,0 @@
// Строки string, string[n], shortstring
var
s: string; // память, занимаемая s, зависит от ее длины
s10: string[10]; // память под ss фиксирована
ss: shortstring := s;
f: file of string[10];
// f: file of string; - ошибка
begin
s := '12345678901234567890';
s10 := s; // обрезание
writeln(s10);
s += s; s += s;
s += s; s += s;
writeln(s);
writeln('Длина строки = ',s.Length);
end.

View file

@ -1,23 +0,0 @@
// Иллюстрация структурной эквивалентности для некоторых типов. В Delphi - именная эквивалентность
var
a: array of integer;
a1: array of integer;
s: set of real;
s1: set of real;
p: procedure (i: integer);
p1: procedure (i: integer);
r: ^integer;
r1: ^integer;
procedure proc(aa: array of integer; ss: set of real; pp: procedure (i: integer); rr: ^integer);
begin
end;
begin
a := a1;
s := s1;
p := p1;
r := r1; // В Delphi ни одно из этих присваиваний не сработает
proc(a,s,p,r); // Этот вызов - тоже
end.

View file

@ -1,19 +0,0 @@
// Бестиповые файлы
var
f: file;
i: integer;
r: real;
s: string;
begin
assign(f,'a.dat');
rewrite(f);
// Записываем в файл данные любых типов
write(f,1,2.5,'Hello');
close(f);
reset(f);
// Считываем эти данные из файла
read(f,i,r,s);
write(i,' ',r,' ',s);
close(f);
end.

View file

@ -1,12 +0,0 @@
// Переменное число параметров
function Sum(params arg: array of integer): integer;
begin
Result := 0;
foreach x: integer in arg do
Result += x;
end;
begin
writeln(Sum(1,2,3));
writeln(Sum(4,5,6,7));
end.

View file

@ -1,21 +0,0 @@
// Перегрузка имен подпрограмм
procedure proc(i: integer);
begin
writeln('integer');
end;
procedure proc(c: char);
begin
writeln('char');
end;
procedure proc(r: real);
begin
writeln('real');
end;
begin
proc(1);
proc(2.5);
proc('d');
end.

View file

@ -1,39 +0,0 @@
// Все возможные способы инициализации поцедурной переменной
// Процедурный тип реализован через делегаты .NET, для него доступны операции +=, -=
procedure pp;
begin
writeln('Вызов обычной процедуры');
end;
type
A = class
private
x: integer;
public
constructor Create(xx: integer);
begin
x := xx;
end;
procedure pp;
begin
writeln('Вызов метода класса, значение поля равно ',x);
end;
class procedure ppstatic;
begin
writeln('Вызов классового метода класса');
end;
end;
var p: procedure;
begin
p := pp;
var a1: A := new A(5);
p += a1.pp;
p += A.ppstatic;
p;
writeln;
p -= pp;
p;
end.

View file

@ -1,23 +0,0 @@
// Обобщенные функции
// Выведение типа T по типам параметров
procedure Swap<T>(var a,b: T);
begin
var v := a;
a := b;
b := v;
end;
begin
var a := 2;
var b := 3;
writelnFormat('До Swap a={0}, b={1}',a,b);
Swap(a,b);
writelnFormat('После Swap a={0}, b={1}',a,b);
var c := 2.5;
var d := 3.3;
writeln;
writelnFormat('До Swap c={0}, d={1}',c,d);
Swap(c,d);
writelnFormat('После Swap c={0}, d={1}',c,d);
end.

View file

@ -1,9 +0,0 @@
// Вызов статического метода add класса Class1, помещенного в пространство имен ClassLibrary1
// Класс Class1 помещен в библиотеку ClassLibrary1.dll, откомпилированную на C#
{$reference ClassLibrary1.dll}
uses ClassLibrary1;
begin
writeln(Class1.add(2,3));
end.

View file

@ -1,16 +0,0 @@
// Dll-библиотека
library MyDll;
const n = 10;
function add(a,b: integer): integer;
begin
Result := a + b;
end;
procedure PrintPascalABCNET;
begin
writeln('PascalABC.NET');
end;
end.

View file

@ -1,10 +0,0 @@
// Это - главная программа
// Именами из dll-библиотеки, написанной на PascalABC.NET, можно пользоваться,
// не подключая пространства имен
{$reference mydll.dll}
begin
PrintPascalABCNET;
writeln(n);
writeln(add(2,3));
end.

View file

@ -1,6 +0,0 @@
// Вызов функции из обычной dll
function add(a,b: integer): integer; external 'NativeDll.dll' name 'add'; // объявление внешней функции
begin // основная программа
writeln(add(2,3));
end.

View file

@ -1,13 +0,0 @@
// Îòêîìïèëèðîâàòü â Delphi
library NativeDll;
function add(a,b: integer): integer; stdcall;
begin
Result := a+b;
end;
exports
add;
begin
end.

View file

@ -1,7 +0,0 @@
uses MyUnit; // подключили модуль
var a: array of integer := (1,5,3,7,3,6,4,5,1,8,3,5,6);
begin
writeln('Максимальный элемент в массиве = ',Max(a));
end.

View file

@ -1,14 +0,0 @@
/// Модуль упрощенной структуры
unit MyUnit; // имя модуля должно совпадать с именем файла
// Документирующие комментарии отображаются при наведении на имя курсора мыши
/// Возвращает максимальный элемент в массиве
function Max(a: array of integer): integer;
begin
Result := integer.MinValue;
foreach x: integer in a do
if x>Result then
Result := x;
end;
end.

View file

@ -1,12 +0,0 @@
// Иллюстрация поиска имен вначале справа налево в секции uses, а затем в системном модуле PABCSystem
uses System;
begin
// Имя Random, определенное в пространстве имен System, перекрывает имя Random
// в модуле PABCSystem, который неявно подключается первым
var r: Random := new Random();
writeln(r.Next(10));
// Именно поэтому перед данным Random необходимо явно указывать имя модуля, в котором он находится
var i: integer := PABCSystem.Random(10);
writeln(i);
end.

View file

@ -1,41 +0,0 @@
// Модуль ABCObjects. Изменение свойств объекта
uses ABCObjects,GraphABC;
const delay = 300;
procedure Pause;
begin
Sleep(delay);
end;
var
r: RectangleABC;
z: StarABC;
begin
z := new StarABC(Window.Center.X,Window.Center.Y,70,30,6,Color.Green);
r := new RectangleABC(100,100,200,100,Color.Gold);
Pause;
r.Center := Window.Center;
Pause;
r.Height := 70;
Pause;
r.Width := 220;
Pause;
z.Radius := 150;
Pause;
z.Color := Color.LightCoral;
Pause;
z.Count := 5;
Pause;
r.Text := 'PascalABC.NET';
r.Color := Color.Gainsboro;
Pause;
r.BorderWidth := 3;
r.BorderColor := Color.Blue;
Pause;
r.Center := Window.Center;
Pause;
// r.Bordered := False;
end.

View file

@ -1,19 +0,0 @@
// Иллюстрация простейших возможностей GraphABC
uses GraphABC;
begin
Coordinate.Origin := Window.Center;
Coordinate.SetMathematic;
Brush.Color := Color.LightSkyBlue;
while True do
begin
LockDrawing;
ClearWindow;
Ellipse(-120,-70,120,70);
Line(0,0,200,0);
Line(0,0,0,200);
Redraw;
Coordinate.Angle := Coordinate.Angle + 1;
Sleep(100);
end;
end.

View file

@ -1,19 +0,0 @@
// Иллюстрация обработки событий мыши
uses GraphABC;
procedure MouseDown(x,y,mb: integer);
begin
MoveTo(x,y);
end;
procedure MouseMove(x,y,mb: integer);
begin
if mb=1 then LineTo(x,y);
end;
begin
// Привязка обработчиков к событиям
OnMouseDown := MouseDown;
OnMouseMove := MouseMove
end.

View file

@ -1,14 +0,0 @@
// Все типы - производные от Object
var
i: integer;
r: real;
o: object;
begin
o := i;
writeln(o.GetType);
o := r;
writeln(o.GetType);
if o.GetType=typeof(real) then
writeln('В переменной o - вещественный тип');
end.

View file

@ -1,22 +0,0 @@
// Упаковка-распаковка размерных типов
var
i: integer := 2;
r: real := 3.14;
o: object;
begin
o := i; // Упаковка: объект размерного типа integer упаковывается в объект ссылочного типа,
// котрый и присваивается переменной o
// Преобразование типов при упаковке - неявное
writeln(integer(o)); // Распаковка: из упакованного объекта извлекается значение
// Преобразование типов при распаковке - явное
o := r;
writeln(real(o));
try // При неверном преобразовании типов генерируется исключение InvalidCastException
writeln(shortint(o));
except
on e: Exception do
writeln(e.GetType);
end;
end.

View file

@ -1,36 +0,0 @@
// Пример использования классового (статического) конструктора
type
Person = class
private
class arr: array of Person; // Классовое поле. Связано не с переменной класса, а с классом.
name: string;
age: integer;
public
class constructor; // Конструктор класса. Вызывается до создания первого объекта класса и до вызова любого классового метода
begin
writeln(' Вызван классовый конструктор');
SetLength(arr,3);
arr[0] := new Person('Иванов',20);
arr[1] := new Person('Петрова',19);
arr[2] := new Person('Попов',35);
end;
constructor (n: string; a: integer);
begin
name := n;
age := a;
end;
function ToString: string; override;
begin
Result := Format('Имя: {0} Возраст: {1}',name,age);
end;
class function RandomPerson: Person; // Классовый метод. Может обращаться только к классовым полям
begin
Result := arr[Random(3)];
end;
end;
begin
writeln('Случайные персоны');
for var i:=1 to 5 do
writeln(Person.RandomPerson); // Вызов классового метода
end.

View file

@ -1,13 +0,0 @@
// Сборка мусора: для освобождения объекта присвойте переменной nil
uses System.Collections.Generic;
var l: List<integer> := new List<integer>;
begin
l.Add(3);
l.Add(5);
l.Add(2);
foreach x:integer in l do
write(x,' ');
l := nil; // после этого память, занимаемая динамическим массивом, будет собрана сборщиком мусора
end.

View file

@ -1,42 +0,0 @@
// Иллюстрация использованя интерфейсов
type
IShape = interface
procedure Draw;
property X: integer read;
property Y: integer read;
end;
ICloneable = interface
function Clone: Object;
end;
Point = class(IShape,ICloneable)
private
xx,yy: integer;
public
constructor Create(x,y: integer);
begin
xx := x; yy := y;
end;
procedure Draw; begin end;
property X: integer read xx;
property Y: integer read yy;
function Clone: Object;
begin
Result := new Point(xx,yy);
end;
end;
var
p: Point := new Point(2,3);
ish: IShape := p;
icl: ICloneable := p;
begin
writeln(ish.X,' ',ish.Y);
var p1: Point := Point(icl.Clone);
p := nil;
writeln(p1.X,' ',p1.Y);
writeln(ish is Point);
writeln(ish is ICloneable); // Cross cast!
end.

View file

@ -1,54 +0,0 @@
// Перегрузка операций
type
Frac = record
private
num,denom: integer;
public
constructor (n,d: integer);
begin
num := n;
denom := d;
end;
class function operator+(a,b: Frac): Frac;
begin
Result := new Frac(a.num*b.denom+b.num*a.denom,a.denom*b.denom);
end;
class function operator-(a,b: Frac): Frac;
begin
Result := new Frac(a.num*b.denom-b.num*a.denom,a.denom*b.denom);
end;
class function operator*(a,b: Frac): Frac;
begin
Result := new Frac(a.num*b.num,a.denom*b.denom);
end;
class function operator/(a,b: Frac): Frac;
begin
Result := new Frac(a.num*b.denom,a.denom*b.num);
end;
class function operator=(a,b: Frac): boolean;
begin
Result := (a.num = b.num) and (a.denom = b.denom);
end;
class procedure operator+=(var a: Frac; b: Frac);
begin
a := a + b;
end;
function ToString: string; override;
begin
Result := Format('{0}/{1}',num,denom);
end;
end;
var
f := new Frac(1,2);
f1 := new Frac(3,5);
begin
writelnFormat('{0} + {1} = {2}',f,f1,f+f1);
writelnFormat('{0} - {1} = {2}',f,f1,f-f1);
writelnFormat('{0} * {1} = {2}',f,f1,f*f1);
writelnFormat('{0} / {1} = {2}',f,f1,f/f1);
writeln(f1=f);
f += f1;
writeln(f);
end.

View file

@ -1,30 +0,0 @@
// Описание методов внутри интерфейса класса
// Удобство: методы можно реализовывать сразу после объявления
// Неудобство: для больших классов интерфейс трудно читается
type
Person = class
private
// Поля класса, как правило, приватны. Доступ к ним - через методы и свойства
name: string;
age: integer;
public
// Конструктор неявно имеет имя Create
constructor (n: string; a: integer);
begin
name := n; age := a;
end;
procedure Print;
begin
writeln('Имя: ',name,' Возраст: ',age);
end;
end;
var p,p1: Person;
begin
p := new Person('Иванов',20); // Новый синтаксис вызова конструктора (рекомендуется)
p.Print;
p1 := Person.Create('Попов',19); // Старый синтаксис вызова конструктора (не рекомендуется)
p1.Print;
// Деструкторы отсутствуют, вместо них - автоматическая сборка мусора
end.

View file

@ -1,26 +0,0 @@
// Иллюстрация конструкторов и методов в записях
// Если переопределен метод ToString, то он вызывается при выводе объекта этого типа процедурой writeln
type
SexType = (Male, Female);
Person = record
Name: string;
Age, Weight: integer;
Sex: SexType;
constructor (Name: string; Age, Weight: integer; Sex: SexType);
begin
Self.Name := Name;
Self.Age := Age;
Self.Sex := Sex;
Self.Weight := Weight;
end;
function ToString: string; override;
begin
Result := Format('Имя: {0} Пол: {1} Возраст: {2} Вес: {3}', Name, Sex, Age, Weight);
end;
end;
var p: Person := new Person('Иванов',20,70,SexType.Male);
begin
writeln(p);
end.

View file

@ -1,56 +0,0 @@
// Демонстрация создания простого класса стека на базе массива
type
Stack<T> = class
private
a: array of T;
last: integer;
public
constructor Create(sz: integer);
begin
SetLength(a,sz);
last := 0;
end;
constructor Create;
begin
Create(100);
end;
procedure push(i: T);
begin
a[last] := i;
Inc(last);
end;
function pop: T;
begin
Dec(last);
pop := a[last];
end;
function top: T;
begin
top := a[last-1];
end;
function empty: boolean;
begin
Result := (last=0);
end;
function ToString: string; override;
begin
Result := '';
for var i:=0 to last-1 do
Result += a[i]+' ';
end;
end;
var s: Stack<integer>;
begin
s := new Stack<integer>;
s.push(7);
s.push(2);
s.push(5);
s.push(4);
writeln(s);
while not s.empty do
write(s.pop,' ');
end.

View file

@ -1,21 +0,0 @@
// Секция Where - ограничение на типы параметров
uses System,System.Collections.Generic;
type
MyClass<T,T1> = class
where T: System.Array,ICloneable;
where T1: constructor;
procedure p(obj1: T; var obj2: T1);
begin
obj1.Clone();
obj2 := new T1;
end;
end;
IntArr = array of integer;
var
m: MyClass<IntArr,integer>;
//m1: MyClass<integer>; // ошибка
begin
end.

View file

@ -1,26 +0,0 @@
// Иллюстрация конструкторов и методов в записях
// Если переопределен метод ToString, то он вызывается при выводе объекта этого типа процедурой writeln
type
SexType = (Male, Female);
Person = record
Name: string;
Age, Weight: integer;
Sex: SexType;
constructor (Name: string; Age, Weight: integer; Sex: SexType);
begin
Self.Name := Name;
Self.Age := Age;
Self.Sex := Sex;
Self.Weight := Weight;
end;
function ToString: string; override;
begin
Result := string.Format('Имя: {0} Возраст: {1} Вес: {2} Пол: {3}', Name, Age, Weight, Sex);
end;
end;
var p: Person := new Person('Иванов',20,70,SexType.Male);
begin
writeln(p);
end.

View file

@ -1,31 +0,0 @@
Uses System;
var d1, d2, d3: DateTime; // Объекты для хранения даты и времени
ts: TimeSpan; // Объект для хранения промежутков времени
begin
// Получение текущей даты - вызов статического метода
d1 := DateTime.Now;
Writeln(d1);
// Дата и время через один месяц
d2 := d1.AddMonths(1);
Writeln(d2);
// Дата и время на 12 часов раньше
d2 := d1.AddHours(-12);
Writeln(d2);
// Формирование даты - вызов конструктора объекта (год, месяц,число)
d3 := new DateTime(2001, 1, 1);
Writeln(d3);
// Определение времени, прошедшего с начала тысячелетия (разность дат)
ts := d1.Subtract(d3);
// Промежуток времени в днях (результат - вещественное число)
Writeln(ts.TotalDays);
// Промежуток времени в днях, часах, минутах и секундах
Writeln(ts.Days, ' ', ts.Hours, ':', ts.Minutes, ':', ts.Seconds);
end.

View file

@ -1,17 +0,0 @@
// Иллюстрация использования компонента WebBrowser
{$apptype windows}
{$reference System.Windows.Forms.dll}
uses
System.Windows.Forms,
System.Net;
begin
var myForm := new Form;
var w := new WebBrowser;
w.Url := new System.Uri('http://pascalabc.net');
w.Dock := Dockstyle.Fill;
myForm.Controls.Add(w);
myForm.WindowState := FormWindowState.Maximized;
Application.Run(myForm);
end.

View file

@ -1,27 +0,0 @@
// Использование LinkedList - двусвязного списка стандартной библиотеки - и его итератора
uses System.Collections,System.Collections.Generic;
procedure print(l: ICollection);
begin
foreach x: integer in l do
write(x,' ');
writeln;
end;
var l: LinkedList<integer> := new LinkedList<integer>;
begin
l.AddLast(3);
l.AddLast(5);
l.AddLast(7);
l.AddFirst(2);
print(l);
var a := new integer[10];
l.CopyTo(a,0);
print(a);
var lit: LinkedListNode<integer> := l.Find(5);
l.AddBefore(lit,777);
print(l);
end.

View file

@ -1,11 +0,0 @@
// Отражение типов. Выводятся все члены типа DateTime
uses System,System.Reflection;
begin
var bf := BindingFlags.Public or BindingFlags.NonPublic or BindingFlags.Instance or BindingFlags.Static;
var t: &Type := typeof(DateTime);
var mi := t.GetMembers(bf);
foreach m: MemberInfo in mi do
writeln(m);
end.

View file

@ -1,29 +0,0 @@
// Создание оконного приложения
{$apptype windows}
{$reference System.Windows.Forms.dll}
uses
System,
System.Windows.Forms;
var
myForm: Form;
myButton: Button;
procedure MyButtonClick(sender: Object; e: EventArgs);
begin
myForm.Close;
end;
begin
myForm := new Form;
myForm.Text := 'Оконное приложение';
myButton := new Button;
myButton.Text := ' Закрыть окно ';
myButton.AutoSize := True;
myButton.Left := 90;
myButton.Top := 110;
myForm.Controls.Add(myButton);
myButton.Click += MyButtonClick;
Application.Run(myForm);
end.

View file

@ -1,12 +0,0 @@
// Использование вспомогательных переменных
var r: real;
begin
write('Введите r: ');
readln(r);
var r2,r4,r8: real; // вспомогательные переменные
r2 := r * r;
r4 := r2 * r2;
r8 := r4 * r4;
writeln(r,' в степени 8 = ',r8);
end.

View file

@ -1,12 +0,0 @@
// Перемена местами значений двух переменных с использованием третьей
var x,y: real;
begin
write('Введите x,y: ');
readln(x,y);
var v: real; // вспомогательная переменная
v := x;
x := y;
y := v;
writeln('Новые значения x,y: ',x,' ',y);
end.

View file

@ -1,18 +0,0 @@
// Присваивания += -= *= /=
var
i: integer;
r: real;
begin
i := 1;
writeln('i := 1; i = ',i);
i += 2; // Увеличение на 2
writeln('i += 2; i = ',i);
i *= 3; // Увеличение в 3 раза
writeln('i *= 3; i = ',i);
writeln;
r := 6;
writeln('r := 6; r = ',r);
r /= 2;
writeln('r /= 2; r = ',r);
end.

View file

@ -1,16 +0,0 @@
// Логический тип. Логические выражения с and, or и not
var
b: boolean;
x: integer;
begin
write('Введите x (от 1 до 9): ');
readln(x);
b := x=5;
writeln('x=5? ',b);
b := (x>=3) and (x<=5);
writeln('x=3,4 или 5? ',b);
b := (x=3) or (x=4) or (x=5);
writeln('x=3,4 или 5? ',b);
b := not Odd(x);
writeln('x - четное? ',b);
end.

View file

@ -1,10 +0,0 @@
// Вывод результатов вычислений
begin
writeln('Вычисления:');
// Вывод пустой строки
writeln;
writeln('121 + 363 = ',121+363);
writeln('121 - 363 = ',121-363);
writeln('121 * 363 = ',121*363);
writeln('121 / 363 = ',121/363);
end.

View file

@ -1,13 +0,0 @@
// Вывод результатов вычислений. Используются именованные константы
const
a = 121;
b = 363;
begin
writeln('Вычисления:');
writeln;
writeln(a,' + ',b,' = ',a+b);
writeln(a,' - ',b,' = ',a-b);
writeln(a,' * ',b,' = ',a*b);
writeln(a,' / ',b,' = ',a/b);
end.

View file

@ -1,12 +0,0 @@
// Вывод результатов вычислений. Используются переменные и процедура ввода
var a,b: integer;
begin
writeln('Введите a и b:');
readln(a,b);
writeln;
writeln(a,' + ',b,' = ',a+b);
writeln(a,' - ',b,' = ',a-b);
writeln(a,' * ',b,' = ',a*b);
writeln(a,' / ',b,' = ',a/b);
end.

Some files were not shown because too many files have changed in this diff Show more