Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
No results found
Show changes
Commits on Source (19)
Showing
with 2488 additions and 649 deletions
......@@ -68,13 +68,19 @@ namespace Lexer
public override bool Parse()
{
NextCh();
int sign = 1;
if (currentCh == '+' || currentCh == '-')
{
if(currentCh== '-')
{
sign = -1;
}
NextCh();
}
if (char.IsDigit(currentCh))
{
parseResult = parseResult * 10 + (currentCh - 48);
NextCh();
}
else
......@@ -84,7 +90,8 @@ namespace Lexer
while (char.IsDigit(currentCh))
{
NextCh();
parseResult = parseResult * 10 + (currentCh - 48);
NextCh();
}
......@@ -93,6 +100,8 @@ namespace Lexer
Error();
}
parseResult*=sign;
return true;
}
......@@ -100,7 +109,7 @@ namespace Lexer
public class IdentLexer : Lexer
{
private string parseResult;
public string parseResult;
protected StringBuilder builder;
public string ParseResult
......@@ -114,22 +123,92 @@ namespace Lexer
}
public override bool Parse()
{
throw new NotImplementedException();
{
NextCh();
if (currentCh >= 'A' && currentCh <= 'Z')
{
parseResult += currentCh;
NextCh();
}
else
if (currentCh >= 'a' && currentCh <= 'z')
{
parseResult += currentCh;
NextCh();
}
else
{
Error();
}
while (char.IsDigit(currentCh) || currentCh >= 'A' && currentCh <= 'Z' || currentCh >= 'a' && currentCh <= 'z' || currentCh == '_')
{
parseResult += currentCh;
NextCh();
}
if (currentCharValue != -1)
{
Error();
}
return true;
// throw new NotImplementedException();
}
}
public class IntNoZeroLexer : IntLexer
{
protected System.Text.StringBuilder intString;
public int parseResult = 0;
public IntNoZeroLexer(string input)
: base(input)
{
intString = new System.Text.StringBuilder();
}
public override bool Parse()
{
throw new NotImplementedException();
NextCh();
int sign = 1;
if (currentCh == '+' || currentCh == '-')
{
if (currentCh == '-')
{
sign = -1;
}
NextCh();
}
if (char.IsDigit(currentCh) && currentCh != '0')
{
parseResult = parseResult * 10 + (currentCh - 48);
NextCh();
}
else
{
Error();
}
while (char.IsDigit(currentCh))
{
parseResult = parseResult * 10 + (currentCh - 48);
NextCh();
}
if (currentCharValue != -1)
{
Error();
}
parseResult *= sign;
return true;
//throw new NotImplementedException();
}
}
......@@ -151,7 +230,49 @@ namespace Lexer
public override bool Parse()
{
throw new NotImplementedException();
NextCh();
bool is_dig = true;
if (currentCh >= 'A' && currentCh <= 'Z' || currentCh >= 'a' && currentCh <= 'z')
{
is_dig = false;
parseResult += currentCh;
NextCh();
}
else
{
Error();
}
while (char.IsDigit(currentCh) || currentCh >= 'A' && currentCh <= 'Z' || currentCh >= 'a' && currentCh <= 'z')
{
if(char.IsDigit(currentCh) && is_dig || (currentCh >= 'A' && currentCh <= 'Z' || currentCh >= 'a' && currentCh <= 'z') && !is_dig)
{
Error();
}
else
if(char.IsDigit(currentCh))
{
is_dig = true;
parseResult += currentCh;
NextCh();
}
else
if(currentCh >= 'A' && currentCh <= 'Z' || currentCh >= 'a' && currentCh <= 'z')
{
is_dig = false;
parseResult += currentCh;
NextCh();
}
}
if (currentCharValue != -1)
{
Error();
}
return true;
//throw new NotImplementedException();
}
}
......@@ -173,7 +294,54 @@ namespace Lexer
public override bool Parse()
{
throw new NotImplementedException();
NextCh();
bool is_letter = false;
int count_letters = 0;
int count_spacers = 0;
if (char.IsLetter(currentCh))
{
is_letter = true;
count_letters++;
parseResult.Add(currentCh);
NextCh();
}
else
{
Error();
}
while (char.IsLetter(currentCh) || currentCh == ',' || currentCh == ';')
{
if (char.IsLetter(currentCh) && is_letter || (currentCh == ',' || currentCh == ';') && !is_letter)
{
Error();
}
else
if (char.IsLetter(currentCh))
{
is_letter = true;
count_letters++;
parseResult.Add(currentCh);
NextCh();
}
else
if (currentCh == ',' || currentCh == ';')
{
is_letter = false;
count_spacers++;
NextCh();
}
}
if (currentCharValue != -1 || count_letters != count_spacers + 1)
{
Error();
}
return true;
//throw new NotImplementedException();
}
}
......@@ -194,7 +362,47 @@ namespace Lexer
public override bool Parse()
{
throw new NotImplementedException();
NextCh();
bool is_dig = false;
int k = 0;//
int c = 1;//
while (char.IsDigit(currentCh) || currentCh == ' '){
if (char.IsDigit(currentCh) && !is_dig)
{
is_dig = true;
k++;
string s = "";
for (int i = 0; i < 1; i++)
{
s += currentCh;
}
parseResult.Add(Int32.Parse(s));
NextCh();
c++;
}
else
if (currentCh == ' ' && k!=0)
{
is_dig = false;
NextCh();
c++;
}
else
break;
}
if (k == 1 && c > 2 || currentCharValue != -1)
{
Error();
}
return true;
//throw new NotImplementedException();
}
}
......@@ -216,7 +424,46 @@ namespace Lexer
public override bool Parse()
{
throw new NotImplementedException();
NextCh();
if(char.IsDigit(currentCh) || currentCharValue ==-1)
{
Error();
}
int seq_digit_count = 0; //
int seq_letter_count = 0; //
bool is_dig = false;
while (char.IsDigit(currentCh) || char.IsLetter(currentCh))
{
if (char.IsDigit(currentCh) && seq_digit_count < 2)
{
is_dig = true;
seq_digit_count++;
seq_letter_count = 0;
parseResult += currentCh;
NextCh();
}
else
if (char.IsLetter(currentCh) && seq_letter_count < 2)
{
is_dig = false;
seq_letter_count++;
seq_digit_count = 0;
parseResult += currentCh;
NextCh();
}
else
break;
}
if (currentCharValue != -1)
{
Error();
}
return true;
//throw new NotImplementedException();
}
}
......@@ -240,7 +487,50 @@ namespace Lexer
public override bool Parse()
{
throw new NotImplementedException();
NextCh();
if (currentCh == '.' || currentCharValue == -1)
{
Error();
}
bool all_integer_part = false;
double denum = 10;
while(char.IsDigit(currentCh) || currentCh == '.')
{
if (char.IsDigit(currentCh) && !all_integer_part)
{
string s = "";
s += currentCh;
parseResult = parseResult * 10 + Int32.Parse(s);
NextCh();
}
else
if (currentCh == '.')
{
all_integer_part = true;
NextCh();
}
else
if (char.IsDigit(currentCh) && all_integer_part)
{
string s = "";
s += currentCh;
parseResult = parseResult + (Int32.Parse(s) / denum);
denum *= 10;
NextCh();
}
else
break;
}
if (all_integer_part && denum == 10 || currentCharValue != -1)
{
Error();
}
return true;
//throw new NotImplementedException();
}
}
......@@ -264,7 +554,41 @@ namespace Lexer
public override bool Parse()
{
throw new NotImplementedException();
NextCh();
bool open_lexem = false;
bool close_lexem = false;
int count = 0; //
if(currentCh!='\'')
{
Error();
}
while (!close_lexem && currentCharValue!=-1)
{
if (currentCh == '\'' && !open_lexem)
{
count++;
open_lexem = true;
}
else
if (currentCh == '\'' && open_lexem)
{
count++;
close_lexem = true;
}
parseResult += currentCh;
NextCh();
}
if (count != 2 || currentCharValue!=-1)
{
Error();
}
return true;
//throw new NotImplementedException();
}
}
......@@ -287,7 +611,47 @@ namespace Lexer
public override bool Parse()
{
throw new NotImplementedException();
NextCh();
bool open_comment = false;
bool close_comment = false;
int count = 0; // '/'
if (currentCh != '/')
{
Error();
}
NextCh();
if (currentCh != '*')
{
Error();
}
NextCh();
count++;
while (!close_comment && currentCharValue != -1)
{
if (currentCh == '*')
{
NextCh();
if(currentCharValue!=-1 && currentCh == '/')
{
count++;
close_comment = true;
}
}
parseResult += currentCh;
NextCh();
}
if (count != 2 || currentCharValue != -1)
{
Error();
}
return true;
//throw new NotImplementedException();
}
}
......@@ -319,8 +683,8 @@ namespace Lexer
{
public static void Main()
{
string input = "154216";
Lexer L = new IntLexer(input);
string input = "''";
Lexer L = new StringLexer(input);
try
{
L.Parse();
......
......@@ -100,6 +100,20 @@ namespace SimpleLexer
keywordsMap["begin"] = Tok.BEGIN;
keywordsMap["end"] = Tok.END;
keywordsMap["cycle"] = Tok.CYCLE;
keywordsMap["and"] = Tok.AND;
keywordsMap["or"] = Tok.OR;
keywordsMap["not"] = Tok.NOT;
keywordsMap["div"] = Tok.DIV;
keywordsMap["mod"] = Tok.MOD;
keywordsMap["while"] = Tok.WHILE;
keywordsMap["do"] = Tok.DO;
keywordsMap["for"] = Tok.FOR;
keywordsMap["to"] = Tok.TO;
keywordsMap["if"] = Tok.IF;
keywordsMap["then"] = Tok.THEN;
keywordsMap["else"] = Tok.ELSE;
keywordsMap["("] = Tok.LEFT_BRACKET;
keywordsMap[")"] = Tok.RIGHT_BRACKET;
}
public string FinishCurrentLine()
......@@ -158,7 +172,12 @@ namespace SimpleLexer
LexCol = col;
// Тип лексемы определяется по ее первому символу
// Для каждой лексемы строится синтаксическая диаграмма
if (currentCh == ';')
if(currentCh == ',')
{
NextCh();
LexKind = Tok.COMMA;
}
else if (currentCh == ';')
{
NextCh();
LexKind = Tok.SEMICOLON;
......@@ -166,12 +185,18 @@ namespace SimpleLexer
else if (currentCh == ':')
{
NextCh();
if (currentCh != '=')
if (currentCh == '=')
{
LexError("= was expected");
NextCh();
LexKind = Tok.ASSIGN;
}
else
LexKind = Tok.COLON;
}
else if (currentCh == '=')
{
NextCh();
LexKind = Tok.ASSIGN;
LexKind = Tok.EQ;
}
else if (char.IsLetter(currentCh))
{
......@@ -197,6 +222,118 @@ namespace SimpleLexer
LexValue = Int32.Parse(LexText);
LexKind = Tok.INUM;
}
else if (currentCh == '+')
{
NextCh();
if (currentCh == '=')
{
NextCh();
LexKind = Tok.PLUSASSIGN;
}
else
LexKind = Tok.PLUS;
}
else if (currentCh == '-')
{
NextCh();
if (currentCh == '=')
{
NextCh();
LexKind = Tok.MINUSASSIGN;
}
else
LexKind = Tok.MINUS;
}
else if (currentCh == '*')
{
NextCh();
if (currentCh == '=')
{
NextCh();
LexKind = Tok.MULTASSIGN;
}
else
LexKind = Tok.MULT;
}
else if (currentCh == '/')
{
NextCh();
if (currentCh == '=')
{
NextCh();
LexKind = Tok.DIVASSIGN;
}
else if (currentCh == '/')
{
while(currentCh != '\n' && currentCh != '\0')
{
NextCh();
}
if (currentCh == '\0')
{
LexKind = Tok.EOF;
}
else
NextLexem();
}
else
LexKind = Tok.DIVISION;
}
else if (currentCh == '{')
{
while (currentCh != '}' && currentCh != '\0')
{
NextCh();
}
if (currentCh != '}')
{
LexError("Expected \'}\'");
}
else
{
NextCh();
NextLexem();
}
}
else if (currentCh == '>')
{
NextCh();
if (currentCh == '=')
{
NextCh();
LexKind = Tok.GEQ;
}
else
LexKind = Tok.GT;
}
else if (currentCh == '<')
{
NextCh();
if (currentCh == '=')
{
NextCh();
LexKind = Tok.LEQ;
}
else if (currentCh == '>')
{
NextCh();
LexKind = Tok.NEQ;
}
else
LexKind = Tok.LT;
}
else if(currentCh == '(')
{
NextCh();
LexKind = Tok.LEFT_BRACKET;
}
else if(currentCh == ')')
{
NextCh();
LexKind = Tok.RIGHT_BRACKET;
}
else if ((int)currentCh == 0)
{
LexKind = Tok.EOF;
......
......@@ -9,14 +9,28 @@ namespace SimpleLangLexerTest
{
class Program
{
public static List<KeyValuePair<Tok, string>> getLexerOutput(Lexer l)
{
List<KeyValuePair<Tok, string>> result = new List<KeyValuePair<Tok, string>>();
do
{
result.Add(new KeyValuePair<Tok, string>(l.LexKind, l.LexText));
l.NextLexem();
} while (l.LexKind != Tok.EOF);
return result;
}
public static void Main()
{
string fileContents = @"begin
/*string fileContents = @"begin
id23 := 24;
cycle ; 2 id258 id29 ;
end";
end";*/
string fileContents = @" ts:=623 { 23 sa 3 }";
TextReader inputReader = new StringReader(fileContents);
Lexer l = new Lexer(inputReader);
var list = getLexerOutput(l);
try
{
do
......
......@@ -13,9 +13,9 @@ namespace GeneratedLexer
private byte[] inputText = new byte[255];
public int idCount = 0;
public int minIdLength = Int32.MaxValue;
public double minIdLength = Int32.MaxValue;
public double avgIdLength = 0;
public int maxIdLength = 0;
public double maxIdLength = 0;
public int sumInt = 0;
public double sumDouble = 0.0;
public List<string> idsInComment = new List<string>();
......@@ -41,11 +41,31 @@ namespace GeneratedLexer
System.Threading.Thread.CurrentThread.CurrentCulture = new System.Globalization.CultureInfo("en-US");
int tok = 0;
int all_length = 0;
do {
tok = myScanner.yylex();
if (tok == (int)Tok.EOF)
if ((Tok)tok == Tok.ID)
{
idCount++;
var length = myScanner.TokToString((Tok)tok).Length - 3;
all_length += length;
if (length < minIdLength)
minIdLength = length;
if (length > maxIdLength)
maxIdLength = length;
}
else if ((Tok)tok == Tok.INUM)
{
sumInt += myScanner.LexValueInt;
}
else if ((Tok)tok == Tok.RNUM)
{
sumDouble += myScanner.LexValueDouble;
}
else if (tok == (int)Tok.EOF)
{
avgIdLength = all_length /(double)idCount;
idsInComment = myScanner.idsInComment;
break;
}
} while (true);
......
This diff is collapsed.
......@@ -6,14 +6,20 @@ Digit [0-9]
AlphaDigit {Alpha}|{Digit}
INTNUM {Digit}+
REALNUM {INTNUM}\.{INTNUM}
ID {Alpha}{AlphaDigit}*
ID {Alpha}{AlphaDigit}*
DotChr [^\r\n]
OneLineCmnt \/\/{DotChr}*
STRINGAP \'[^']*\'
// , - Scanner
%{
public int LexValueInt;
public double LexValueDouble;
public List<string> idsInComment = new List<string>();
%}
%x COMMENT
%%
{INTNUM} {
LexValueInt = int.Parse(yytext);
......@@ -53,6 +59,39 @@ cycle {
return (int)Tok.SEMICOLON;
}
{OneLineCmnt} {
return (int)Tok.COMMENT;
}
{STRINGAP} {
return (int)Tok.STRINGAP;
}
"{" {
// COMMENT
BEGIN(COMMENT);
return (int)Tok.LONGCOMMENT;
}
<COMMENT> "}" {
// INITIAL
BEGIN(INITIAL);
return (int)Tok.LONGCOMMENT;
}
<COMMENT>begin {
}
<COMMENT>end {
}
<COMMENT>cycle {
}
<COMMENT>{ID} {
// ID
idsInComment.Add(yytext);
}
[^ \r\n] {
LexError();
return 0; //
......@@ -64,6 +103,8 @@ cycle {
public void LexError()
{
//Encoding encoding = Encoding.GetEncoding("windows-1251");
//Console.OutputEncoding = encoding;
Console.WriteLine("({0},{1}): {2}", yyline, yycol, yytext);
}
......
......@@ -2,6 +2,7 @@ using System;
using System.IO;
using SimpleScanner;
using ScannerHelper;
using System.Collections.Generic;
namespace GeneratedLexer
{
......@@ -11,7 +12,7 @@ namespace GeneratedLexer
static void Main(string[] args)
{
int cnt_id = 0;//-
int min_id_len = Int32.MaxValue, max_id_len = 0; //,
double min_id_len = Double.MaxValue, max_id_len = 0; //,
double avg_id_len = 0; //
int sum_int = 0; //
......@@ -27,16 +28,150 @@ namespace GeneratedLexer
Scanner scanner = new Scanner(new FileStream(fname, FileMode.Open));
int tok = 0;
int all_length = 0;
bool longcomment = false;
List<string> idsInComment = new List<string>();
do {
tok = scanner.yylex();
if ((Tok)tok == Tok.ID && !longcomment)
{
cnt_id++;
var length = scanner.TokToString((Tok)tok).Length - 3;
all_length += length;
if (length < min_id_len)
min_id_len = length;
if (length > max_id_len)
max_id_len = length;
}
else if ((Tok)tok == Tok.ID && longcomment)
{
var s = scanner.TokToString((Tok)tok);
var id = "";
for (int i = 3; i < s.Length; i++)
{
id += s[i];
}
idsInComment.Add(id);
}
else if ((Tok)tok == Tok.INUM)
{
int sum = 0;
var k = scanner.TokToString((Tok)tok);
int index_begin = 0;
for (int i=0;i<k.Length;i++)
{
if (char.IsDigit(k[i]))
{
index_begin = i;
break;
}
}
for (int i = index_begin; i < k.Length; i++)
{
sum = sum * 10 + int.Parse(k[i].ToString());
}
sum_int += sum;
}
else if ((Tok)tok == Tok.RNUM)
{
double sum = 0;
var k = scanner.TokToString((Tok)tok);
int index1 = 0;
int index2 = 0;
for (int i = 0; i < k.Length; i++)
{
if (char.IsDigit(k[i]))
{
index1 = i;
break;
}
}
for (int i = index1; i < k.Length; i++)
{
if (k[i]=='.')
{
index2 = i;
break;
}
}
for (int i = index1; i < index2; i++)
{
sum = sum * 10 + int.Parse(k[i].ToString());
}
double double_part = 0;
for(int i=index2+1;i<k.Length;i++)
{
double_part = double_part*10+int.Parse(k[i].ToString())/(Math.Pow(10,(i-index2)));
}
sum += double_part;
sum_d += sum;
}
else if ((Tok)tok == Tok.STRINGAP)
{
var s = scanner.TokToString((Tok)tok);
int ind = 0;
for (int i = 0; i < s.Length; i++)
{
if (s[i] == '\'')
{
ind = i;
break;
}
}
var s2 = "";
for (int i = ind + 1; i < s.Length; i++)
{
if (s[i] == '\'')
break;
s2 += s[i];
}
int tok2 = 0;
byte[] inputText2 = new byte[255];
using (StreamWriter writer = new StreamWriter(new MemoryStream(inputText2)))
{
writer.Write(s2);
writer.Flush();
}
MemoryStream inputStream2 = new MemoryStream(inputText2);
var myScanner2 = new Scanner(inputStream2);
do
{
tok2 = myScanner2.yylex();
if ((Tok)tok2 == Tok.ID)
{
cnt_id++;
}
else if (tok2 == (int)Tok.EOF)
{
break;
}
} while (true);
}
if ((Tok)tok == Tok.LONGCOMMENT && !longcomment)
{
longcomment = true;
}
else if ((Tok)tok == Tok.LONGCOMMENT && longcomment)
{
longcomment = false;
}
if (tok == (int)Tok.EOF)
{
avg_id_len = all_length / (double)cnt_id;
Console.WriteLine();
Console.WriteLine("number of id: {0:D}", cnt_id);
Console.WriteLine("average length of the id: {0:N}", avg_id_len / cnt_id);
Console.WriteLine("min length of the id: {0:D}", min_id_len);
Console.WriteLine("min length of the id: {0:D}", max_id_len);
Console.WriteLine("average length of the id: {0:N}", avg_id_len);
Console.WriteLine("min length of the id: {0:D}", (int)min_id_len);
Console.WriteLine("max length of the id: {0:D}", (int)max_id_len);
Console.WriteLine();
Console.WriteLine("sum of int: {0:D}", sum_int);
......@@ -54,3 +189,109 @@ namespace GeneratedLexer
}
}
}
/* 1
begin ggg : ; := 7 99.9 5
1
ppp end
-------------------------
BEGIN
ID ggg
COLON
SEMICOLON
ASSIGN
INUM 7
RNUM 99.9
INUM 5
INUM 1
ID ppp
END
number of id: 0
average length of the id: NaN
min length of the id: 2147483647
min length of the id: 0
sum of int: 0
sum of double: 0.00
begin ggg : ; :+= 7 99.9 5
1
ppp end
-------------------------
BEGIN
ID ggg
COLON
SEMICOLON
COLON
(1,15): Iaecaanoiue neiaie +
number of id: 0
average length of the id: NaN
min length of the id: 2147483647
min length of the id: 0
sum of int: 0
sum of double: 0.00
()()()()()()()()()()()()()()()()
begin ggg : ; := 7 99.9 5 //
1
ppp end
-------------------------
BEGIN
ID ggg
COLON
SEMICOLON
ASSIGN
INUM 7
RNUM 99.9
INUM 5
(1,26): Iaecaanoiue neiaie /
number of id: 0
average length of the id: NaN
min length of the id: 2147483647
min length of the id: 0
sum of int: 0
sum of double: 0.00
()()()()()()()()()()()()()()()()
begin ggg : ; := 7 99.9 5
1
ppp end {}
-------------------------
BEGIN
ID ggg
COLON
SEMICOLON
ASSIGN
INUM 7
RNUM 99.9
INUM 5
INUM 1
ID ppp
END
(3,8): Iaecaanoiue neiaie {
number of id: 0
average length of the id: NaN
min length of the id: 2147483647
min length of the id: 0
sum of int: 0
sum of double: 0.00
*/
......@@ -29,9 +29,58 @@ namespace SimpleLangParser
public void Expr()
{
if (l.LexKind == Tok.ID || l.LexKind == Tok.INUM)
/*if (l.LexKind == Tok.ID || l.LexKind == Tok.INUM || l.LexKind == Tok.LEFT_BRACKET ||
l.LexKind == Tok.RIGHT_BRACKET || l.LexKind == Tok.PLUS || l.LexKind == Tok.MINUS ||
l.LexKind == Tok.MULT || l.LexKind == Tok.DIVISION)
{
while(l.LexKind == Tok.ID || l.LexKind == Tok.INUM || l.LexKind == Tok.LEFT_BRACKET ||
l.LexKind == Tok.RIGHT_BRACKET || l.LexKind == Tok.PLUS || l.LexKind == Tok.MINUS ||
l.LexKind == Tok.MULT || l.LexKind == Tok.DIVISION)
{
l.NextLexem();
}
}*/
T();
A();
/*else
{
SyntaxError("expression expected");
}*/
}
public void T()
{
M();
B();
}
public void A()
{
if(l.LexKind == Tok.PLUS || l.LexKind==Tok.MINUS)
{
l.NextLexem();
T();
A();
}
}
public void M()
{
if(l.LexKind==Tok.ID || l.LexKind == Tok.INUM)
{
l.NextLexem();
}
else if(l.LexKind==Tok.LEFT_BRACKET)
{
l.NextLexem();
Expr();
if (l.LexKind == Tok.RIGHT_BRACKET)
l.NextLexem();
else
{
SyntaxError("expression expected");
}
}
else
{
......@@ -39,6 +88,16 @@ namespace SimpleLangParser
}
}
public void B()
{
if (l.LexKind == Tok.MULT || l.LexKind == Tok.DIVISION)
{
l.NextLexem();
M();
B();
}
}
public void Assign()
{
l.NextLexem(); // пропуск id
......@@ -81,6 +140,21 @@ namespace SimpleLangParser
Assign();
break;
}
case Tok.WHILE:
{
While();
break;
}
case Tok.FOR:
{
For();
break;
}
case Tok.IF:
{
If();
break;
}
default:
{
SyntaxError("Operator expected");
......@@ -111,6 +185,81 @@ namespace SimpleLangParser
Statement();
}
public void While()
{
l.NextLexem(); // пропуск while
Expr();
if (l.LexKind == Tok.DO)
{
l.NextLexem();
Statement();
}
else
{
SyntaxError("do expected");
}
}
public void For()
{
l.NextLexem(); //пропуск for
if(l.LexKind == Tok.ID)
{
l.NextLexem();
if(l.LexKind == Tok.ASSIGN)
{
l.NextLexem();
Expr();
if (l.LexKind == Tok.TO)
{
l.NextLexem();
Expr();
if (l.LexKind == Tok.DO)
{
l.NextLexem();
Statement();
}
else
{
SyntaxError("do expected");
}
}
else
{
SyntaxError("to expected");
}
}
else
{
SyntaxError("assign expected");
}
}
else
{
SyntaxError("id expected");
}
}
public void If()
{
l.NextLexem(); //пропуск if
Expr();
if (l.LexKind == Tok.THEN)
{
l.NextLexem();
Statement();
if (l.LexKind == Tok.ELSE)
{
l.NextLexem();
Statement();
}
}
else
{
SyntaxError("then expected");
}
}
public void SyntaxError(string message)
{
var errorMessage = "Syntax error in line " + l.LexRow.ToString() + ":\n";
......
//
// This CSharp output file generated by Gardens Point LEX
// Gardens Point LEX (GPLEX) is Copyright (c) John Gough, QUT 2006-2014.
// Output produced by GPLEX is the property of the user.
// See accompanying file GPLEXcopyright.rtf.
//
// GPLEX Version: 1.2.2
// Machine: MAINHOMEPC2
// DateTime: 30.09.2018 18:11:00
// UserName: someone
// GPLEX input file <SimpleLex.lex - 24.09.2018 23:47:02>
// Version: 1.1.3.301
// Machine: LAPTOP-COHFJ4CB
// DateTime: 24.10.2022 13:31:30
// UserName: Acer
// GPLEX input file <SimpleLex.lex>
// GPLEX frame file <embedded resource>
//
// Option settings: unicode, parser, minimize
......@@ -17,8 +13,8 @@
//
//
// Revised backup code
// Version 1.2.1 of 24-June-2013
// Experimental embedded frame
// Version 1.1.3 of 18-April-2010
//
//
#define BACKUP
......@@ -127,8 +123,8 @@ namespace SimpleScanner
enum Result {accept, noMatch, contextFound};
const int maxAccept = 7;
const int initial = 8;
const int maxAccept = 14;
const int initial = 15;
const int eofNum = 0;
const int goStart = -1;
const int INITIAL = 0;
......@@ -165,24 +161,24 @@ namespace SimpleScanner
}
};
static int[] startState = new int[] {8, 0};
static int[] startState = new int[] {15, 0};
#region CompressedCharacterMap
//
// There are 8 equivalence classes
// There are 15 equivalence classes
// There are 2 character sequence regions
// There are 1 tables, 123 entries
// There are 1 runs, 0 singletons
// Decision tree depth is 1
//
static sbyte[] mapC0 = new sbyte[123] {
/* '\0' */ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 7, 7, 0, 7, 7,
/* '\x10' */ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
/* '\x20' */ 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 2, 7,
/* '0' */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 4, 6, 7, 5, 7, 7,
/* '@' */ 7, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
/* 'P' */ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 7, 7, 7, 7, 3,
/* '`' */ 7, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
/* '\0' */ 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 0, 14, 14, 0, 14, 14,
/* '\x10' */ 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
/* '\x20' */ 0, 14, 14, 14, 14, 14, 14, 14, 7, 8, 12, 10, 9, 11, 2, 13,
/* '0' */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 4, 6, 14, 5, 14, 14,
/* '@' */ 14, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
/* 'P' */ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 14, 14, 14, 14, 3,
/* '`' */ 14, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
/* 'p' */ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 };
static sbyte MapC(int code)
......@@ -190,22 +186,29 @@ namespace SimpleScanner
if (code < 123) // '\0' <= code <= 'z'
return mapC0[code - 0];
else // '{' <= code <= '\U0010FFFF'
return (sbyte)7;
return (sbyte)14;
}
#endregion
static Table[] NxS = new Table[10] {
static Table[] NxS = new Table[17] {
/* NxS[ 0] */ new Table(0, 0, 0, null),
/* NxS[ 1] */ new Table(1, 2, -1, new sbyte[] {1, 9}),
/* NxS[ 1] */ new Table(1, 2, -1, new sbyte[] {1, 16}),
/* NxS[ 2] */ new Table(0, 0, -1, null),
/* NxS[ 3] */ new Table(1, 3, -1, new sbyte[] {3, -1, 3}),
/* NxS[ 4] */ new Table(5, 1, -1, new sbyte[] {6}),
/* NxS[ 4] */ new Table(5, 1, -1, new sbyte[] {13}),
/* NxS[ 5] */ new Table(0, 0, -1, null),
/* NxS[ 6] */ new Table(0, 0, -1, null),
/* NxS[ 7] */ new Table(1, 1, -1, new sbyte[] {7}),
/* NxS[ 8] */ new Table(1, 7, -1, new sbyte[] {1, 2, 3, 4, 2, 5,
2}),
/* NxS[ 9] */ new Table(1, 1, -1, new sbyte[] {7}),
/* NxS[ 7] */ new Table(0, 0, -1, null),
/* NxS[ 8] */ new Table(0, 0, -1, null),
/* NxS[ 9] */ new Table(0, 0, -1, null),
/* NxS[ 10] */ new Table(0, 0, -1, null),
/* NxS[ 11] */ new Table(0, 0, -1, null),
/* NxS[ 12] */ new Table(0, 0, -1, null),
/* NxS[ 13] */ new Table(0, 0, -1, null),
/* NxS[ 14] */ new Table(1, 1, -1, new sbyte[] {14}),
/* NxS[ 15] */ new Table(1, 14, -1, new sbyte[] {1, 2, 3, 4, 2, 5,
6, 7, 8, 9, 10, 11, 12, 2}),
/* NxS[ 16] */ new Table(1, 1, -1, new sbyte[] {14}),
};
int NextState() {
......@@ -215,7 +218,7 @@ int NextState() {
unchecked {
int rslt;
int idx = MapC(code) - NxS[state].min;
if (idx < 0) idx += 8;
if (idx < 0) idx += 15;
if ((uint)idx >= (uint)NxS[state].rng) rslt = NxS[state].dflt;
else rslt = NxS[state].nxt[idx];
return rslt;
......@@ -295,7 +298,8 @@ int NextState() {
public Scanner(Stream file, string codepage) {
SetSource(file, CodePageHandling.GetCodePage(codepage));
}
}
#endif // !NOFILES
public Scanner() { }
......@@ -323,7 +327,7 @@ int NextState() {
if (next < 0xDC00 || next > 0xDFFF)
code = ScanBuff.UnicodeReplacementChar;
else
code = (0x10000 + ((code & 0x3FF) << 10) + (next & 0x3FF));
code = (0x10000 + (code & 0x3FF << 10) + (next & 0x3FF));
}
#endif
cCol++;
......@@ -376,7 +380,9 @@ int NextState() {
GetCode();
}
#if !NOFILES
// ================ LineBuffer Initialization ===================
/// <summary>
/// Create and initialize a LineBuff buffer object for this scanner
/// </summary>
......@@ -390,7 +396,6 @@ int NextState() {
GetCode();
}
#if !NOFILES
// =============== StreamBuffer Initialization ==================
/// <summary>
......@@ -492,12 +497,6 @@ int NextState() {
}
}
/// <summary>
/// Discards all but the first "n" codepoints in the recognized pattern.
/// Resets the buffer position so that only n codepoints have been consumed;
/// yytext is also re-evaluated.
/// </summary>
/// <param name="n">The number of codepoints to consume</param>
[SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
void yyless(int n)
{
......@@ -517,10 +516,6 @@ int NextState() {
// but it does not seem possible to re-establish
// the correct column counts except by going forward.
//
/// <summary>
/// Removes the last "n" code points from the pattern.
/// </summary>
/// <param name="n">The number to remove</param>
[SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
void _yytrunc(int n) { yyless(yyleng - n); }
......@@ -533,23 +528,18 @@ int NextState() {
// can't use (tokEPos - tokPos) because of the
// possibility of surrogate pairs in the token.
//
/// <summary>
/// The length of the pattern in codepoints (not the same as
/// string-length if the pattern contains any surrogate pairs).
/// </summary>
[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
#if BYTEMODE
return tokEPos - tokPos;
#else
{
else {
int ch;
int count = 0;
int save = buffer.Pos;
......@@ -558,7 +548,7 @@ int NextState() {
ch = buffer.Read();
if (!char.IsHighSurrogate((char)ch)) count++;
} while (buffer.Pos < tokEPos && ch != ScanBuff.EndOfFile);
buffer.Pos = save;
buffer.Pos = save;
return count;
}
#endif // BYTEMODE
......@@ -583,56 +573,65 @@ int NextState() {
// ============== The main tokenizer code =================
int Scan() {
int Scan()
{
try {
for (; ; ) {
int next; // next state to enter
for (; ; )
{
int next; // next state to enter
#if BACKUP
Result rslt = Result.noMatch;
#endif // BACKUP
#if LEFTANCHORS
for (;;) {
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...
if ((next = NextState()) != goStart)
break; // LOOP EXIT HERE...
GetCode();
}
#else // !LEFTANCHORS
state = currentStart;
while ((next = NextState()) == goStart) {
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();
GetCode();
while ((next = NextState()) > eofNum) // Exit for goStart AND for eofNum
#if BACKUP
bool contextSaved = false;
while ((next = NextState()) > eofNum) { // Exit for goStart AND for eofNum
if (state <= maxAccept && next > maxAccept) { // need to prepare backup data
// Store data for the *latest* accept state that was found.
SaveStateAndPos( ref ctx );
contextSaved = true;
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;
}
state = next;
GetCode();
}
if (state > maxAccept && contextSaved)
RestoreStateAndPos( ref ctx );
#else // BACKUP
while ((next = NextState()) > eofNum) { // Exit for goStart AND for eofNum
state = next;
GetCode();
}
else
#endif // BACKUP
if (state <= maxAccept) {
{
state = next;
GetCode();
}
if (state <= maxAccept)
{
MarkEnd();
#region ActionSwitch
#pragma warning disable 162, 1522
#pragma warning disable 162
switch (state)
{
case eofNum:
......@@ -655,15 +654,36 @@ int res = ScannerHelper.GetIDToken(yytext);
return (int)Tokens.SEMICOLON;
break;
case 6:
return (int)Tokens.ASSIGN;
return (int)Tokens.LEFT_BRACKET;
break;
case 7:
return (int)Tokens.RIGHT_BRACKET;
break;
case 8:
return (int)Tokens.COMMA;
break;
case 9:
return (int)Tokens.PLUS;
break;
case 10:
return (int)Tokens.MINUS;
break;
case 11:
return (int)Tokens.MULT;
break;
case 12:
return (int)Tokens.DIVISION;
break;
case 13:
return (int)Tokens.ASSIGN;
break;
case 14:
return (int)Tokens.RNUM;
break;
default:
break;
}
#pragma warning restore 162, 1522
#pragma warning restore 162
#endregion
}
}
......@@ -676,7 +696,29 @@ yylloc = new LexLocation(tokLin, tokCol, tokELin, tokECol);
}
#if BACKUP
void SaveStateAndPos(ref Context ctx) {
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;
......@@ -685,7 +727,8 @@ yylloc = new LexLocation(tokLin, tokCol, tokELin, tokECol);
ctx.cChr = code;
}
void RestoreStateAndPos(ref Context ctx) {
void RestoreStateAndPos(ref Context ctx)
{
buffer.Pos = ctx.bPos;
readPos = ctx.rPos;
cCol = ctx.cCol;
......@@ -693,7 +736,8 @@ yylloc = new LexLocation(tokLin, tokCol, tokELin, tokECol);
state = ctx.state;
code = ctx.cChr;
}
#endif // BACKUP
#endif // BACKUP
// ============= End of the tokenizer code ================
......@@ -725,16 +769,16 @@ yylloc = new LexLocation(tokLin, tokCol, tokELin, tokECol);
#region UserCodeSection
public override void yyerror(string format, params object[] args) // îáðàáîòêà ñèíòàêñè÷åñêèõ îøèáîê
public override void yyerror(string format, params object[] args) //
{
var ww = args.Skip(1).Cast<string>().ToArray();
string errorMsg = string.Format("({0},{1}): Âñòðå÷åíî {2}, à îæèäàëîñü {3}", yyline, yycol, args[0], string.Join(" èëè ", ww));
string errorMsg = string.Format("({0},{1}): {2}, {3}", yyline, yycol, args[0], string.Join(" ", ww));
throw new SyntaxException(errorMsg);
}
public void LexError()
{
string errorMsg = string.Format("({0},{1}): Íåèçâåñòíûé ñèìâîë {2}", yyline, yycol, yytext);
string errorMsg = string.Format("({0},{1}): {2}", yyline, yycol, yytext);
throw new LexException(errorMsg);
}
......@@ -748,10 +792,21 @@ class ScannerHelper
keywords.Add("begin",(int)Tokens.BEGIN);
keywords.Add("end",(int)Tokens.END);
keywords.Add("cycle",(int)Tokens.CYCLE);
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("if",(int)Tokens.IF);
keywords.Add("then",(int)Tokens.THEN);
keywords.Add("else",(int)Tokens.ELSE);
keywords.Add("write",(int)Tokens.WRITE);
keywords.Add("var",(int)Tokens.VAR);
}
public static int GetIDToken(string s)
{
if (keywords.ContainsKey(s.ToLower())) // ÿçûê íå÷óâñòâèòåëåí ê ðåãèñòðó
if (keywords.ContainsKey(s.ToLower())) //
return keywords[s];
else
return (int)Tokens.ID;
......@@ -807,7 +862,6 @@ class ScannerHelper
return new LineBuffer(source);
}
#if (!NOFILES)
public static ScanBuff GetBuffer(Stream source)
{
return new BuildBuffer(source);
......@@ -818,8 +872,7 @@ class ScannerHelper
{
return new BuildBuffer(source, fallbackCodePage);
}
#endif // !BYTEMODE
#endif // !NOFILES
#endif
}
#region Buffer classes
......@@ -942,7 +995,7 @@ class ScannerHelper
{
ix = lstart = 0;
}
while (ix < numLines)
for (; ; )
{
int len = line[ix].Length + 1;
if (pos < lstart + len) break;
......@@ -1000,8 +1053,7 @@ class ScannerHelper
{
cPos = value;
findIndex(cPos, out cLine, out curLineStart);
// cLine should be the *next* line after curLine.
curLine = (cLine < numLines ? line[cLine++] : "");
curLine = line[cLine];
curLineEnd = curLineStart + curLine.Length;
}
}
......@@ -1009,7 +1061,7 @@ class ScannerHelper
public override string ToString() { return "LineBuffer"; }
}
#if (!NOFILES)
// ==============================================================
// ===== class BuildBuff : for unicode text files ========
// ==============================================================
......@@ -1250,13 +1302,12 @@ class ScannerHelper
}
#endif // !BYTEMODE
}
#endif // !NOFILES
#endregion Buffer classes
// ==============================================================
// ============ class CodePageHandling =============
// ==============================================================
#if (!NOFILES)
public static class CodePageHandling
{
public static int GetCodePage(string option)
......@@ -1467,7 +1518,6 @@ class ScannerHelper
#endif // !BYTEMODE
#endregion
#endif // !NOFILES
// End of code copied from embedded resource
......
......@@ -28,6 +28,13 @@ ID {Alpha}{AlphaDigit}*
":=" { return (int)Tokens.ASSIGN; }
";" { return (int)Tokens.SEMICOLON; }
"(" { return (int)Tokens.LEFT_BRACKET; }
")" { return (int)Tokens.RIGHT_BRACKET; }
"," { return (int)Tokens.COMMA; }
"+" { return (int)Tokens.PLUS; }
"-" { return (int)Tokens.MINUS; }
"*" { return (int)Tokens.MULT; }
"/" { return (int)Tokens.DIVISION; }
[^ \r\n] {
LexError();
......@@ -63,6 +70,17 @@ class ScannerHelper
keywords.Add("begin",(int)Tokens.BEGIN);
keywords.Add("end",(int)Tokens.END);
keywords.Add("cycle",(int)Tokens.CYCLE);
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("if",(int)Tokens.IF);
keywords.Add("then",(int)Tokens.THEN);
keywords.Add("else",(int)Tokens.ELSE);
keywords.Add("write",(int)Tokens.WRITE);
keywords.Add("var",(int)Tokens.VAR);
}
public static int GetIDToken(string s)
{
......
// This code was generated by the Gardens Point Parser Generator
// Copyright (c) Wayne Kelly, John Gough, QUT 2005-2014
// Copyright (c) Wayne Kelly, QUT 2005-2010
// (see accompanying GPPGcopyright.rtf)
// GPPG version 1.5.2
// Machine: MAINHOMEPC2
// DateTime: 30.09.2018 18:11:19
// UserName: someone
// Input file <SimpleYacc.y - 24.09.2018 23:47:02>
// GPPG version 1.3.6
// Machine: LAPTOP-COHFJ4CB
// DateTime: 24.10.2022 13:31:30
// UserName: Acer
// Input file <SimpleYacc.y>
// options: no-lines gplex
using System;
using System.Collections.Generic;
using System.CodeDom.Compiler;
using System.Globalization;
using System.Text;
using QUT.Gppg;
namespace SimpleParser
{
public enum Tokens {error=2,EOF=3,BEGIN=4,END=5,CYCLE=6,
INUM=7,RNUM=8,ID=9,ASSIGN=10,SEMICOLON=11};
public enum Tokens {
error=1,EOF=2,BEGIN=3,END=4,CYCLE=5,INUM=6,
RNUM=7,ID=8,ASSIGN=9,SEMICOLON=10,WHILE=11,DO=12,
REPEAT=13,UNTIL=14,FOR=15,TO=16,IF=17,THEN=18,
ELSE=19,WRITE=20,LEFT_BRACKET=21,RIGHT_BRACKET=22,VAR=23,COMMA=24,
PLUS=25,MINUS=26,MULT=27,DIVISION=28};
// Abstract base class for GPLEX scanners
[GeneratedCodeAttribute( "Gardens Point Parser Generator", "1.5.2")]
public abstract class ScanBase : AbstractScanner<int,LexLocation> {
private LexLocation __yylloc = new LexLocation();
public override LexLocation yylloc { get { return __yylloc; } set { __yylloc = value; } }
protected virtual bool yywrap() { return true; }
}
// Utility class for encapsulating token information
[GeneratedCodeAttribute( "Gardens Point Parser Generator", "1.5.2")]
public class ScanObj {
public int token;
public int yylval;
public LexLocation yylloc;
public ScanObj( int t, int val, LexLocation loc ) {
this.token = t; this.yylval = val; this.yylloc = loc;
}
}
[GeneratedCodeAttribute( "Gardens Point Parser Generator", "1.5.2")]
public class Parser: ShiftReduceParser<int, LexLocation>
{
// Verbatim content from SimpleYacc.y - 24.09.2018 23:47:02
// Ýòè îáúÿâëåíèÿ äîáàâëÿþòñÿ â êëàññ GPPGParser, ïðåäñòàâëÿþùèé ñîáîé ïàðñåð, ãåíåðèðóåìûé ñèñòåìîé gppg
// Verbatim content from SimpleYacc.y
// Ýòè îáúÿâëåíèÿ äîáàâëÿþòñÿ â êëàññ GPPGParser, ïðåäñòàâëÿþùèé ñîáîé ïàðñåð, ãåíåðèðóåìûé ñèñòåìîé gppg
public Parser(AbstractScanner<int, LexLocation> scanner) : base(scanner) { }
// End verbatim content from SimpleYacc.y - 24.09.2018 23:47:02
// End verbatim content from SimpleYacc.y
#pragma warning disable 649
private static Dictionary<int, string> aliases;
private static Dictionary<int, string> aliasses;
#pragma warning restore 649
private static Rule[] rules = new Rule[14];
private static State[] states = new State[22];
private static Rule[] rules = new Rule[38];
private static State[] states = new State[74];
private static string[] nonTerms = new string[] {
"progr", "$accept", "block", "stlist", "statement", "assign", "cycle",
"ident", "expr", };
"progr", "$accept", "block", "stlist", "statement", "idlist", "ident",
"assign", "cycle", "while", "repeat", "for", "if", "write", "var", "expr",
"T", "F", };
static Parser() {
states[0] = new State(new int[]{4,4},new int[]{-1,1,-3,3});
states[1] = new State(new int[]{3,2});
states[0] = new State(new int[]{3,4},new int[]{-1,1,-3,3});
states[1] = new State(new int[]{2,2});
states[2] = new State(-1);
states[3] = new State(-2);
states[4] = new State(new int[]{9,14,4,4,6,18},new int[]{-4,5,-5,21,-6,9,-8,10,-3,16,-7,17});
states[5] = new State(new int[]{5,6,11,7});
states[6] = new State(-12);
states[7] = new State(new int[]{9,14,4,4,6,18},new int[]{-5,8,-6,9,-8,10,-3,16,-7,17});
states[4] = new State(new int[]{8,18,3,4,5,33,11,37,13,42,15,48,17,57,20,64,23,69},new int[]{-4,5,-5,46,-8,9,-7,10,-3,31,-9,32,-10,36,-11,41,-12,47,-13,56,-14,63,-15,68});
states[5] = new State(new int[]{4,6,10,7});
states[6] = new State(-20);
states[7] = new State(new int[]{8,18,3,4,5,33,11,37,13,42,15,48,17,57,20,64,23,69},new int[]{-5,8,-8,9,-7,10,-3,31,-9,32,-10,36,-11,41,-12,47,-13,56,-14,63,-15,68});
states[8] = new State(-4);
states[9] = new State(-5);
states[10] = new State(new int[]{10,11});
states[11] = new State(new int[]{9,14,7,15},new int[]{-9,12,-8,13});
states[12] = new State(-9);
states[13] = new State(-10);
states[14] = new State(-8);
states[15] = new State(-11);
states[16] = new State(-6);
states[17] = new State(-7);
states[18] = new State(new int[]{9,14,7,15},new int[]{-9,19,-8,13});
states[19] = new State(new int[]{9,14,4,4,6,18},new int[]{-5,20,-6,9,-8,10,-3,16,-7,17});
states[20] = new State(-13);
states[21] = new State(-3);
for (int sNo = 0; sNo < states.Length; sNo++) states[sNo].number = sNo;
states[9] = new State(-7);
states[10] = new State(new int[]{9,11});
states[11] = new State(new int[]{8,18,6,29,21,20},new int[]{-16,12,-7,28,-17,30,-18,27});
states[12] = new State(new int[]{25,13,26,23,4,-17,10,-17,14,-17,19,-17});
states[13] = new State(new int[]{8,18,6,19,21,20},new int[]{-17,14,-18,27,-7,17});
states[14] = new State(new int[]{27,15,28,25,25,-30,26,-30,4,-30,10,-30,14,-30,19,-30,22,-30,8,-30,3,-30,5,-30,11,-30,13,-30,15,-30,17,-30,20,-30,23,-30,12,-30,16,-30,18,-30});
states[15] = new State(new int[]{8,18,6,19,21,20},new int[]{-18,16,-7,17});
states[16] = new State(-33);
states[17] = new State(-35);
states[18] = new State(-16);
states[19] = new State(-36);
states[20] = new State(new int[]{8,18,6,29,21,20},new int[]{-16,21,-7,28,-17,30,-18,27});
states[21] = new State(new int[]{22,22,25,13,26,23});
states[22] = new State(-37);
states[23] = new State(new int[]{8,18,6,19,21,20},new int[]{-17,24,-18,27,-7,17});
states[24] = new State(new int[]{27,15,28,25,25,-31,26,-31,4,-31,10,-31,14,-31,19,-31,22,-31,8,-31,3,-31,5,-31,11,-31,13,-31,15,-31,17,-31,20,-31,23,-31,12,-31,16,-31,18,-31});
states[25] = new State(new int[]{8,18,6,19,21,20},new int[]{-18,26,-7,17});
states[26] = new State(-34);
states[27] = new State(-32);
states[28] = new State(new int[]{25,-18,26,-18,4,-18,10,-18,14,-18,19,-18,22,-18,8,-18,3,-18,5,-18,11,-18,13,-18,15,-18,17,-18,20,-18,23,-18,12,-18,16,-18,18,-18,27,-35,28,-35});
states[29] = new State(new int[]{25,-19,26,-19,4,-19,10,-19,14,-19,19,-19,22,-19,8,-19,3,-19,5,-19,11,-19,13,-19,15,-19,17,-19,20,-19,23,-19,12,-19,16,-19,18,-19,27,-36,28,-36});
states[30] = new State(new int[]{27,15,28,25,25,-29,26,-29,4,-29,10,-29,14,-29,19,-29,22,-29,8,-29,3,-29,5,-29,11,-29,13,-29,15,-29,17,-29,20,-29,23,-29,12,-29,16,-29,18,-29});
states[31] = new State(-8);
states[32] = new State(-9);
states[33] = new State(new int[]{8,18,6,29,21,20},new int[]{-16,34,-7,28,-17,30,-18,27});
states[34] = new State(new int[]{25,13,26,23,8,18,3,4,5,33,11,37,13,42,15,48,17,57,20,64,23,69},new int[]{-5,35,-8,9,-7,10,-3,31,-9,32,-10,36,-11,41,-12,47,-13,56,-14,63,-15,68});
states[35] = new State(-21);
states[36] = new State(-10);
states[37] = new State(new int[]{8,18,6,29,21,20},new int[]{-16,38,-7,28,-17,30,-18,27});
states[38] = new State(new int[]{12,39,25,13,26,23});
states[39] = new State(new int[]{8,18,3,4,5,33,11,37,13,42,15,48,17,57,20,64,23,69},new int[]{-5,40,-8,9,-7,10,-3,31,-9,32,-10,36,-11,41,-12,47,-13,56,-14,63,-15,68});
states[40] = new State(-22);
states[41] = new State(-11);
states[42] = new State(new int[]{8,18,3,4,5,33,11,37,13,42,15,48,17,57,20,64,23,69},new int[]{-4,43,-5,46,-8,9,-7,10,-3,31,-9,32,-10,36,-11,41,-12,47,-13,56,-14,63,-15,68});
states[43] = new State(new int[]{14,44,10,7});
states[44] = new State(new int[]{8,18,6,29,21,20},new int[]{-16,45,-7,28,-17,30,-18,27});
states[45] = new State(new int[]{25,13,26,23,4,-23,10,-23,14,-23,19,-23});
states[46] = new State(-3);
states[47] = new State(-12);
states[48] = new State(new int[]{8,18},new int[]{-7,49});
states[49] = new State(new int[]{9,50});
states[50] = new State(new int[]{8,18,6,29,21,20},new int[]{-16,51,-7,28,-17,30,-18,27});
states[51] = new State(new int[]{16,52,25,13,26,23});
states[52] = new State(new int[]{8,18,6,29,21,20},new int[]{-16,53,-7,28,-17,30,-18,27});
states[53] = new State(new int[]{12,54,25,13,26,23});
states[54] = new State(new int[]{8,18,3,4,5,33,11,37,13,42,15,48,17,57,20,64,23,69},new int[]{-5,55,-8,9,-7,10,-3,31,-9,32,-10,36,-11,41,-12,47,-13,56,-14,63,-15,68});
states[55] = new State(-24);
states[56] = new State(-13);
states[57] = new State(new int[]{8,18,6,29,21,20},new int[]{-16,58,-7,28,-17,30,-18,27});
states[58] = new State(new int[]{18,59,25,13,26,23});
states[59] = new State(new int[]{8,18,3,4,5,33,11,37,13,42,15,48,17,57,20,64,23,69},new int[]{-5,60,-8,9,-7,10,-3,31,-9,32,-10,36,-11,41,-12,47,-13,56,-14,63,-15,68});
states[60] = new State(new int[]{19,61,4,-25,10,-25,14,-25});
states[61] = new State(new int[]{8,18,3,4,5,33,11,37,13,42,15,48,17,57,20,64,23,69},new int[]{-5,62,-8,9,-7,10,-3,31,-9,32,-10,36,-11,41,-12,47,-13,56,-14,63,-15,68});
states[62] = new State(-26);
states[63] = new State(-14);
states[64] = new State(new int[]{21,65});
states[65] = new State(new int[]{8,18,6,29,21,20},new int[]{-16,66,-7,28,-17,30,-18,27});
states[66] = new State(new int[]{22,67,25,13,26,23});
states[67] = new State(-27);
states[68] = new State(-15);
states[69] = new State(new int[]{8,18},new int[]{-6,70,-7,73});
states[70] = new State(new int[]{24,71,4,-28,10,-28,14,-28,19,-28});
states[71] = new State(new int[]{8,18},new int[]{-7,72});
states[72] = new State(-6);
states[73] = new State(-5);
rules[1] = new Rule(-2, new int[]{-1,3});
rules[1] = new Rule(-2, new int[]{-1,2});
rules[2] = new Rule(-1, new int[]{-3});
rules[3] = new Rule(-4, new int[]{-5});
rules[4] = new Rule(-4, new int[]{-4,11,-5});
rules[5] = new Rule(-5, new int[]{-6});
rules[6] = new Rule(-5, new int[]{-3});
rules[7] = new Rule(-5, new int[]{-7});
rules[8] = new Rule(-8, new int[]{9});
rules[9] = new Rule(-6, new int[]{-8,10,-9});
rules[10] = new Rule(-9, new int[]{-8});
rules[11] = new Rule(-9, new int[]{7});
rules[12] = new Rule(-3, new int[]{4,-4,5});
rules[13] = new Rule(-7, new int[]{6,-9,-5});
rules[4] = new Rule(-4, new int[]{-4,10,-5});
rules[5] = new Rule(-6, new int[]{-7});
rules[6] = new Rule(-6, new int[]{-6,24,-7});
rules[7] = new Rule(-5, new int[]{-8});
rules[8] = new Rule(-5, new int[]{-3});
rules[9] = new Rule(-5, new int[]{-9});
rules[10] = new Rule(-5, new int[]{-10});
rules[11] = new Rule(-5, new int[]{-11});
rules[12] = new Rule(-5, new int[]{-12});
rules[13] = new Rule(-5, new int[]{-13});
rules[14] = new Rule(-5, new int[]{-14});
rules[15] = new Rule(-5, new int[]{-15});
rules[16] = new Rule(-7, new int[]{8});
rules[17] = new Rule(-8, new int[]{-7,9,-16});
rules[18] = new Rule(-16, new int[]{-7});
rules[19] = new Rule(-16, new int[]{6});
rules[20] = new Rule(-3, new int[]{3,-4,4});
rules[21] = new Rule(-9, new int[]{5,-16,-5});
rules[22] = new Rule(-10, new int[]{11,-16,12,-5});
rules[23] = new Rule(-11, new int[]{13,-4,14,-16});
rules[24] = new Rule(-12, new int[]{15,-7,9,-16,16,-16,12,-5});
rules[25] = new Rule(-13, new int[]{17,-16,18,-5});
rules[26] = new Rule(-13, new int[]{17,-16,18,-5,19,-5});
rules[27] = new Rule(-14, new int[]{20,21,-16,22});
rules[28] = new Rule(-15, new int[]{23,-6});
rules[29] = new Rule(-16, new int[]{-17});
rules[30] = new Rule(-16, new int[]{-16,25,-17});
rules[31] = new Rule(-16, new int[]{-16,26,-17});
rules[32] = new Rule(-17, new int[]{-18});
rules[33] = new Rule(-17, new int[]{-17,27,-18});
rules[34] = new Rule(-17, new int[]{-17,28,-18});
rules[35] = new Rule(-18, new int[]{-7});
rules[36] = new Rule(-18, new int[]{6});
rules[37] = new Rule(-18, new int[]{21,-16,22});
}
protected override void Initialize() {
......@@ -108,17 +173,15 @@ public class Parser: ShiftReduceParser<int, LexLocation>
protected override void DoAction(int action)
{
#pragma warning disable 162, 1522
switch (action)
{
}
#pragma warning restore 162, 1522
}
protected override string TerminalToString(int terminal)
{
if (aliases != null && aliases.ContainsKey(terminal))
return aliases[terminal];
if (aliasses != null && aliasses.ContainsKey(terminal))
return aliasses[terminal];
else if (((Tokens)terminal).ToString() != terminal.ToString(CultureInfo.InvariantCulture))
return ((Tokens)terminal).ToString();
else
......
......@@ -7,7 +7,7 @@
%namespace SimpleParser
%token BEGIN END CYCLE INUM RNUM ID ASSIGN SEMICOLON
%token BEGIN END CYCLE INUM RNUM ID ASSIGN SEMICOLON WHILE DO REPEAT UNTIL FOR TO IF THEN ELSE WRITE LEFT_BRACKET RIGHT_BRACKET VAR COMMA PLUS MINUS MULT DIVISION
%%
......@@ -18,9 +18,19 @@ stlist : statement
| stlist SEMICOLON statement
;
idlist : ident
| idlist COMMA ident
;
statement: assign
| block
| cycle
| cycle
| while
| repeat
| for
| if
| write
| var
;
ident : ID
......@@ -39,4 +49,38 @@ block : BEGIN stlist END
cycle : CYCLE expr statement
;
while : WHILE expr DO statement
;
repeat : REPEAT stlist UNTIL expr
;
for : FOR ident ASSIGN expr TO expr DO statement
;
if : IF expr THEN statement
| IF expr THEN statement ELSE statement
;
write : WRITE LEFT_BRACKET expr RIGHT_BRACKET
;
var : VAR idlist
;
expr : T
| expr PLUS T
| expr MINUS T
;
T : F
| T MULT F
| T DIVISION F
;
F : ident
| INUM
| LEFT_BRACKET expr RIGHT_BRACKET
;
%%
......@@ -65,4 +65,125 @@ namespace ProgramTree
}
}
public class WhileNode : StatementNode
{
public ExprNode Expr { get; set; }
public StatementNode Stat { get; set; }
public WhileNode(ExprNode expr, StatementNode stat)
{
Expr = expr;
Stat = stat;
}
}
public class RepeatNode : StatementNode
{
public List<StatementNode> StList = new List<StatementNode>();
public ExprNode Expr { get; set; }
public RepeatNode(StatementNode stat,ExprNode expr)
{
Add(stat);
Expr = expr;
}
public void Add(StatementNode stat)
{
StList.Add(stat);
}
}
public class ForNode : StatementNode
{
public ExprNode Expr1 { get; set; }
public ExprNode Expr2 { get; set; }
public StatementNode Stat { get; set; }
public ForNode(ExprNode expr1, ExprNode expr2, StatementNode stat)
{
Expr1 = expr1;
Expr2 = expr2;
Stat = stat;
}
}
public class WriteNode : StatementNode
{
public ExprNode Expr { get; set; }
public WriteNode(ExprNode expr)
{
Expr = expr;
}
}
public class IfNode : StatementNode
{
public ExprNode Expr { get; set; }
public StatementNode Stat1 { get; set; }
public IfNode(ExprNode expr, StatementNode stat1)
{
Expr = expr;
Stat1 = stat1;
}
}
public class IfFullNode : StatementNode
{
public ExprNode Expr { get; set; }
public StatementNode Stat1 { get; set; }
public StatementNode Stat2 { get; set; }
public IfFullNode(ExprNode expr, StatementNode stat1, StatementNode stat2)
{
Expr = expr;
Stat1 = stat1;
Stat2 = stat2;
}
}
public class VarDefNode : StatementNode
{
public List<IdNode> IdList = new List<IdNode>();
public VarDefNode(IdNode id)
{
Add(id);
}
public void Add(IdNode id)
{
IdList.Add(id);
}
}
public class OpNode : Node
{
public string Op { get; set; }
public OpNode(string op)
{
Op = op;
}
}
public class BinaryNode : ExprNode
{
public ExprNode Left { get; set; }
public ExprNode Right { get; set; }
public OpNode Op { get; set; }
public BinaryNode(ExprNode left, ExprNode right, OpNode op)
{
Left = left;
Right = right;
Op = op;
}
}
}
\ No newline at end of file
//
// This CSharp output file generated by Gardens Point LEX
// Gardens Point LEX (GPLEX) is Copyright (c) John Gough, QUT 2006-2014.
// Output produced by GPLEX is the property of the user.
// See accompanying file GPLEXcopyright.rtf.
//
// GPLEX Version: 1.2.2
// Machine: MAINHOMEPC2
// DateTime: 30.09.2018 18:14:30
// UserName: someone
// GPLEX input file <SimpleLex.lex - 24.09.2018 23:47:03>
// Version: 1.1.3.301
// Machine: LAPTOP-COHFJ4CB
// DateTime: 24.10.2022 16:12:47
// UserName: Acer
// GPLEX input file <SimpleLex.lex>
// GPLEX frame file <embedded resource>
//
// Option settings: unicode, parser, minimize
......@@ -17,8 +13,8 @@
//
//
// Revised backup code
// Version 1.2.1 of 24-June-2013
// Experimental embedded frame
// Version 1.1.3 of 18-April-2010
//
//
#define BACKUP
......@@ -127,8 +123,8 @@ namespace SimpleScanner
enum Result {accept, noMatch, contextFound};
const int maxAccept = 7;
const int initial = 8;
const int maxAccept = 14;
const int initial = 15;
const int eofNum = 0;
const int goStart = -1;
const int INITIAL = 0;
......@@ -165,24 +161,24 @@ namespace SimpleScanner
}
};
static int[] startState = new int[] {8, 0};
static int[] startState = new int[] {15, 0};
#region CompressedCharacterMap
//
// There are 8 equivalence classes
// There are 15 equivalence classes
// There are 2 character sequence regions
// There are 1 tables, 123 entries
// There are 1 runs, 0 singletons
// Decision tree depth is 1
//
static sbyte[] mapC0 = new sbyte[123] {
/* '\0' */ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 7, 7, 0, 7, 7,
/* '\x10' */ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
/* '\x20' */ 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 2, 7,
/* '0' */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 4, 6, 7, 5, 7, 7,
/* '@' */ 7, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
/* 'P' */ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 7, 7, 7, 7, 3,
/* '`' */ 7, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
/* '\0' */ 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 0, 14, 14, 0, 14, 14,
/* '\x10' */ 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
/* '\x20' */ 0, 14, 14, 14, 14, 14, 14, 14, 7, 8, 12, 10, 9, 11, 2, 13,
/* '0' */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 4, 6, 14, 5, 14, 14,
/* '@' */ 14, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
/* 'P' */ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 14, 14, 14, 14, 3,
/* '`' */ 14, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
/* 'p' */ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 };
static sbyte MapC(int code)
......@@ -190,22 +186,29 @@ namespace SimpleScanner
if (code < 123) // '\0' <= code <= 'z'
return mapC0[code - 0];
else // '{' <= code <= '\U0010FFFF'
return (sbyte)7;
return (sbyte)14;
}
#endregion
static Table[] NxS = new Table[10] {
static Table[] NxS = new Table[17] {
/* NxS[ 0] */ new Table(0, 0, 0, null),
/* NxS[ 1] */ new Table(1, 2, -1, new sbyte[] {1, 9}),
/* NxS[ 1] */ new Table(1, 2, -1, new sbyte[] {1, 16}),
/* NxS[ 2] */ new Table(0, 0, -1, null),
/* NxS[ 3] */ new Table(1, 3, -1, new sbyte[] {3, -1, 3}),
/* NxS[ 4] */ new Table(5, 1, -1, new sbyte[] {6}),
/* NxS[ 4] */ new Table(5, 1, -1, new sbyte[] {13}),
/* NxS[ 5] */ new Table(0, 0, -1, null),
/* NxS[ 6] */ new Table(0, 0, -1, null),
/* NxS[ 7] */ new Table(1, 1, -1, new sbyte[] {7}),
/* NxS[ 8] */ new Table(1, 7, -1, new sbyte[] {1, 2, 3, 4, 2, 5,
2}),
/* NxS[ 9] */ new Table(1, 1, -1, new sbyte[] {7}),
/* NxS[ 7] */ new Table(0, 0, -1, null),
/* NxS[ 8] */ new Table(0, 0, -1, null),
/* NxS[ 9] */ new Table(0, 0, -1, null),
/* NxS[ 10] */ new Table(0, 0, -1, null),
/* NxS[ 11] */ new Table(0, 0, -1, null),
/* NxS[ 12] */ new Table(0, 0, -1, null),
/* NxS[ 13] */ new Table(0, 0, -1, null),
/* NxS[ 14] */ new Table(1, 1, -1, new sbyte[] {14}),
/* NxS[ 15] */ new Table(1, 14, -1, new sbyte[] {1, 2, 3, 4, 2, 5,
6, 7, 8, 9, 10, 11, 12, 2}),
/* NxS[ 16] */ new Table(1, 1, -1, new sbyte[] {14}),
};
int NextState() {
......@@ -215,7 +218,7 @@ int NextState() {
unchecked {
int rslt;
int idx = MapC(code) - NxS[state].min;
if (idx < 0) idx += 8;
if (idx < 0) idx += 15;
if ((uint)idx >= (uint)NxS[state].rng) rslt = NxS[state].dflt;
else rslt = NxS[state].nxt[idx];
return rslt;
......@@ -295,7 +298,8 @@ int NextState() {
public Scanner(Stream file, string codepage) {
SetSource(file, CodePageHandling.GetCodePage(codepage));
}
}
#endif // !NOFILES
public Scanner() { }
......@@ -323,7 +327,7 @@ int NextState() {
if (next < 0xDC00 || next > 0xDFFF)
code = ScanBuff.UnicodeReplacementChar;
else
code = (0x10000 + ((code & 0x3FF) << 10) + (next & 0x3FF));
code = (0x10000 + (code & 0x3FF << 10) + (next & 0x3FF));
}
#endif
cCol++;
......@@ -376,7 +380,9 @@ int NextState() {
GetCode();
}
#if !NOFILES
// ================ LineBuffer Initialization ===================
/// <summary>
/// Create and initialize a LineBuff buffer object for this scanner
/// </summary>
......@@ -390,7 +396,6 @@ int NextState() {
GetCode();
}
#if !NOFILES
// =============== StreamBuffer Initialization ==================
/// <summary>
......@@ -492,12 +497,6 @@ int NextState() {
}
}
/// <summary>
/// Discards all but the first "n" codepoints in the recognized pattern.
/// Resets the buffer position so that only n codepoints have been consumed;
/// yytext is also re-evaluated.
/// </summary>
/// <param name="n">The number of codepoints to consume</param>
[SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
void yyless(int n)
{
......@@ -517,10 +516,6 @@ int NextState() {
// but it does not seem possible to re-establish
// the correct column counts except by going forward.
//
/// <summary>
/// Removes the last "n" code points from the pattern.
/// </summary>
/// <param name="n">The number to remove</param>
[SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
void _yytrunc(int n) { yyless(yyleng - n); }
......@@ -533,23 +528,18 @@ int NextState() {
// can't use (tokEPos - tokPos) because of the
// possibility of surrogate pairs in the token.
//
/// <summary>
/// The length of the pattern in codepoints (not the same as
/// string-length if the pattern contains any surrogate pairs).
/// </summary>
[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
#if BYTEMODE
return tokEPos - tokPos;
#else
{
else {
int ch;
int count = 0;
int save = buffer.Pos;
......@@ -558,7 +548,7 @@ int NextState() {
ch = buffer.Read();
if (!char.IsHighSurrogate((char)ch)) count++;
} while (buffer.Pos < tokEPos && ch != ScanBuff.EndOfFile);
buffer.Pos = save;
buffer.Pos = save;
return count;
}
#endif // BYTEMODE
......@@ -583,56 +573,65 @@ int NextState() {
// ============== The main tokenizer code =================
int Scan() {
int Scan()
{
try {
for (; ; ) {
int next; // next state to enter
for (; ; )
{
int next; // next state to enter
#if BACKUP
Result rslt = Result.noMatch;
#endif // BACKUP
#if LEFTANCHORS
for (;;) {
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...
if ((next = NextState()) != goStart)
break; // LOOP EXIT HERE...
GetCode();
}
#else // !LEFTANCHORS
state = currentStart;
while ((next = NextState()) == goStart) {
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();
GetCode();
while ((next = NextState()) > eofNum) // Exit for goStart AND for eofNum
#if BACKUP
bool contextSaved = false;
while ((next = NextState()) > eofNum) { // Exit for goStart AND for eofNum
if (state <= maxAccept && next > maxAccept) { // need to prepare backup data
// Store data for the *latest* accept state that was found.
SaveStateAndPos( ref ctx );
contextSaved = true;
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;
}
state = next;
GetCode();
}
if (state > maxAccept && contextSaved)
RestoreStateAndPos( ref ctx );
#else // BACKUP
while ((next = NextState()) > eofNum) { // Exit for goStart AND for eofNum
state = next;
GetCode();
}
else
#endif // BACKUP
if (state <= maxAccept) {
{
state = next;
GetCode();
}
if (state <= maxAccept)
{
MarkEnd();
#region ActionSwitch
#pragma warning disable 162, 1522
#pragma warning disable 162
switch (state)
{
case eofNum:
......@@ -657,16 +656,37 @@ int res = ScannerHelper.GetIDToken(yytext);
return (int)Tokens.SEMICOLON;
break;
case 6:
return (int)Tokens.ASSIGN;
return (int)Tokens.LEFT_BRACKET;
break;
case 7:
return (int)Tokens.RIGHT_BRACKET;
break;
case 8:
return (int)Tokens.COMMA;
break;
case 9:
return (int)Tokens.PLUS;
break;
case 10:
return (int)Tokens.MINUS;
break;
case 11:
return (int)Tokens.MULT;
break;
case 12:
return (int)Tokens.DIVISION;
break;
case 13:
return (int)Tokens.ASSIGN;
break;
case 14:
yylval.dVal = double.Parse(yytext);
return (int)Tokens.RNUM;
break;
default:
break;
}
#pragma warning restore 162, 1522
#pragma warning restore 162
#endregion
}
}
......@@ -679,7 +699,29 @@ yylloc = new LexLocation(tokLin, tokCol, tokELin, tokECol);
}
#if BACKUP
void SaveStateAndPos(ref Context ctx) {
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;
......@@ -688,7 +730,8 @@ yylloc = new LexLocation(tokLin, tokCol, tokELin, tokECol);
ctx.cChr = code;
}
void RestoreStateAndPos(ref Context ctx) {
void RestoreStateAndPos(ref Context ctx)
{
buffer.Pos = ctx.bPos;
readPos = ctx.rPos;
cCol = ctx.cCol;
......@@ -696,7 +739,8 @@ yylloc = new LexLocation(tokLin, tokCol, tokELin, tokECol);
state = ctx.state;
code = ctx.cChr;
}
#endif // BACKUP
#endif // BACKUP
// ============= End of the tokenizer code ================
......@@ -728,16 +772,16 @@ yylloc = new LexLocation(tokLin, tokCol, tokELin, tokECol);
#region UserCodeSection
public override void yyerror(string format, params object[] args) // îáðàáîòêà ñèíòàêñè÷åñêèõ îøèáîê
public override void yyerror(string format, params object[] args) //
{
var ww = args.Skip(1).Cast<string>().ToArray();
string errorMsg = string.Format("({0},{1}): Âñòðå÷åíî {2}, à îæèäàëîñü {3}", yyline, yycol, args[0], string.Join(" èëè ", ww));
string errorMsg = string.Format("({0},{1}): {2}, {3}", yyline, yycol, args[0], string.Join(" ", ww));
throw new SyntaxException(errorMsg);
}
public void LexError()
{
string errorMsg = string.Format("({0},{1}): Íåèçâåñòíûé ñèìâîë {2}", yyline, yycol, yytext);
string errorMsg = string.Format("({0},{1}): {2}", yyline, yycol, yytext);
throw new LexException(errorMsg);
}
......@@ -751,6 +795,17 @@ class ScannerHelper
keywords.Add("begin",(int)Tokens.BEGIN);
keywords.Add("end",(int)Tokens.END);
keywords.Add("cycle",(int)Tokens.CYCLE);
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("write",(int)Tokens.WRITE);
keywords.Add("if",(int)Tokens.IF);
keywords.Add("then",(int)Tokens.THEN);
keywords.Add("else",(int)Tokens.ELSE);
keywords.Add("var",(int)Tokens.VAR);
}
public static int GetIDToken(string s)
{
......@@ -811,7 +866,6 @@ class ScannerHelper
return new LineBuffer(source);
}
#if (!NOFILES)
public static ScanBuff GetBuffer(Stream source)
{
return new BuildBuffer(source);
......@@ -822,8 +876,7 @@ class ScannerHelper
{
return new BuildBuffer(source, fallbackCodePage);
}
#endif // !BYTEMODE
#endif // !NOFILES
#endif
}
#region Buffer classes
......@@ -946,7 +999,7 @@ class ScannerHelper
{
ix = lstart = 0;
}
while (ix < numLines)
for (; ; )
{
int len = line[ix].Length + 1;
if (pos < lstart + len) break;
......@@ -1004,8 +1057,7 @@ class ScannerHelper
{
cPos = value;
findIndex(cPos, out cLine, out curLineStart);
// cLine should be the *next* line after curLine.
curLine = (cLine < numLines ? line[cLine++] : "");
curLine = line[cLine];
curLineEnd = curLineStart + curLine.Length;
}
}
......@@ -1013,7 +1065,7 @@ class ScannerHelper
public override string ToString() { return "LineBuffer"; }
}
#if (!NOFILES)
// ==============================================================
// ===== class BuildBuff : for unicode text files ========
// ==============================================================
......@@ -1254,13 +1306,12 @@ class ScannerHelper
}
#endif // !BYTEMODE
}
#endif // !NOFILES
#endregion Buffer classes
// ==============================================================
// ============ class CodePageHandling =============
// ==============================================================
#if (!NOFILES)
public static class CodePageHandling
{
public static int GetCodePage(string option)
......@@ -1471,7 +1522,6 @@ class ScannerHelper
#endif // !BYTEMODE
#endregion
#endif // !NOFILES
// End of code copied from embedded resource
......
......@@ -32,6 +32,13 @@ ID {Alpha}{AlphaDigit}*
":=" { return (int)Tokens.ASSIGN; }
";" { return (int)Tokens.SEMICOLON; }
"(" { return (int)Tokens.LEFT_BRACKET; }
")" { return (int)Tokens.RIGHT_BRACKET; }
"," { return (int)Tokens.COMMA; }
"+" { return (int)Tokens.PLUS; }
"-" { return (int)Tokens.MINUS; }
"*" { return (int)Tokens.MULT; }
"/" { return (int)Tokens.DIVISION; }
[^ \r\n] {
LexError();
......@@ -66,6 +73,17 @@ class ScannerHelper
keywords.Add("begin",(int)Tokens.BEGIN);
keywords.Add("end",(int)Tokens.END);
keywords.Add("cycle",(int)Tokens.CYCLE);
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("write",(int)Tokens.WRITE);
keywords.Add("if",(int)Tokens.IF);
keywords.Add("then",(int)Tokens.THEN);
keywords.Add("else",(int)Tokens.ELSE);
keywords.Add("var",(int)Tokens.VAR);
}
public static int GetIDToken(string s)
{
......
This diff is collapsed.
......@@ -14,20 +14,22 @@
public ExprNode eVal;
public StatementNode stVal;
public BlockNode blVal;
public OpNode opVal;
}
%using ProgramTree;
%namespace SimpleParser
%token BEGIN END CYCLE ASSIGN SEMICOLON
%token BEGIN END CYCLE ASSIGN SEMICOLON WHILE DO REPEAT UNTIL FOR TO WRITE LEFT_BRACKET RIGHT_BRACKET IF THEN ELSE VAR COMMA PLUS MINUS MULT DIVISION
%token <iVal> INUM
%token <dVal> RNUM
%token <sVal> ID
%type <eVal> expr ident
%type <stVal> assign statement cycle
%type <eVal> expr ident T F
%type <stVal> assign statement cycle while repeat for write if idlist
%type <blVal> stlist block
%type <opVal> plus minus mult div
%%
......@@ -45,9 +47,26 @@ stlist : statement
}
;
idlist : VAR ident
{
$$ = new VarDefNode($2 as IdNode);
}
| idlist COMMA ident
{
($1 as VarDefNode).Add($3 as IdNode);
$$ = $1;
}
;
statement: assign { $$ = $1; }
| block { $$ = $1; }
| cycle { $$ = $1; }
| while { $$ = $1; }
| repeat { $$ = $1; }
| for { $$ = $1; }
| write { $$ = $1; }
| if { $$ = $1; }
| idlist { $$ = $1; }
;
ident : ID { $$ = new IdNode($1); }
......@@ -65,6 +84,79 @@ block : BEGIN stlist END { $$ = $2; }
cycle : CYCLE expr statement { $$ = new CycleNode($2, $3); }
;
while : WHILE expr DO statement { $$ = new WhileNode($2, $4); }
;
repeat : REPEAT stlist UNTIL expr { $$ = new RepeatNode($2, $4); }
;
for : FOR ID ASSIGN expr TO expr DO statement { $$ = new ForNode($4,$6,$8); }
;
write : WRITE LEFT_BRACKET expr RIGHT_BRACKET { $$ = new WriteNode($3); }
;
if : IF expr THEN statement { $$ = new IfNode($2,$4); }
| IF expr THEN statement ELSE statement { $$ = new IfFullNode($2,$4,$6); }
;
plus : PLUS { $$ = new OpNode($1.ToString()); }
;
minus : MINUS { $$ = new OpNode($1.ToString()); }
;
mult : MULT { $$ = new OpNode($1.ToString()); }
;
div : DIVISION { $$ = new OpNode($1.ToString()); }
;
expr : T
{
$$ = $1;
}
| expr plus T
{
$$ = new BinaryNode($1,$3,$2);
}
| expr minus T
{
$$ = new BinaryNode($1,$3,$2);
}
;
T : F
{
$$ = $1;
}
|
T mult F
{
$$ = new BinaryNode($1,$3,$2);
}
|
T div F
{
$$ = new BinaryNode($1,$3,$2);
}
;
F : ident
{
$$ = $1 as IdNode;
}
|
INUM
{
$$ = new IntNumNode($1);
}
| LEFT_BRACKET expr RIGHT_BRACKET
{
$$ = $2;
}
;
%%
......@@ -20,6 +20,18 @@ namespace ProgramTree
public IdNode(string name) { Name = name; }
public override void Visit(Visitor v)
{
if (v.GetType() == typeof(CommonlyUsedVarVisitor))
{
if (((CommonlyUsedVarVisitor)v).Dict.ContainsKey(Name))
((CommonlyUsedVarVisitor)v).Dict[Name]++;
else
((CommonlyUsedVarVisitor)v).Dict[Name] = 1;
}
else if(v.GetType() == typeof(ChangeVarIdVisitor))
{
if (Name == ((ChangeVarIdVisitor)v).get_from())
Name = ((ChangeVarIdVisitor)v).get_to();
}
v.VisitIdNode(this);
}
}
......@@ -39,14 +51,22 @@ namespace ProgramTree
public ExprNode Left { get; set; }
public ExprNode Right { get; set; }
public char Op { get; set; }
public BinOpNode(ExprNode Left, ExprNode Right, char op)
public BinOpNode(ExprNode Left, ExprNode Right, char Op)
{
this.Left = Left;
this.Right = Right;
this.Op = op;
this.Op = Op;
}
public override void Visit(Visitor v)
{
if (v.GetType() == typeof(ExprComplexityVisitor))
{
if (Op == '+' || Op == '-')
((ExprComplexityVisitor)v).ExprComplexity[((ExprComplexityVisitor)v).ExprComplexity.Count - 1] += 1;
else
if (Op == '*' || Op == '/')
((ExprComplexityVisitor)v).ExprComplexity[((ExprComplexityVisitor)v).ExprComplexity.Count - 1] += 3;
}
v.VisitBinOpNode(this);
}
}
......@@ -68,6 +88,13 @@ namespace ProgramTree
}
public override void Visit(Visitor v)
{
if (v.GetType() == typeof(CountCyclesOpVisitor))
{
if (((CountCyclesOpVisitor)v).InCycle)
((CountCyclesOpVisitor)v).OpCnt++;
}
else if (v.GetType() == typeof(ExprComplexityVisitor))
((ExprComplexityVisitor)v).ExprComplexity.Add(0);
v.VisitAssignNode(this);
}
}
......@@ -83,7 +110,23 @@ namespace ProgramTree
}
public override void Visit(Visitor v)
{
if (v.GetType() == typeof(CountCyclesOpVisitor))
{
((CountCyclesOpVisitor)v).CyclesCnt++;
((CountCyclesOpVisitor)v).InCycle = true;
}
else if (v.GetType() == typeof(ExprComplexityVisitor))
((ExprComplexityVisitor)v).ExprComplexity.Add(0);
else if (v.GetType() == typeof(MaxNestCyclesVisitor))
{
if(Stat.GetType() == typeof(CycleNode))
((MaxNestCyclesVisitor)v).MaxNest++;
}
else if(v.GetType() == typeof(MaxIfCycleNestVisitor))
((MaxIfCycleNestVisitor)v).MaxNest++;
v.VisitCycleNode(this);
if (v.GetType() == typeof(CountCyclesOpVisitor))
((CountCyclesOpVisitor)v).InCycle = false;
}
}
......@@ -100,7 +143,12 @@ namespace ProgramTree
}
public override void Visit(Visitor v)
{
v.VisitBlockNode(this);
if (v.GetType() == typeof(MaxNestCyclesVisitor))
{
if(StList[StList.Count-1].GetType()==typeof(CycleNode))
((MaxNestCyclesVisitor)v).MaxNest++;
}
v.VisitBlockNode(this);
}
}
......@@ -113,6 +161,8 @@ namespace ProgramTree
}
public override void Visit(Visitor v)
{
if (v.GetType() == typeof(ExprComplexityVisitor))
((ExprComplexityVisitor)v).ExprComplexity.Add(0);
v.VisitWriteNode(this);
}
}
......@@ -142,4 +192,28 @@ namespace ProgramTree
v.VisitVarDefNode(this);
}
}
public class IfNode : StatementNode
{
public ExprNode Expr { get; set; }
public StatementNode Stat1 { get; set; }
public StatementNode Stat2 { get; set; }
public IfNode(ExprNode expr, StatementNode stat1)
{
Expr = expr;
Stat1 = stat1;
}
public IfNode(ExprNode expr, StatementNode stat1, StatementNode stat2)
{
Expr = expr;
Stat1 = stat1;
Stat2 = stat2;
}
public override void Visit(Visitor v)
{
if (v.GetType() == typeof(MaxIfCycleNestVisitor))
((MaxIfCycleNestVisitor)v).MaxNest++;
v.VisitIfNode(this);
}
}
}
\ No newline at end of file
//
// This CSharp output file generated by Gardens Point LEX
// Gardens Point LEX (GPLEX) is Copyright (c) John Gough, QUT 2006-2014.
// Output produced by GPLEX is the property of the user.
// See accompanying file GPLEXcopyright.rtf.
//
// GPLEX Version: 1.2.2
// Machine: MAINHOMEPC2
// DateTime: 30.09.2018 18:17:27
// UserName: someone
// GPLEX input file <SimpleLex.lex - 24.09.2018 23:47:03>
// Version: 1.1.3.301
// Machine: LAPTOP-COHFJ4CB
// DateTime: 06.11.2022 19:39:13
// UserName: Acer
// GPLEX input file <SimpleLex.lex>
// GPLEX frame file <embedded resource>
//
// Option settings: unicode, parser, minimize
......@@ -17,8 +13,8 @@
//
//
// Revised backup code
// Version 1.2.1 of 24-June-2013
// Experimental embedded frame
// Version 1.1.3 of 18-April-2010
//
//
#define BACKUP
......@@ -305,7 +301,8 @@ int NextState() {
public Scanner(Stream file, string codepage) {
SetSource(file, CodePageHandling.GetCodePage(codepage));
}
}
#endif // !NOFILES
public Scanner() { }
......@@ -333,7 +330,7 @@ int NextState() {
if (next < 0xDC00 || next > 0xDFFF)
code = ScanBuff.UnicodeReplacementChar;
else
code = (0x10000 + ((code & 0x3FF) << 10) + (next & 0x3FF));
code = (0x10000 + (code & 0x3FF << 10) + (next & 0x3FF));
}
#endif
cCol++;
......@@ -386,7 +383,9 @@ int NextState() {
GetCode();
}
#if !NOFILES
// ================ LineBuffer Initialization ===================
/// <summary>
/// Create and initialize a LineBuff buffer object for this scanner
/// </summary>
......@@ -400,7 +399,6 @@ int NextState() {
GetCode();
}
#if !NOFILES
// =============== StreamBuffer Initialization ==================
/// <summary>
......@@ -502,12 +500,6 @@ int NextState() {
}
}
/// <summary>
/// Discards all but the first "n" codepoints in the recognized pattern.
/// Resets the buffer position so that only n codepoints have been consumed;
/// yytext is also re-evaluated.
/// </summary>
/// <param name="n">The number of codepoints to consume</param>
[SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
void yyless(int n)
{
......@@ -527,10 +519,6 @@ int NextState() {
// but it does not seem possible to re-establish
// the correct column counts except by going forward.
//
/// <summary>
/// Removes the last "n" code points from the pattern.
/// </summary>
/// <param name="n">The number to remove</param>
[SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
void _yytrunc(int n) { yyless(yyleng - n); }
......@@ -543,23 +531,18 @@ int NextState() {
// can't use (tokEPos - tokPos) because of the
// possibility of surrogate pairs in the token.
//
/// <summary>
/// The length of the pattern in codepoints (not the same as
/// string-length if the pattern contains any surrogate pairs).
/// </summary>
[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
#if BYTEMODE
return tokEPos - tokPos;
#else
{
else {
int ch;
int count = 0;
int save = buffer.Pos;
......@@ -568,7 +551,7 @@ int NextState() {
ch = buffer.Read();
if (!char.IsHighSurrogate((char)ch)) count++;
} while (buffer.Pos < tokEPos && ch != ScanBuff.EndOfFile);
buffer.Pos = save;
buffer.Pos = save;
return count;
}
#endif // BYTEMODE
......@@ -593,56 +576,65 @@ int NextState() {
// ============== The main tokenizer code =================
int Scan() {
int Scan()
{
try {
for (; ; ) {
int next; // next state to enter
for (; ; )
{
int next; // next state to enter
#if BACKUP
Result rslt = Result.noMatch;
#endif // BACKUP
#if LEFTANCHORS
for (;;) {
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...
if ((next = NextState()) != goStart)
break; // LOOP EXIT HERE...
GetCode();
}
#else // !LEFTANCHORS
state = currentStart;
while ((next = NextState()) == goStart) {
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();
GetCode();
while ((next = NextState()) > eofNum) // Exit for goStart AND for eofNum
#if BACKUP
bool contextSaved = false;
while ((next = NextState()) > eofNum) { // Exit for goStart AND for eofNum
if (state <= maxAccept && next > maxAccept) { // need to prepare backup data
// Store data for the *latest* accept state that was found.
SaveStateAndPos( ref ctx );
contextSaved = true;
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;
}
state = next;
GetCode();
}
if (state > maxAccept && contextSaved)
RestoreStateAndPos( ref ctx );
#else // BACKUP
while ((next = NextState()) > eofNum) { // Exit for goStart AND for eofNum
state = next;
GetCode();
}
else
#endif // BACKUP
if (state <= maxAccept) {
{
state = next;
GetCode();
}
if (state <= maxAccept)
{
MarkEnd();
#region ActionSwitch
#pragma warning disable 162, 1522
#pragma warning disable 162
switch (state)
{
case eofNum:
......@@ -706,7 +698,7 @@ yylval.dVal = double.Parse(yytext);
default:
break;
}
#pragma warning restore 162, 1522
#pragma warning restore 162
#endregion
}
}
......@@ -719,7 +711,29 @@ yylloc = new LexLocation(tokLin, tokCol, tokELin, tokECol);
}
#if BACKUP
void SaveStateAndPos(ref Context ctx) {
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;
......@@ -728,7 +742,8 @@ yylloc = new LexLocation(tokLin, tokCol, tokELin, tokECol);
ctx.cChr = code;
}
void RestoreStateAndPos(ref Context ctx) {
void RestoreStateAndPos(ref Context ctx)
{
buffer.Pos = ctx.bPos;
readPos = ctx.rPos;
cCol = ctx.cCol;
......@@ -736,7 +751,8 @@ yylloc = new LexLocation(tokLin, tokCol, tokELin, tokECol);
state = ctx.state;
code = ctx.cChr;
}
#endif // BACKUP
#endif // BACKUP
// ============= End of the tokenizer code ================
......@@ -768,16 +784,16 @@ yylloc = new LexLocation(tokLin, tokCol, tokELin, tokECol);
#region UserCodeSection
public override void yyerror(string format, params object[] args) // îáðàáîòêà ñèíòàêñè÷åñêèõ îøèáîê
public override void yyerror(string format, params object[] args) //
{
var ww = args.Skip(1).Cast<string>().ToArray();
string errorMsg = string.Format("({0},{1}): Âñòðå÷åíî {2}, à îæèäàëîñü {3}", yyline, yycol, args[0], string.Join(" èëè ", ww));
string errorMsg = string.Format("({0},{1}): {2}, {3}", yyline, yycol, args[0], string.Join(" ", ww));
throw new SyntaxException(errorMsg);
}
public void LexError()
{
string errorMsg = string.Format("({0},{1}): Íåèçâåñòíûé ñèìâîë {2}", yyline, yycol, yytext);
string errorMsg = string.Format("({0},{1}): {2}", yyline, yycol, yytext);
throw new LexException(errorMsg);
}
......@@ -793,6 +809,9 @@ class ScannerHelper
keywords.Add("cycle",(int)Tokens.CYCLE);
keywords.Add("write",(int)Tokens.WRITE);
keywords.Add("var",(int)Tokens.VAR);
keywords.Add("if",(int)Tokens.IF);
keywords.Add("then",(int)Tokens.THEN);
keywords.Add("else",(int)Tokens.ELSE);
}
public static int GetIDToken(string s)
{
......@@ -853,7 +872,6 @@ class ScannerHelper
return new LineBuffer(source);
}
#if (!NOFILES)
public static ScanBuff GetBuffer(Stream source)
{
return new BuildBuffer(source);
......@@ -864,8 +882,7 @@ class ScannerHelper
{
return new BuildBuffer(source, fallbackCodePage);
}
#endif // !BYTEMODE
#endif // !NOFILES
#endif
}
#region Buffer classes
......@@ -988,7 +1005,7 @@ class ScannerHelper
{
ix = lstart = 0;
}
while (ix < numLines)
for (; ; )
{
int len = line[ix].Length + 1;
if (pos < lstart + len) break;
......@@ -1046,8 +1063,7 @@ class ScannerHelper
{
cPos = value;
findIndex(cPos, out cLine, out curLineStart);
// cLine should be the *next* line after curLine.
curLine = (cLine < numLines ? line[cLine++] : "");
curLine = line[cLine];
curLineEnd = curLineStart + curLine.Length;
}
}
......@@ -1055,7 +1071,7 @@ class ScannerHelper
public override string ToString() { return "LineBuffer"; }
}
#if (!NOFILES)
// ==============================================================
// ===== class BuildBuff : for unicode text files ========
// ==============================================================
......@@ -1296,13 +1312,12 @@ class ScannerHelper
}
#endif // !BYTEMODE
}
#endif // !NOFILES
#endregion Buffer classes
// ==============================================================
// ============ class CodePageHandling =============
// ==============================================================
#if (!NOFILES)
public static class CodePageHandling
{
public static int GetCodePage(string option)
......@@ -1513,7 +1528,6 @@ class ScannerHelper
#endif // !BYTEMODE
#endregion
#endif // !NOFILES
// End of code copied from embedded resource
......
......@@ -78,6 +78,9 @@ class ScannerHelper
keywords.Add("cycle",(int)Tokens.CYCLE);
keywords.Add("write",(int)Tokens.WRITE);
keywords.Add("var",(int)Tokens.VAR);
keywords.Add("if",(int)Tokens.IF);
keywords.Add("then",(int)Tokens.THEN);
keywords.Add("else",(int)Tokens.ELSE);
}
public static int GetIDToken(string s)
{
......