fix index
This commit is contained in:
parent
7132c64f1e
commit
3e48c33ae7
27
.gitignore
vendored
27
.gitignore
vendored
|
|
@ -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
|
||||
|
|
|
|||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load diff
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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>&<>~!%^*()-+=|\#/{}[]:;"' , .?</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 = "<" />
|
||||
<Key word = ">" />
|
||||
<Key word = "<=" />
|
||||
<Key word = ">=" />
|
||||
<Key word = "~" />
|
||||
<Key word = "#" />
|
||||
<Key word = "=" />
|
||||
</KeyWords>
|
||||
|
||||
</RuleSet>
|
||||
|
||||
<RuleSet name = "CommentMarkerSet" ignorecase = "true">
|
||||
<Delimiters><>~!@%^*()-+=|\#/{}[]:;"' , .?</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>
|
||||
Binary file not shown.
|
|
@ -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.
|
||||
Binary file not shown.
Binary file not shown.
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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>
|
||||
|
|
@ -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
|
||||
Binary file not shown.
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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")]
|
||||
|
|
@ -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; }
|
||||
}
|
||||
}
|
||||
|
|
@ -1,3 +0,0 @@
|
|||
cls
|
||||
GPLex_GPPG\gplex.exe /unicode oberon00.lex
|
||||
GPLex_GPPG\gppg.exe /no-lines /gplex oberon00.y
|
||||
|
|
@ -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
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -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);
|
||||
}
|
||||
// ==========================================================================
|
||||
|
||||
|
|
@ -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
10
ReleaseGenerators/.gitignore
vendored
10
ReleaseGenerators/.gitignore
vendored
|
|
@ -3,14 +3,4 @@
|
|||
|
||||
/RebuildStandartModules.exe
|
||||
|
||||
#TODO Вместо утого удалить устаревшие .pas тесты, оставив остальное без игнора
|
||||
/Samples/*
|
||||
!/Samples/_SVN/
|
||||
|
||||
|
||||
|
||||
!/Samples/ExportSamples.bat
|
||||
!/Samples/GetSamples.exe
|
||||
!/Samples/GetSamples.pnet
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
@ -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.
|
||||
|
|
@ -1,10 +0,0 @@
|
|||
// Автоопределение типа переменной
|
||||
// Описание переменной в заголовке цикла for
|
||||
begin
|
||||
var x := 2;
|
||||
for var i:=1 to 10 do
|
||||
begin
|
||||
write(x,' ');
|
||||
x += 2;
|
||||
end;
|
||||
end.
|
||||
|
|
@ -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.
|
||||
|
|
@ -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.
|
||||
|
|
@ -1,5 +0,0 @@
|
|||
// Генерация случайного числа в заданном диапазоне
|
||||
begin
|
||||
var i := Random(2,5);
|
||||
writeln('Случайное целое в диапазоне 2..5: ',i);
|
||||
end.
|
||||
|
|
@ -1,5 +0,0 @@
|
|||
// При работе с вещественными числами невозможно получить ошибку выполнения
|
||||
begin
|
||||
writeln(1/0);
|
||||
writeln(sqrt(-1));
|
||||
end.
|
||||
|
|
@ -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.
|
||||
|
|
@ -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.
|
||||
|
|
@ -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.
|
||||
|
|
@ -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.
|
||||
|
|
@ -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.
|
||||
|
|
@ -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.
|
||||
|
|
@ -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.
|
||||
|
|
@ -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.
|
||||
|
|
@ -1,10 +0,0 @@
|
|||
// Указатели на ссылочные типы запрещены. Исключение: указатели на строки и динамические массивы
|
||||
type
|
||||
A = class
|
||||
i: integer;
|
||||
end;
|
||||
|
||||
var p: ^record field: A; end;
|
||||
|
||||
begin
|
||||
end.
|
||||
|
|
@ -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.
|
||||
|
|
@ -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.
|
||||
|
|
@ -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.
|
||||
|
|
@ -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.
|
||||
|
|
@ -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.
|
||||
|
|
@ -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.
|
||||
|
|
@ -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.
|
||||
|
|
@ -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.
|
||||
Binary file not shown.
|
|
@ -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.
|
||||
|
|
@ -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.
|
||||
|
|
@ -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.
|
||||
|
|
@ -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.
|
||||
|
|
@ -1,9 +0,0 @@
|
|||
// Вызов статического метода add класса Class1, помещенного в пространство имен ClassLibrary1
|
||||
// Класс Class1 помещен в библиотеку ClassLibrary1.dll, откомпилированную на C#
|
||||
|
||||
{$reference ClassLibrary1.dll}
|
||||
uses ClassLibrary1;
|
||||
|
||||
begin
|
||||
writeln(Class1.add(2,3));
|
||||
end.
|
||||
Binary file not shown.
Binary file not shown.
|
|
@ -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.
|
||||
|
|
@ -1,10 +0,0 @@
|
|||
// Это - главная программа
|
||||
// Именами из dll-библиотеки, написанной на PascalABC.NET, можно пользоваться,
|
||||
// не подключая пространства имен
|
||||
{$reference mydll.dll}
|
||||
|
||||
begin
|
||||
PrintPascalABCNET;
|
||||
writeln(n);
|
||||
writeln(add(2,3));
|
||||
end.
|
||||
|
|
@ -1,6 +0,0 @@
|
|||
// Вызов функции из обычной dll
|
||||
function add(a,b: integer): integer; external 'NativeDll.dll' name 'add'; // объявление внешней функции
|
||||
|
||||
begin // основная программа
|
||||
writeln(add(2,3));
|
||||
end.
|
||||
Binary file not shown.
|
|
@ -1,13 +0,0 @@
|
|||
// Îòêîìïèëèðîâàòü â Delphi
|
||||
library NativeDll;
|
||||
|
||||
function add(a,b: integer): integer; stdcall;
|
||||
begin
|
||||
Result := a+b;
|
||||
end;
|
||||
|
||||
exports
|
||||
add;
|
||||
begin
|
||||
end.
|
||||
|
||||
|
|
@ -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.
|
||||
|
|
@ -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.
|
||||
Binary file not shown.
|
|
@ -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.
|
||||
|
|
@ -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.
|
||||
|
|
@ -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.
|
||||
|
|
@ -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.
|
||||
|
||||
|
|
@ -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.
|
||||
|
|
@ -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.
|
||||
|
|
@ -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.
|
||||
|
|
@ -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.
|
||||
|
|
@ -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.
|
||||
|
|
@ -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.
|
||||
|
|
@ -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.
|
||||
|
|
@ -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.
|
||||
|
|
@ -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.
|
||||
|
||||
|
||||
|
|
@ -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.
|
||||
|
|
@ -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.
|
||||
|
|
@ -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.
|
||||
|
|
@ -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.
|
||||
|
|
@ -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.
|
||||
|
|
@ -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.
|
||||
|
||||
|
|
@ -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.
|
||||
|
|
@ -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.
|
||||
|
|
@ -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.
|
||||
|
|
@ -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.
|
||||
|
|
@ -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.
|
||||
|
|
@ -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.
|
||||
|
|
@ -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.
|
||||
|
|
@ -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
Loading…
Reference in a new issue