2040 lines
87 KiB
C#
Executable File
2040 lines
87 KiB
C#
Executable File
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.IO;
|
|
|
|
|
|
// FileName : Parser.cs
|
|
// Author : Sean Kessler
|
|
|
|
namespace Axiom.Interpreter
|
|
{
|
|
public class Parser : Emitter
|
|
{
|
|
public enum ParserSymbols { undefined2, directive_clear_modified2, declare2, do2, defaddr2, goto2, add2, subtract2, multiply2, divide2, assign2, negate2, less2, lessequal2, greater2, greaterequal2, equalequal2, notequal2, variableaccess2, call2, push2, not2, codeend2, oror2, andand2, noop2 };
|
|
public enum ErrorCodes{DivideByZero};
|
|
private SymbolTable symbolTable;
|
|
private ParseSymbols directiveSymbols = new ParseSymbols();
|
|
private ParseSymbols assignmentStatementSymbols = new ParseSymbols();
|
|
private ParseSymbols statementSymbols = new ParseSymbols();
|
|
private ParseSymbols simpleExpressionSymbols = new ParseSymbols();
|
|
private ParseSymbols mathSymbols = new ParseSymbols();
|
|
private ParseSymbols termSymbols = new ParseSymbols();
|
|
private ParseSymbols factorSymbols = new ParseSymbols();
|
|
private ParseSymbols addSymbols = new ParseSymbols();
|
|
private ParseSymbols signSymbols = new ParseSymbols();
|
|
private ParseSymbols expressionSymbols = new ParseSymbols();
|
|
private ParseSymbols parseSymbols = new ParseSymbols();
|
|
private ParseSymbols relationSymbols = new ParseSymbols();
|
|
private ParseSymbols logicalSymbols = new ParseSymbols();
|
|
private ParseSymbols declarationSymbols = new ParseSymbols();
|
|
private ParseSymbols mathFunctionSymbols = new ParseSymbols();
|
|
private ParseSymbols stringManipulationSymbols = new ParseSymbols();
|
|
private Scanner.ScanSymbols currentSymbolType;
|
|
private double numeralValue;
|
|
private String stringValue;
|
|
private bool strictStatementMode=false; // is StrictStatementMode is true then the parser will return an error if there is not at least one statement processed.
|
|
private Stack<long> breakStack = new Stack<long>(); // when we encounter a break statement we need to record the address of the code pointer
|
|
private Stack<bool> loopStack = new Stack<bool>(); // when we encounter a loop (while/for) statement we need to record the event so that we can validate any break statements
|
|
|
|
public Parser(BinaryReader binaryReader, BinaryWriter binaryWriter, SymbolTable symbolTable)
|
|
: base(binaryReader, binaryWriter)
|
|
{
|
|
this.symbolTable = symbolTable;
|
|
currentSymbolType = Scanner.ScanSymbols.unknown1;
|
|
CreateDeclarationSymbols();
|
|
CreateAssignmentStatementSymbols();
|
|
CreateStatementSymbols();
|
|
CreateSimpleExpressionSymbols();
|
|
CreateMathSymbols();
|
|
CreateTermSymbols();
|
|
CreateFactorSymbols();
|
|
CreateAddSymbols();
|
|
CreateSignSymbols();
|
|
CreateExpressionSymbols();
|
|
CreateRelationSymbols();
|
|
CreateFunctionSymbols();
|
|
CreateLogicalSymbols();
|
|
CreateMathFunctionSymbols();
|
|
CreateStringManipulationSymbols();
|
|
IsInError = false;
|
|
LineNumber = 0;
|
|
LastLineNumber = 0;
|
|
SymbolNumber = -1;
|
|
LastSymbolNumber = -1;
|
|
StatementNumber = 0;
|
|
LastStatementNumber = 0;
|
|
LastMessage = "";
|
|
}
|
|
public bool Parse(bool includeCodeEnd=true)
|
|
{
|
|
NextSymbol();
|
|
InsertSymbols(new ParseSymbol(Scanner.ScanSymbols.endtext1));
|
|
InsertSymbols(new ParseSymbol(Scanner.ScanSymbols.directive_clear_modified1));
|
|
while (!(Scanner.ScanSymbols.endtext1.Equals(currentSymbolType)) && !IsInError) Statement();
|
|
RemoveSymbols(new ParseSymbol(Scanner.ScanSymbols.endtext1));
|
|
RemoveSymbols(new ParseSymbol(Scanner.ScanSymbols.directive_clear_modified1));
|
|
if(includeCodeEnd)Emit(Parser.ParserSymbols.codeend2);
|
|
if(StrictStatementMode && 0==StatementNumber)SyntaxError("The input document does not contain any valid statements.");
|
|
if (IsInError) return false;
|
|
if(Debug)
|
|
{
|
|
if (parseSymbols.Count != 0) Console.WriteLine("ParseSymbols is not empty.");
|
|
else Console.WriteLine("ParseSymbols, all symbols cleared from stack.");
|
|
}
|
|
return !IsInError;
|
|
}
|
|
public bool StrictStatementMode
|
|
{
|
|
get { return strictStatementMode; }
|
|
set{strictStatementMode=value;}
|
|
}
|
|
public int ParseSymbolsCount
|
|
{
|
|
get{return parseSymbols.Count;}
|
|
}
|
|
public int GetParseSymbolsCount()
|
|
{
|
|
return parseSymbols.Count;
|
|
}
|
|
public void Statement()
|
|
{
|
|
InsertSymbols(new ParseSymbol(Scanner.ScanSymbols.semicolon1));
|
|
if(SymbolIn(new ParseSymbol(Scanner.ScanSymbols.directive_clear_modified1)))
|
|
{
|
|
DirectiveClearModified();
|
|
}
|
|
else if(SymbolIn(new ParseSymbol(Scanner.ScanSymbols.declare1)))
|
|
{
|
|
DeclarationStatement();
|
|
}
|
|
else if (SymbolIn(new ParseSymbol(Scanner.ScanSymbols.label1)))
|
|
{
|
|
SyntaxError();
|
|
}
|
|
else if (SymbolIn(new ParseSymbol(Scanner.ScanSymbols.literal1)))
|
|
{
|
|
ParseLiteral();
|
|
}
|
|
else if (Scanner.ScanSymbols.variable1.Equals(currentSymbolType))
|
|
{
|
|
bool assignmentStatement = PeekSymbol(new ParseSymbol(Scanner.ScanSymbols.equal1));
|
|
VariableAccess();
|
|
if(assignmentStatement)
|
|
{
|
|
AssignmentStatement();
|
|
StatementNumber++;
|
|
}
|
|
}
|
|
else if (Scanner.ScanSymbols.if1.Equals(currentSymbolType))
|
|
{
|
|
IfStatement();
|
|
StatementNumber++;
|
|
}
|
|
else if(Scanner.ScanSymbols.break1.Equals(currentSymbolType))
|
|
{
|
|
BreakStatement();
|
|
StatementNumber++;
|
|
}
|
|
else if (Scanner.ScanSymbols.while1.Equals(currentSymbolType))
|
|
{
|
|
WhileStatement();
|
|
StatementNumber++;
|
|
}
|
|
else if (Scanner.ScanSymbols.for1.Equals(currentSymbolType))
|
|
{
|
|
ForStatement();
|
|
StatementNumber++;
|
|
}
|
|
else if (SymbolIn(termSymbols))
|
|
{
|
|
Term();
|
|
}
|
|
else SyntaxCheck();
|
|
|
|
InsertSymbols(new ParseSymbol(Scanner.ScanSymbols.endtext1));
|
|
InsertSymbols(statementSymbols);
|
|
if (SymbolIn(new ParseSymbol(Scanner.ScanSymbols.semicolon1)))
|
|
{
|
|
Expect(Scanner.ScanSymbols.semicolon1);
|
|
}
|
|
RemoveSymbols(statementSymbols);
|
|
RemoveSymbols(new ParseSymbol(Scanner.ScanSymbols.semicolon1));
|
|
RemoveSymbols(new ParseSymbol(Scanner.ScanSymbols.endtext1));
|
|
return;
|
|
}
|
|
|
|
public void DeclarationStatement()
|
|
{
|
|
bool moreDeclarations = true;
|
|
InsertSymbols(new ParseSymbol(Scanner.ScanSymbols.variable1));
|
|
Expect(Scanner.ScanSymbols.declare1);
|
|
SyntaxCheck();
|
|
while(moreDeclarations)
|
|
{
|
|
InsertSymbols(new ParseSymbol(Scanner.ScanSymbols.comma1));
|
|
Expect(Scanner.ScanSymbols.variable1);
|
|
Emit(Parser.ParserSymbols.declare2, stringValue);
|
|
RemoveSymbols(new ParseSymbol(Scanner.ScanSymbols.comma1));
|
|
if (SymbolIn(new ParseSymbol(Scanner.ScanSymbols.comma1)))
|
|
{
|
|
Expect(Scanner.ScanSymbols.comma1);
|
|
SyntaxCheck();
|
|
}
|
|
else moreDeclarations = false;
|
|
}
|
|
RemoveSymbols(new ParseSymbol(Scanner.ScanSymbols.variable1));
|
|
}
|
|
|
|
public void DirectiveClearModified()
|
|
{
|
|
Emit(Parser.ParserSymbols.directive_clear_modified2);
|
|
Expect(Scanner.ScanSymbols.directive_clear_modified1);
|
|
}
|
|
|
|
public void ParseLiteral()
|
|
{
|
|
Emit(Parser.ParserSymbols.push2, stringValue);
|
|
Expect(Scanner.ScanSymbols.literal1);
|
|
}
|
|
|
|
public void BreakStatement()
|
|
{
|
|
if(0.Equals(loopStack.Count))
|
|
{
|
|
SyntaxError("Encountered 'break' without 'while'/'for'");
|
|
}
|
|
if(breakStack.Count>0)
|
|
{
|
|
long codePointer = breakStack.Peek();
|
|
if(codePointer.Equals(CodePointer()))
|
|
{
|
|
SyntaxError("Unexpected break encountered.");
|
|
}
|
|
}
|
|
breakStack.Push(CodePointer());
|
|
Expect(Scanner.ScanSymbols.break1);
|
|
}
|
|
// ********************************************************************************************************************************
|
|
// *************************************************** F O R S T A T E M E N T *************************************************
|
|
// ********************************************************************************************************************************
|
|
//INIT
|
|
//L1:
|
|
// CONDITION
|
|
// IF FALSE -> L2
|
|
//BODY
|
|
//INCREMENT
|
|
//GOTO L1
|
|
//L2: NOOP
|
|
public void ForStatement()
|
|
{
|
|
long codePointerL1;
|
|
long codePointerFalseBranch;
|
|
long codePointerL2;
|
|
long codePointerTerminalAddress;
|
|
|
|
loopStack.Push(true); // register this is a for loop
|
|
InsertSymbols(expressionSymbols);
|
|
InsertSymbols(directiveSymbols);
|
|
Expect(Scanner.ScanSymbols.for1);
|
|
Expect(Scanner.ScanSymbols.leftparen1);
|
|
RemoveSymbols(expressionSymbols);
|
|
RemoveSymbols(directiveSymbols);
|
|
if (IsInError) { loopStack.Pop(); return; }
|
|
DoInitialization(); // Do initialization. I=1
|
|
codePointerL1 = CodePointer(); // execution target codePointerL1
|
|
DoForCondition(); // e.g., I < 10 // emit the for condition
|
|
codePointerFalseBranch = CodePointer(); // get the location in the stream for the defaddr2 that follows
|
|
Emit(Parser.ParserSymbols.defaddr2, 0L); // emit defaddr2 (jump if false) with dummy address of 0L
|
|
BeginCapture(); // start a new code emit frame. This is how we implement deferred emit
|
|
DoForIncrement(); // emit the increment code e.g., I = I + 1
|
|
EndCapture(); // end the capture
|
|
DoForBlock(); // emit the BODY
|
|
EmitCapture(); // emit the increment code we capture between BeginCapture and EndCapture
|
|
if (IsInError) { loopStack.Pop(); return; } // check error condition
|
|
Emit(Parser.ParserSymbols.goto2, codePointerL1); // jump back to condition after the body
|
|
codePointerL2 = CodePointer(); // get the location in the stream for the L2 exit location
|
|
Emit(Parser.ParserSymbols.noop2); // emit a noop at the current location
|
|
codePointerTerminalAddress = CodePointer(); // Record code pointer before seeking
|
|
Seek(codePointerFalseBranch); // seek to the defaddr2 statement that we emitted above
|
|
Emit(Parser.ParserSymbols.defaddr2, codePointerL2); // rewrite that statement with the correct branch address of L2 exit marker
|
|
HandleBreak(codePointerL2); // Handle any breaks
|
|
Seek(codePointerTerminalAddress); // seek to Terminal address in order to leave the stream at the correct location at the end of this all.
|
|
loopStack.Pop();
|
|
}
|
|
|
|
private void DoForIncrement()
|
|
{
|
|
InsertSymbols(new ParseSymbol(Scanner.ScanSymbols.rightparen1));
|
|
InsertSymbols(statementSymbols);
|
|
Expect(Scanner.ScanSymbols.semicolon1);
|
|
Statement();
|
|
RemoveSymbols(statementSymbols);
|
|
RemoveSymbols(new ParseSymbol(Scanner.ScanSymbols.rightparen1));
|
|
InsertSymbols(new ParseSymbol(Scanner.ScanSymbols.leftcurly1));
|
|
Expect(Scanner.ScanSymbols.rightparen1);
|
|
RemoveSymbols(new ParseSymbol(Scanner.ScanSymbols.leftcurly1));
|
|
}
|
|
|
|
private void DoForBlock()
|
|
{
|
|
InsertSymbols(new ParseSymbol(Scanner.ScanSymbols.rightcurly1));
|
|
InsertSymbols(statementSymbols);
|
|
Expect(Scanner.ScanSymbols.leftcurly1); // at this point we have {
|
|
if(IsInError)return;
|
|
while(!SymbolIn(new ParseSymbol(Scanner.ScanSymbols.rightcurly1)) && !IsInError)
|
|
{
|
|
Statement();
|
|
}
|
|
RemoveSymbols(new ParseSymbol(Scanner.ScanSymbols.rightcurly1));
|
|
Expect(Scanner.ScanSymbols.rightcurly1);
|
|
if(IsInError)return;
|
|
RemoveSymbols(statementSymbols);
|
|
}
|
|
|
|
|
|
private void DoForCondition()
|
|
{
|
|
long enterSymbolCount = SymbolCount();
|
|
Stack<Parser.ParserSymbols> logicalOperatorStack = new Stack<Parser.ParserSymbols>();
|
|
|
|
while (!IsInError)
|
|
{
|
|
// Stop at the increment separator
|
|
if (SymbolIn(new ParseSymbol(Scanner.ScanSymbols.semicolon1)))
|
|
break;
|
|
|
|
bool inShortFunction = false;
|
|
InsertSymbols(expressionSymbols);
|
|
if (PeekSymbolIn(directiveSymbols)) inShortFunction = true;
|
|
|
|
InsertSymbols(new ParseSymbol(Scanner.ScanSymbols.semicolon1));
|
|
InsertSymbols(logicalSymbols);
|
|
|
|
// Parse left-hand side expression and relation
|
|
Expression();
|
|
Relation();
|
|
|
|
InsertSymbols(relationSymbols);
|
|
SyntaxCheck();
|
|
if (IsInError) return;
|
|
|
|
RemoveSymbols(relationSymbols);
|
|
RemoveSymbols(logicalSymbols);
|
|
RemoveSymbols(new ParseSymbol(Scanner.ScanSymbols.semicolon1));
|
|
|
|
// Handle short functions or logical chaining
|
|
if (inShortFunction || SymbolIn(logicalSymbols))
|
|
{
|
|
if (SymbolIn(new ParseSymbol(Scanner.ScanSymbols.oror1)))
|
|
{
|
|
logicalOperatorStack.Push(Parser.ParserSymbols.oror2);
|
|
InsertSymbols(expressionSymbols);
|
|
InsertSymbols(directiveSymbols);
|
|
Expect(currentSymbolType);
|
|
RemoveSymbols(expressionSymbols);
|
|
RemoveSymbols(expressionSymbols); // yes, twice
|
|
RemoveSymbols(directiveSymbols);
|
|
continue;
|
|
}
|
|
else if (SymbolIn(new ParseSymbol(Scanner.ScanSymbols.andand1)))
|
|
{
|
|
logicalOperatorStack.Push(Parser.ParserSymbols.andand2);
|
|
InsertSymbols(expressionSymbols);
|
|
InsertSymbols(directiveSymbols);
|
|
Expect(currentSymbolType);
|
|
RemoveSymbols(expressionSymbols);
|
|
RemoveSymbols(expressionSymbols); // yes, twice
|
|
RemoveSymbols(directiveSymbols);
|
|
continue;
|
|
}
|
|
}
|
|
|
|
// Stop if next symbol is semicolon (increment)
|
|
if (SymbolIn(new ParseSymbol(Scanner.ScanSymbols.semicolon1)))
|
|
{
|
|
RemoveSymbols(expressionSymbols);
|
|
break;
|
|
}
|
|
|
|
// Parse relational operator
|
|
ParseSymbol relationSymbol = new ParseSymbol(currentSymbolType);
|
|
InsertSymbols(new ParseSymbol(Scanner.ScanSymbols.leftcurly1));
|
|
InsertSymbols(logicalSymbols);
|
|
InsertSymbols(directiveSymbols);
|
|
Expect(currentSymbolType);
|
|
if (IsInError) return;
|
|
|
|
RemoveSymbols(expressionSymbols);
|
|
RemoveSymbols(directiveSymbols);
|
|
|
|
if (!inShortFunction)
|
|
{
|
|
InsertSymbols(new ParseSymbol(Scanner.ScanSymbols.rightparen1));
|
|
|
|
if (SymbolIn(directiveSymbols))
|
|
{
|
|
InsertSymbols(relationSymbols);
|
|
Directive();
|
|
Relation();
|
|
RemoveSymbols(relationSymbols);
|
|
}
|
|
|
|
RemoveSymbols(new ParseSymbol(Scanner.ScanSymbols.rightparen1));
|
|
if (SymbolIn(new ParseSymbol(Scanner.ScanSymbols.rightparen1)))
|
|
Expect(Scanner.ScanSymbols.rightparen1);
|
|
|
|
EmitRelation(relationSymbol);
|
|
}
|
|
|
|
// Emit any logical operators in stack
|
|
if (logicalOperatorStack.Count != 0)
|
|
Emit(logicalOperatorStack.Pop());
|
|
|
|
// Check for trailing logical operators
|
|
if (SymbolIn(new ParseSymbol(Scanner.ScanSymbols.oror1)))
|
|
{
|
|
logicalOperatorStack.Push(Parser.ParserSymbols.oror2);
|
|
InsertSymbols(expressionSymbols);
|
|
InsertSymbols(directiveSymbols);
|
|
Expect(currentSymbolType);
|
|
RemoveSymbols(expressionSymbols);
|
|
RemoveSymbols(directiveSymbols);
|
|
}
|
|
else if (SymbolIn(new ParseSymbol(Scanner.ScanSymbols.andand1)))
|
|
{
|
|
logicalOperatorStack.Push(Parser.ParserSymbols.andand2);
|
|
InsertSymbols(expressionSymbols);
|
|
InsertSymbols(directiveSymbols);
|
|
Expect(currentSymbolType);
|
|
RemoveSymbols(expressionSymbols);
|
|
RemoveSymbols(directiveSymbols);
|
|
}
|
|
|
|
RemoveSymbols(logicalSymbols);
|
|
RemoveSymbols(new ParseSymbol(Scanner.ScanSymbols.leftcurly1));
|
|
RemoveSymbols(expressionSymbols);
|
|
|
|
if (!SymbolIn(expressionSymbols) && !SymbolIn(directiveSymbols))
|
|
break;
|
|
}
|
|
|
|
// Emit remaining logical operators
|
|
while (logicalOperatorStack.Count > 0)
|
|
Emit(logicalOperatorStack.Pop());
|
|
|
|
// Check symbol stack consistency
|
|
long exitSymbolCount = SymbolCount();
|
|
if (enterSymbolCount != exitSymbolCount)
|
|
throw new InvalidOperationException("Symbol counts do not match");
|
|
}
|
|
|
|
private void EmitRelation(ParseSymbol relationSymbol)
|
|
{
|
|
if (relationSymbol.Equals(new ParseSymbol(Scanner.ScanSymbols.notequal1)))
|
|
{
|
|
Emit(Parser.ParserSymbols.notequal2);
|
|
}
|
|
else if (relationSymbol.Equals(new ParseSymbol(Scanner.ScanSymbols.equalequal1)))
|
|
{
|
|
Emit(Parser.ParserSymbols.equalequal2);
|
|
}
|
|
else if (relationSymbol.Equals(new ParseSymbol(Scanner.ScanSymbols.less1)))
|
|
{
|
|
Emit(Parser.ParserSymbols.less2);
|
|
}
|
|
else if (relationSymbol.Equals(new ParseSymbol(Scanner.ScanSymbols.lessequal1)))
|
|
{
|
|
Emit(Parser.ParserSymbols.lessequal2);
|
|
}
|
|
else if (relationSymbol.Equals(new ParseSymbol(Scanner.ScanSymbols.greater1)))
|
|
{
|
|
Emit(Parser.ParserSymbols.greater2);
|
|
}
|
|
else if (relationSymbol.Equals(new ParseSymbol(Scanner.ScanSymbols.greaterequal1)))
|
|
{
|
|
Emit(Parser.ParserSymbols.greaterequal2);
|
|
}
|
|
}
|
|
|
|
private void DoInitialization()
|
|
{
|
|
// for (; ... ) → empty initialization
|
|
if(SymbolIn(new ParseSymbol(Scanner.ScanSymbols.semicolon1)))return;
|
|
// Reuse your normal assignment parser
|
|
Statement();
|
|
}
|
|
|
|
private void DoIncrement()
|
|
{
|
|
if(SymbolIn(new ParseSymbol(Scanner.ScanSymbols.rightparen1)))
|
|
{
|
|
return;
|
|
}
|
|
Expression();
|
|
}
|
|
// ********************************************************************************************************************************
|
|
// ************************************************** W H I L E S T A T E M E N T **********************************************
|
|
// ********************************************************************************************************************************
|
|
/// <summary>
|
|
/// WhileStatement Parses WhileStatement.
|
|
///WHILE
|
|
///L1: B //
|
|
/// Do(L2) // Here we branch L2 when the condition is False
|
|
/// S
|
|
/// Goto(L1) // Goto L1 and re-evaluate
|
|
///L2
|
|
/// </summary>
|
|
public void WhileStatement()
|
|
{
|
|
long codePointerFalseInstructionAddress;
|
|
long codePointerL1;
|
|
long codePointerL2;
|
|
long codePointerTerminalAddress;
|
|
|
|
loopStack.Push(true); // Register that we are processing a while loop
|
|
InsertSymbols(expressionSymbols);
|
|
InsertSymbols(directiveSymbols);
|
|
Expect(Scanner.ScanSymbols.while1);
|
|
Expect(Scanner.ScanSymbols.leftparen1);
|
|
RemoveSymbols(expressionSymbols);
|
|
RemoveSymbols(directiveSymbols);
|
|
if (IsInError){loopStack.Pop(); return;}
|
|
codePointerL1 = CodePointer(); // L1:
|
|
DoBForWhile(); // B
|
|
if(IsInError){loopStack.Pop(); return;}
|
|
codePointerFalseInstructionAddress = CodePointer(); // Record the location of the DEFADDR2 instruction.
|
|
Emit(Parser.ParserSymbols.defaddr2,0L); // Write DEFADDR2,0L. This will be jump to condition:false
|
|
DoSForWhile(); // S
|
|
if(IsInError){loopStack.Pop(); return;}
|
|
Emit(Parser.ParserSymbols.goto2,codePointerL1); // Goto(L1)
|
|
codePointerL2=CodePointer(); // L2:
|
|
Emit(Parser.ParserSymbols.noop2); // Don't write any instructions past this point
|
|
codePointerTerminalAddress=CodePointer(); // Record code pointer before seeking
|
|
Seek(codePointerFalseInstructionAddress); // Seek to DEFADDR2 instruction
|
|
Emit(Parser.ParserSymbols.defaddr2,codePointerL2); // Write DEFADDR2, L2
|
|
HandleBreak(codePointerL2); // If there was a break statement then handle the jump to condition
|
|
Seek(codePointerTerminalAddress);
|
|
loopStack.Pop();
|
|
}
|
|
|
|
/// <summary>
|
|
/// This is the handling for break statements in while loops
|
|
/// For the while statement there will be a DEFADDR, L2 just prior to a NOOP
|
|
/// </summary>
|
|
/// <param name="codePointerL2"></param>
|
|
public void HandleBreak(long codePointerL2)
|
|
{
|
|
if(0==breakStack.Count)return;
|
|
Seek(breakStack.Pop());
|
|
Emit(Parser.ParserSymbols.goto2,codePointerL2);
|
|
}
|
|
/// <summary>
|
|
/// B Section for While.
|
|
/// </summary>
|
|
public void DoBForWhile()
|
|
{
|
|
Stack<Parser.ParserSymbols> logicalOperatorStack = new Stack<Parser.ParserSymbols>();
|
|
while (!IsInError)
|
|
{
|
|
bool inShortFunction = false;
|
|
InsertSymbols(expressionSymbols);
|
|
if (PeekSymbolIn(directiveSymbols)) inShortFunction = true;
|
|
InsertSymbols(new ParseSymbol(Scanner.ScanSymbols.rightparen1));
|
|
InsertSymbols(logicalSymbols);
|
|
Expression();
|
|
Relation();
|
|
InsertSymbols(relationSymbols);
|
|
SyntaxCheck();
|
|
if (IsInError) return;
|
|
RemoveSymbols(relationSymbols);
|
|
RemoveSymbols(logicalSymbols);
|
|
RemoveSymbols(new ParseSymbol(Scanner.ScanSymbols.rightparen1));
|
|
if(SymbolIn(new ParseSymbol(Scanner.ScanSymbols.rightparen1))
|
|
&& !PeekSymbol(new ParseSymbol(Scanner.ScanSymbols.leftcurly1)))
|
|
{
|
|
RemoveSymbols(expressionSymbols);
|
|
break;
|
|
}
|
|
if (inShortFunction||SymbolIn(logicalSymbols))
|
|
{
|
|
if(SymbolIn(new ParseSymbol(Scanner.ScanSymbols.oror1)))
|
|
{
|
|
logicalOperatorStack.Push(Parser.ParserSymbols.oror2);
|
|
InsertSymbols(expressionSymbols);
|
|
InsertSymbols(directiveSymbols);
|
|
Expect(currentSymbolType);
|
|
RemoveSymbols(expressionSymbols);
|
|
RemoveSymbols(expressionSymbols); // yes do this twice
|
|
RemoveSymbols(directiveSymbols);
|
|
continue;
|
|
}
|
|
else if(SymbolIn(new ParseSymbol(Scanner.ScanSymbols.andand1)))
|
|
{
|
|
logicalOperatorStack.Push(Parser.ParserSymbols.andand2);
|
|
InsertSymbols(expressionSymbols);
|
|
InsertSymbols(directiveSymbols);
|
|
Expect(currentSymbolType);
|
|
RemoveSymbols(expressionSymbols);
|
|
RemoveSymbols(expressionSymbols); // yes do this twice
|
|
RemoveSymbols(directiveSymbols);
|
|
continue;
|
|
}
|
|
}
|
|
ParseSymbol relationSymbol = new ParseSymbol(currentSymbolType);
|
|
InsertSymbols(new ParseSymbol(Scanner.ScanSymbols.leftcurly1)); // going to handle while(){stmt;stmt;} and while()stmt;
|
|
InsertSymbols(logicalSymbols);
|
|
InsertSymbols(directiveSymbols);
|
|
Expect(currentSymbolType);
|
|
RemoveSymbols(expressionSymbols);
|
|
RemoveSymbols(directiveSymbols);
|
|
if (!inShortFunction)
|
|
{
|
|
InsertSymbols(new ParseSymbol(Scanner.ScanSymbols.rightparen1));
|
|
if (SymbolIn(directiveSymbols))
|
|
{
|
|
InsertSymbols(relationSymbols);
|
|
Directive();
|
|
Relation();
|
|
RemoveSymbols(relationSymbols);
|
|
}
|
|
else
|
|
{
|
|
Statement();
|
|
}
|
|
RemoveSymbols(new ParseSymbol(Scanner.ScanSymbols.rightparen1));
|
|
if (SymbolIn(new ParseSymbol(Scanner.ScanSymbols.rightparen1))) Expect(Scanner.ScanSymbols.rightparen1);
|
|
if (relationSymbol.Equals(new ParseSymbol(Scanner.ScanSymbols.notequal1)))
|
|
{
|
|
Emit(Parser.ParserSymbols.notequal2);
|
|
}
|
|
else if (relationSymbol.Equals(new ParseSymbol(Scanner.ScanSymbols.equalequal1)))
|
|
{
|
|
Emit(Parser.ParserSymbols.equalequal2);
|
|
}
|
|
else if (relationSymbol.Equals(new ParseSymbol(Scanner.ScanSymbols.less1)))
|
|
{
|
|
Emit(Parser.ParserSymbols.less2);
|
|
}
|
|
else if (relationSymbol.Equals(new ParseSymbol(Scanner.ScanSymbols.lessequal1)))
|
|
{
|
|
Emit(Parser.ParserSymbols.lessequal2);
|
|
}
|
|
else if (relationSymbol.Equals(new ParseSymbol(Scanner.ScanSymbols.greater1)))
|
|
{
|
|
Emit(Parser.ParserSymbols.greater2);
|
|
}
|
|
else if (relationSymbol.Equals(new ParseSymbol(Scanner.ScanSymbols.greaterequal1)))
|
|
{
|
|
Emit(Parser.ParserSymbols.greaterequal2);
|
|
}
|
|
}
|
|
if (0 != logicalOperatorStack.Count) Emit(logicalOperatorStack.Pop());
|
|
if(SymbolIn(new ParseSymbol(Scanner.ScanSymbols.oror1)))
|
|
{
|
|
logicalOperatorStack.Push(Parser.ParserSymbols.oror2);
|
|
InsertSymbols(expressionSymbols);
|
|
InsertSymbols(directiveSymbols);
|
|
Expect(currentSymbolType);
|
|
RemoveSymbols(expressionSymbols);
|
|
RemoveSymbols(directiveSymbols);
|
|
}
|
|
else if(SymbolIn(new ParseSymbol(Scanner.ScanSymbols.andand1)))
|
|
{
|
|
logicalOperatorStack.Push(Parser.ParserSymbols.andand2);
|
|
InsertSymbols(expressionSymbols);
|
|
InsertSymbols(directiveSymbols);
|
|
Expect(currentSymbolType);
|
|
RemoveSymbols(expressionSymbols);
|
|
RemoveSymbols(directiveSymbols);
|
|
}
|
|
RemoveSymbols(logicalSymbols);
|
|
RemoveSymbols(new ParseSymbol(Scanner.ScanSymbols.leftcurly1));
|
|
RemoveSymbols(expressionSymbols);
|
|
if (!SymbolIn(expressionSymbols)&&!SymbolIn(directiveSymbols)) break;
|
|
} // while we continue to have logical expressions and we have no errors
|
|
if (0 != logicalOperatorStack.Count) Emit(logicalOperatorStack.Pop());
|
|
}
|
|
/// <summary>
|
|
/// S Section for While.
|
|
/// </summary>
|
|
public void DoSForWhile()
|
|
{
|
|
InsertSymbols(statementSymbols);
|
|
if(SymbolIn(new ParseSymbol(Scanner.ScanSymbols.rightparen1)))
|
|
{
|
|
Expect(Scanner.ScanSymbols.rightparen1);
|
|
Statement();
|
|
}
|
|
else if(SymbolIn(new ParseSymbol(Scanner.ScanSymbols.leftcurly1)))
|
|
{
|
|
InsertSymbols(new ParseSymbol(Scanner.ScanSymbols.rightcurly1));
|
|
Expect(Scanner.ScanSymbols.leftcurly1);
|
|
while (!IsInError)
|
|
{
|
|
Statement();
|
|
if (SymbolIn(new ParseSymbol(Scanner.ScanSymbols.rightcurly1)))
|
|
{
|
|
Expect(Scanner.ScanSymbols.rightcurly1);
|
|
break;
|
|
}
|
|
}
|
|
RemoveSymbols(new ParseSymbol(Scanner.ScanSymbols.rightcurly1));
|
|
}
|
|
else if(SymbolIn(new ParseSymbol(Scanner.ScanSymbols.semicolon1)))
|
|
{
|
|
Expect(Scanner.ScanSymbols.semicolon1);
|
|
}
|
|
else SyntaxError();
|
|
RemoveSymbols(statementSymbols);
|
|
}
|
|
// **************************************************************************************************************************************
|
|
/// <summary>
|
|
/// IfStatement.
|
|
///if B then S1 else S2
|
|
///
|
|
/// B
|
|
/// Do(L1) // Here we branch when the condition is False
|
|
/// S1
|
|
/// Goto(L2) // Here we branch unconditionally
|
|
///L1: S2
|
|
///L2:
|
|
/// </summary>
|
|
public void IfStatement()
|
|
{
|
|
InsertSymbols(expressionSymbols);
|
|
InsertSymbols(directiveSymbols);
|
|
Expect(Scanner.ScanSymbols.if1);
|
|
Expect(Scanner.ScanSymbols.leftparen1);
|
|
RemoveSymbols(expressionSymbols);
|
|
RemoveSymbols(directiveSymbols);
|
|
if(IsInError)return;
|
|
DoBForIf();
|
|
if(IsInError)return;
|
|
DoSForIf();
|
|
}
|
|
|
|
public void DoBForIf()
|
|
{
|
|
Stack<Parser.ParserSymbols> logicalOperatorStack = new Stack<Parser.ParserSymbols>();
|
|
while (!IsInError)
|
|
{
|
|
bool inShortFunction = false;
|
|
InsertSymbols(expressionSymbols);
|
|
if (PeekSymbolIn(directiveSymbols)) inShortFunction = true;
|
|
InsertSymbols(new ParseSymbol(Scanner.ScanSymbols.rightparen1));
|
|
InsertSymbols(logicalSymbols);
|
|
Expression();
|
|
Relation();
|
|
InsertSymbols(relationSymbols);
|
|
SyntaxCheck();
|
|
if (IsInError) return;
|
|
RemoveSymbols(relationSymbols);
|
|
RemoveSymbols(logicalSymbols);
|
|
RemoveSymbols(new ParseSymbol(Scanner.ScanSymbols.rightparen1));
|
|
if (inShortFunction||SymbolIn(logicalSymbols))
|
|
{
|
|
if(SymbolIn(new ParseSymbol(Scanner.ScanSymbols.oror1)))
|
|
{
|
|
logicalOperatorStack.Push(Parser.ParserSymbols.oror2);
|
|
InsertSymbols(expressionSymbols);
|
|
InsertSymbols(directiveSymbols);
|
|
Expect(currentSymbolType);
|
|
RemoveSymbols(expressionSymbols);
|
|
RemoveSymbols(expressionSymbols); // yes do this twice
|
|
RemoveSymbols(directiveSymbols);
|
|
continue;
|
|
}
|
|
else if(SymbolIn(new ParseSymbol(Scanner.ScanSymbols.andand1)))
|
|
{
|
|
logicalOperatorStack.Push(Parser.ParserSymbols.andand2);
|
|
InsertSymbols(expressionSymbols);
|
|
InsertSymbols(directiveSymbols);
|
|
Expect(currentSymbolType);
|
|
RemoveSymbols(expressionSymbols);
|
|
RemoveSymbols(expressionSymbols); // yes do this twice
|
|
RemoveSymbols(directiveSymbols);
|
|
continue;
|
|
}
|
|
}
|
|
ParseSymbol relationSymbol = new ParseSymbol(currentSymbolType);
|
|
InsertSymbols(new ParseSymbol(Scanner.ScanSymbols.then1)); // going to handle if() then stmt; else stmt;
|
|
InsertSymbols(new ParseSymbol(Scanner.ScanSymbols.leftcurly1)); // going to handle if(){stmt;stmt;}else{stmt;stmt;}
|
|
InsertSymbols(logicalSymbols);
|
|
InsertSymbols(directiveSymbols);
|
|
Expect(currentSymbolType);
|
|
RemoveSymbols(expressionSymbols);
|
|
RemoveSymbols(directiveSymbols);
|
|
if (!inShortFunction)
|
|
{
|
|
InsertSymbols(new ParseSymbol(Scanner.ScanSymbols.rightparen1));
|
|
if (SymbolIn(directiveSymbols))
|
|
{
|
|
InsertSymbols(relationSymbols);
|
|
Directive();
|
|
Relation();
|
|
RemoveSymbols(relationSymbols);
|
|
}
|
|
else
|
|
{
|
|
Statement();
|
|
}
|
|
RemoveSymbols(new ParseSymbol(Scanner.ScanSymbols.rightparen1));
|
|
if (SymbolIn(new ParseSymbol(Scanner.ScanSymbols.rightparen1))) Expect(Scanner.ScanSymbols.rightparen1);
|
|
if (relationSymbol.Equals(new ParseSymbol(Scanner.ScanSymbols.notequal1)))
|
|
{
|
|
Emit(Parser.ParserSymbols.notequal2);
|
|
}
|
|
else if (relationSymbol.Equals(new ParseSymbol(Scanner.ScanSymbols.equalequal1)))
|
|
{
|
|
Emit(Parser.ParserSymbols.equalequal2);
|
|
}
|
|
else if (relationSymbol.Equals(new ParseSymbol(Scanner.ScanSymbols.less1)))
|
|
{
|
|
Emit(Parser.ParserSymbols.less2);
|
|
}
|
|
else if (relationSymbol.Equals(new ParseSymbol(Scanner.ScanSymbols.lessequal1)))
|
|
{
|
|
Emit(Parser.ParserSymbols.lessequal2);
|
|
}
|
|
else if (relationSymbol.Equals(new ParseSymbol(Scanner.ScanSymbols.greater1)))
|
|
{
|
|
Emit(Parser.ParserSymbols.greater2);
|
|
}
|
|
else if (relationSymbol.Equals(new ParseSymbol(Scanner.ScanSymbols.greaterequal1)))
|
|
{
|
|
Emit(Parser.ParserSymbols.greaterequal2);
|
|
}
|
|
}
|
|
if (0 != logicalOperatorStack.Count) Emit(logicalOperatorStack.Pop());
|
|
if(SymbolIn(new ParseSymbol(Scanner.ScanSymbols.oror1)))
|
|
{
|
|
logicalOperatorStack.Push(Parser.ParserSymbols.oror2);
|
|
InsertSymbols(expressionSymbols);
|
|
InsertSymbols(directiveSymbols);
|
|
Expect(currentSymbolType);
|
|
RemoveSymbols(expressionSymbols);
|
|
RemoveSymbols(directiveSymbols);
|
|
}
|
|
else if(SymbolIn(new ParseSymbol(Scanner.ScanSymbols.andand1)))
|
|
{
|
|
logicalOperatorStack.Push(Parser.ParserSymbols.andand2);
|
|
InsertSymbols(expressionSymbols);
|
|
InsertSymbols(directiveSymbols);
|
|
Expect(currentSymbolType);
|
|
RemoveSymbols(expressionSymbols);
|
|
RemoveSymbols(directiveSymbols);
|
|
}
|
|
RemoveSymbols(logicalSymbols);
|
|
RemoveSymbols(new ParseSymbol(Scanner.ScanSymbols.then1));
|
|
RemoveSymbols(new ParseSymbol(Scanner.ScanSymbols.leftcurly1));
|
|
RemoveSymbols(expressionSymbols);
|
|
if (!SymbolIn(expressionSymbols)&&!SymbolIn(directiveSymbols)) break;
|
|
} // while we continue to have logical expressions and we have no errors
|
|
if (0 != logicalOperatorStack.Count) Emit(logicalOperatorStack.Pop());
|
|
}
|
|
public void DoSForIf()
|
|
{
|
|
bool containsElse=true;
|
|
long codePointerFalseInstructionAddress=0;
|
|
long codePointerFalseGotoTarget=0;
|
|
long codePointerTrueInstructionAddress=0;
|
|
long codePointerTrueGotoTarget=0;
|
|
long codePointerTerminalAddress=0;
|
|
|
|
#region DO(L1)
|
|
codePointerFalseInstructionAddress = CodePointer(); // Do(L1) False. Get the address of where I am going to write the next instruction
|
|
Emit(Parser.ParserSymbols.defaddr2,0L); // write the next instruction with a zero. It will be filled in later with a valid address. This will be jump to condition:false
|
|
#endregion
|
|
#region S1
|
|
InsertSymbols(statementSymbols);
|
|
if(SymbolIn(new ParseSymbol(Scanner.ScanSymbols.then1)))
|
|
{
|
|
Expect(Scanner.ScanSymbols.then1);
|
|
InsertSymbols(new ParseSymbol(Scanner.ScanSymbols.else1));
|
|
Statement(); // after this statement we need to jump to the end
|
|
}
|
|
else if(SymbolIn(new ParseSymbol(Scanner.ScanSymbols.leftcurly1)))
|
|
{
|
|
InsertSymbols(new ParseSymbol(Scanner.ScanSymbols.rightcurly1));
|
|
Expect(Scanner.ScanSymbols.leftcurly1);
|
|
while (!IsInError)
|
|
{
|
|
Statement();
|
|
if (SymbolIn(new ParseSymbol(Scanner.ScanSymbols.rightcurly1)))
|
|
{
|
|
InsertSymbols(new ParseSymbol(Scanner.ScanSymbols.else1));
|
|
Expect(Scanner.ScanSymbols.rightcurly1);
|
|
RemoveSymbols(new ParseSymbol(Scanner.ScanSymbols.else1));
|
|
break;
|
|
}
|
|
}
|
|
RemoveSymbols(new ParseSymbol(Scanner.ScanSymbols.rightcurly1));
|
|
}
|
|
else if(SymbolIn(new ParseSymbol(Scanner.ScanSymbols.semicolon1)))
|
|
{
|
|
Expect(Scanner.ScanSymbols.semicolon1);
|
|
}
|
|
else SyntaxError();
|
|
RemoveSymbols(new ParseSymbol(Scanner.ScanSymbols.else1));
|
|
#endregion
|
|
#region GOTO(L2)
|
|
codePointerTrueInstructionAddress = CodePointer();
|
|
Emit(Parser.ParserSymbols.goto2,0L);
|
|
#endregion
|
|
#region L1:S2
|
|
codePointerFalseGotoTarget = CodePointer(); // This is where instructions start for the false condition
|
|
Seek(codePointerFalseInstructionAddress);
|
|
Emit(Parser.ParserSymbols.defaddr2,codePointerFalseGotoTarget);
|
|
Seek(codePointerFalseGotoTarget);
|
|
if(!SymbolIn(new ParseSymbol(Scanner.ScanSymbols.else1)))containsElse=false;
|
|
if(containsElse)
|
|
{
|
|
InsertSymbols(new ParseSymbol(Scanner.ScanSymbols.leftcurly1));
|
|
Expect(Scanner.ScanSymbols.else1);
|
|
RemoveSymbols(new ParseSymbol(Scanner.ScanSymbols.leftcurly1));
|
|
if (SymbolIn(new ParseSymbol(Scanner.ScanSymbols.leftcurly1)))
|
|
{
|
|
InsertSymbols(new ParseSymbol(Scanner.ScanSymbols.rightcurly1));
|
|
InsertSymbols(new ParseSymbol(Scanner.ScanSymbols.leftcurly1));
|
|
InsertSymbols(statementSymbols);
|
|
Expect(Scanner.ScanSymbols.leftcurly1);
|
|
RemoveSymbols(statementSymbols);
|
|
RemoveSymbols(new ParseSymbol(Scanner.ScanSymbols.leftcurly1));
|
|
while (!IsInError)
|
|
{
|
|
Statement();
|
|
if (SymbolIn(new ParseSymbol(Scanner.ScanSymbols.rightcurly1)))
|
|
{
|
|
Expect(Scanner.ScanSymbols.rightcurly1);
|
|
break;
|
|
}
|
|
}
|
|
RemoveSymbols(new ParseSymbol(Scanner.ScanSymbols.rightcurly1));
|
|
}
|
|
else
|
|
{
|
|
Statement();
|
|
}
|
|
}
|
|
#endregion
|
|
#region L2
|
|
codePointerTrueGotoTarget=CodePointer();
|
|
Emit(Parser.ParserSymbols.noop2);
|
|
codePointerTerminalAddress = CodePointer();
|
|
Seek(codePointerTrueInstructionAddress);
|
|
Emit(Parser.ParserSymbols.goto2,codePointerTrueGotoTarget);
|
|
Seek(codePointerTerminalAddress);
|
|
RemoveSymbols(statementSymbols);
|
|
#endregion
|
|
}
|
|
// **************************************************************************************************************
|
|
public void Relation()
|
|
{
|
|
Stack<Parser.ParserSymbols> logicalOperatorStack = new Stack<Parser.ParserSymbols>();
|
|
if (!SymbolIn(relationSymbols)) return;
|
|
while (!IsInError)
|
|
{
|
|
if(SymbolIn(new ParseSymbol(Scanner.ScanSymbols.equalequal1)))
|
|
{
|
|
logicalOperatorStack.Push(Parser.ParserSymbols.equalequal2);
|
|
InsertSymbols(expressionSymbols);
|
|
InsertSymbols(directiveSymbols);
|
|
Expect(currentSymbolType);
|
|
RemoveSymbols(expressionSymbols);
|
|
RemoveSymbols(directiveSymbols);
|
|
continue;
|
|
}
|
|
else if(SymbolIn(new ParseSymbol(Scanner.ScanSymbols.notequal1)))
|
|
{
|
|
logicalOperatorStack.Push(Parser.ParserSymbols.notequal2);
|
|
InsertSymbols(expressionSymbols);
|
|
InsertSymbols(directiveSymbols);
|
|
Expect(currentSymbolType);
|
|
RemoveSymbols(expressionSymbols);
|
|
RemoveSymbols(directiveSymbols);
|
|
continue;
|
|
}
|
|
else if(SymbolIn(new ParseSymbol(Scanner.ScanSymbols.less1)))
|
|
{
|
|
logicalOperatorStack.Push(Parser.ParserSymbols.less2);
|
|
InsertSymbols(expressionSymbols);
|
|
InsertSymbols(directiveSymbols);
|
|
Expect(currentSymbolType);
|
|
RemoveSymbols(expressionSymbols);
|
|
RemoveSymbols(directiveSymbols);
|
|
continue;
|
|
}
|
|
else if(SymbolIn(new ParseSymbol(Scanner.ScanSymbols.lessequal1)))
|
|
{
|
|
logicalOperatorStack.Push(Parser.ParserSymbols.lessequal2);
|
|
InsertSymbols(expressionSymbols);
|
|
InsertSymbols(directiveSymbols);
|
|
Expect(currentSymbolType);
|
|
RemoveSymbols(expressionSymbols);
|
|
RemoveSymbols(directiveSymbols);
|
|
continue;
|
|
}
|
|
else if(SymbolIn(new ParseSymbol(Scanner.ScanSymbols.greater1)))
|
|
{
|
|
logicalOperatorStack.Push(Parser.ParserSymbols.greater2);
|
|
InsertSymbols(expressionSymbols);
|
|
InsertSymbols(directiveSymbols);
|
|
Expect(currentSymbolType);
|
|
RemoveSymbols(expressionSymbols);
|
|
RemoveSymbols(directiveSymbols);
|
|
continue;
|
|
}
|
|
else if(SymbolIn(new ParseSymbol(Scanner.ScanSymbols.greaterequal1)))
|
|
{
|
|
logicalOperatorStack.Push(Parser.ParserSymbols.greaterequal2);
|
|
InsertSymbols(expressionSymbols);
|
|
InsertSymbols(directiveSymbols);
|
|
Expect(currentSymbolType);
|
|
RemoveSymbols(expressionSymbols);
|
|
RemoveSymbols(directiveSymbols);
|
|
continue;
|
|
}
|
|
else if(SymbolIn(new ParseSymbol(Scanner.ScanSymbols.oror1)))
|
|
{
|
|
logicalOperatorStack.Push(Parser.ParserSymbols.oror2);
|
|
InsertSymbols(expressionSymbols);
|
|
InsertSymbols(directiveSymbols);
|
|
Expect(currentSymbolType);
|
|
RemoveSymbols(expressionSymbols);
|
|
RemoveSymbols(directiveSymbols);
|
|
continue;
|
|
}
|
|
else if(SymbolIn(new ParseSymbol(Scanner.ScanSymbols.andand1)))
|
|
{
|
|
logicalOperatorStack.Push(Parser.ParserSymbols.andand2);
|
|
InsertSymbols(expressionSymbols);
|
|
InsertSymbols(directiveSymbols);
|
|
Expect(currentSymbolType);
|
|
RemoveSymbols(expressionSymbols);
|
|
RemoveSymbols(directiveSymbols);
|
|
continue;
|
|
}
|
|
else if(SymbolIn(new ParseSymbol(Scanner.ScanSymbols.less1)))
|
|
{
|
|
logicalOperatorStack.Push(Parser.ParserSymbols.less2);
|
|
InsertSymbols(expressionSymbols);
|
|
InsertSymbols(directiveSymbols);
|
|
Expect(currentSymbolType);
|
|
RemoveSymbols(expressionSymbols);
|
|
RemoveSymbols(directiveSymbols);
|
|
continue;
|
|
}
|
|
InsertSymbols(new ParseSymbol(Scanner.ScanSymbols.rightparen1));
|
|
Term();
|
|
RemoveSymbols(new ParseSymbol(Scanner.ScanSymbols.rightparen1));
|
|
ParseSymbol relationSymbol = new ParseSymbol(currentSymbolType);
|
|
if (0 != logicalOperatorStack.Count) Emit(logicalOperatorStack.Pop());
|
|
if (!SymbolIn(relationSymbols)&&!SymbolIn(logicalSymbols)) break;
|
|
} // while true
|
|
if (0 != logicalOperatorStack.Count) Emit(logicalOperatorStack.Pop());
|
|
}
|
|
public void AssignmentStatement()
|
|
{
|
|
InsertSymbols(expressionSymbols);
|
|
InsertSymbols(directiveSymbols);
|
|
Expect(Scanner.ScanSymbols.equal1);
|
|
if (IsInError) return;
|
|
RemoveSymbols(directiveSymbols);
|
|
RemoveSymbols(expressionSymbols);
|
|
if (SymbolIn(expressionSymbols))
|
|
{
|
|
Expression();
|
|
Emit(Parser.ParserSymbols.assign2);
|
|
}
|
|
else if (SymbolIn(directiveSymbols))
|
|
{
|
|
RemoveSymbols(directiveSymbols);
|
|
RemoveSymbols(expressionSymbols);
|
|
Directive();
|
|
if (SymbolIn(expressionSymbols))
|
|
{
|
|
while (SymbolIn(expressionSymbols))
|
|
{
|
|
InsertSymbols(expressionSymbols);
|
|
InsertSymbols(directiveSymbols);
|
|
Expression();
|
|
RemoveSymbols(directiveSymbols);
|
|
RemoveSymbols(expressionSymbols);
|
|
}
|
|
}
|
|
else if (SymbolIn(mathSymbols))
|
|
{
|
|
InsertSymbols(expressionSymbols);
|
|
InsertSymbols(directiveSymbols);
|
|
SimpleTerm();
|
|
RemoveSymbols(expressionSymbols);
|
|
RemoveSymbols(directiveSymbols);
|
|
}
|
|
Emit(Parser.ParserSymbols.assign2);
|
|
}
|
|
else SyntaxError();
|
|
}
|
|
public void VariableAccess()
|
|
{
|
|
Emit(Parser.ParserSymbols.variableaccess2,stringValue);
|
|
NextSymbol();
|
|
}
|
|
// *******************************************************************************************************************************************************************************************************************************************************************
|
|
// ************************************************************************************************************ B U I L T - I N F U N C T I O N S ******************************************************************************************************************
|
|
// *******************************************************************************************************************************************************************************************************************************************************************
|
|
public void Directive()
|
|
{
|
|
if (SymbolIn(new ParseSymbol(Scanner.ScanSymbols.abs1))) ParseABS();
|
|
else if (SymbolIn(new ParseSymbol(Scanner.ScanSymbols.pow1))) ParsePOW();
|
|
else if (SymbolIn(new ParseSymbol(Scanner.ScanSymbols.sqrt1))) ParseSQRT();
|
|
else if (SymbolIn(new ParseSymbol(Scanner.ScanSymbols.convert1))) ParseConvert();
|
|
else if (SymbolIn(new ParseSymbol(Scanner.ScanSymbols.substring1))) ParseSubstring();
|
|
else if (SymbolIn(new ParseSymbol(Scanner.ScanSymbols.getprice1))) ParseGetPrice();
|
|
else if (SymbolIn(new ParseSymbol(Scanner.ScanSymbols.in1))) ParseIn();
|
|
else if (SymbolIn(new ParseSymbol(Scanner.ScanSymbols.like1))) ParseLike();
|
|
else if (SymbolIn(new ParseSymbol(Scanner.ScanSymbols.isnull1))) ParseIsNull();
|
|
else if (SymbolIn(new ParseSymbol(Scanner.ScanSymbols.trim1))) ParseTrim();
|
|
else if (SymbolIn(new ParseSymbol(Scanner.ScanSymbols.upper1))) ParseUpper();
|
|
else if (SymbolIn(new ParseSymbol(Scanner.ScanSymbols.lower1))) ParseLower();
|
|
}
|
|
public void ParseLike()
|
|
{
|
|
Symbol namedFunction = symbolTable.Find(Scanner.ScanSymbols.like1);
|
|
Expect(Scanner.ScanSymbols.like1);
|
|
InsertSymbols(new ParseSymbol(Scanner.ScanSymbols.literal1));
|
|
InsertSymbols(new ParseSymbol(Scanner.ScanSymbols.variable1));
|
|
if (SymbolIn(new ParseSymbol(Scanner.ScanSymbols.literal1)))
|
|
{
|
|
Emit(Parser.ParserSymbols.push2, stringValue);
|
|
Expect(Scanner.ScanSymbols.literal1);
|
|
}
|
|
else if (SymbolIn(new ParseSymbol(Scanner.ScanSymbols.variable1)))
|
|
{
|
|
VariableAccess();
|
|
}
|
|
else SyntaxCheck();
|
|
RemoveSymbols(new ParseSymbol(Scanner.ScanSymbols.literal1));
|
|
RemoveSymbols(new ParseSymbol(Scanner.ScanSymbols.variable1));
|
|
Emit(Parser.ParserSymbols.call2,namedFunction.SymbolName,1);
|
|
}
|
|
public void ParseTrim()
|
|
{
|
|
Symbol namedFunction = symbolTable.Find(Scanner.ScanSymbols.trim1);
|
|
InsertSymbols(new ParseSymbol(Scanner.ScanSymbols.leftparen1));
|
|
Expect(Scanner.ScanSymbols.trim1);
|
|
InsertSymbols(new ParseSymbol(Scanner.ScanSymbols.literal1));
|
|
InsertSymbols(new ParseSymbol(Scanner.ScanSymbols.variable1));
|
|
InsertSymbols(directiveSymbols);
|
|
Expect(Scanner.ScanSymbols.leftparen1);
|
|
RemoveSymbols(directiveSymbols);
|
|
RemoveSymbols(new ParseSymbol(Scanner.ScanSymbols.leftparen1));
|
|
InsertSymbols(new ParseSymbol(Scanner.ScanSymbols.rightparen1));
|
|
Expression();
|
|
InsertSymbols(addSymbols);
|
|
Expect(Scanner.ScanSymbols.rightparen1);
|
|
RemoveSymbols(addSymbols);
|
|
RemoveSymbols(new ParseSymbol(Scanner.ScanSymbols.rightparen1));
|
|
RemoveSymbols(new ParseSymbol(Scanner.ScanSymbols.literal1));
|
|
RemoveSymbols(new ParseSymbol(Scanner.ScanSymbols.variable1));
|
|
Emit(Parser.ParserSymbols.call2,namedFunction.SymbolName,1);
|
|
}
|
|
public void ParseUpper()
|
|
{
|
|
Symbol namedFunction = symbolTable.Find(Scanner.ScanSymbols.upper1);
|
|
InsertSymbols(new ParseSymbol(Scanner.ScanSymbols.leftparen1));
|
|
Expect(Scanner.ScanSymbols.upper1);
|
|
InsertSymbols(new ParseSymbol(Scanner.ScanSymbols.literal1));
|
|
InsertSymbols(new ParseSymbol(Scanner.ScanSymbols.variable1));
|
|
InsertSymbols(directiveSymbols);
|
|
Expect(Scanner.ScanSymbols.leftparen1);
|
|
RemoveSymbols(directiveSymbols);
|
|
RemoveSymbols(new ParseSymbol(Scanner.ScanSymbols.leftparen1));
|
|
InsertSymbols(new ParseSymbol(Scanner.ScanSymbols.rightparen1));
|
|
Expression();
|
|
InsertSymbols(addSymbols);
|
|
Expect(Scanner.ScanSymbols.rightparen1);
|
|
RemoveSymbols(addSymbols);
|
|
RemoveSymbols(new ParseSymbol(Scanner.ScanSymbols.rightparen1));
|
|
RemoveSymbols(new ParseSymbol(Scanner.ScanSymbols.literal1));
|
|
RemoveSymbols(new ParseSymbol(Scanner.ScanSymbols.variable1));
|
|
Emit(Parser.ParserSymbols.call2,namedFunction.SymbolName,1);
|
|
}
|
|
public void ParseLower()
|
|
{
|
|
Symbol namedFunction = symbolTable.Find(Scanner.ScanSymbols.lower1);
|
|
InsertSymbols(new ParseSymbol(Scanner.ScanSymbols.leftparen1));
|
|
Expect(Scanner.ScanSymbols.lower1);
|
|
InsertSymbols(new ParseSymbol(Scanner.ScanSymbols.literal1));
|
|
InsertSymbols(new ParseSymbol(Scanner.ScanSymbols.variable1));
|
|
InsertSymbols(directiveSymbols);
|
|
Expect(Scanner.ScanSymbols.leftparen1);
|
|
RemoveSymbols(directiveSymbols);
|
|
RemoveSymbols(new ParseSymbol(Scanner.ScanSymbols.leftparen1));
|
|
InsertSymbols(new ParseSymbol(Scanner.ScanSymbols.rightparen1));
|
|
Expression();
|
|
InsertSymbols(addSymbols);
|
|
Expect(Scanner.ScanSymbols.rightparen1);
|
|
RemoveSymbols(addSymbols);
|
|
RemoveSymbols(new ParseSymbol(Scanner.ScanSymbols.rightparen1));
|
|
RemoveSymbols(new ParseSymbol(Scanner.ScanSymbols.literal1));
|
|
RemoveSymbols(new ParseSymbol(Scanner.ScanSymbols.variable1));
|
|
Emit(Parser.ParserSymbols.call2,namedFunction.SymbolName,1);
|
|
}
|
|
// SUBSTRING("",START_INDEX,LENGTH)
|
|
public void ParseSubstring()
|
|
{
|
|
InsertSymbols(new ParseSymbol(Scanner.ScanSymbols.leftparen1));
|
|
Expect(Scanner.ScanSymbols.substring1);
|
|
InsertSymbols(new ParseSymbol(Scanner.ScanSymbols.literal1));
|
|
InsertSymbols(new ParseSymbol(Scanner.ScanSymbols.variable1));
|
|
InsertSymbols(directiveSymbols);
|
|
Expect(Scanner.ScanSymbols.leftparen1);
|
|
RemoveSymbols(directiveSymbols);
|
|
RemoveSymbols(new ParseSymbol(Scanner.ScanSymbols.leftparen1));
|
|
RemoveSymbols(new ParseSymbol(Scanner.ScanSymbols.variable1));
|
|
RemoveSymbols(new ParseSymbol(Scanner.ScanSymbols.literal1));
|
|
InsertSymbols(new ParseSymbol(Scanner.ScanSymbols.comma1));
|
|
Expression();
|
|
RemoveSymbols(new ParseSymbol(Scanner.ScanSymbols.comma1));
|
|
InsertSymbols(new ParseSymbol(Scanner.ScanSymbols.numeral1));
|
|
InsertSymbols(new ParseSymbol(Scanner.ScanSymbols.variable1));
|
|
Expect(Scanner.ScanSymbols.comma1);
|
|
RemoveSymbols(new ParseSymbol(Scanner.ScanSymbols.variable1));
|
|
InsertSymbols(new ParseSymbol(Scanner.ScanSymbols.comma1));
|
|
RemoveSymbols(new ParseSymbol(Scanner.ScanSymbols.numeral1));
|
|
Expression();
|
|
RemoveSymbols(new ParseSymbol(Scanner.ScanSymbols.comma1));
|
|
InsertSymbols(new ParseSymbol(Scanner.ScanSymbols.numeral1));
|
|
InsertSymbols(new ParseSymbol(Scanner.ScanSymbols.variable1));
|
|
Expect(Scanner.ScanSymbols.comma1);
|
|
RemoveSymbols(new ParseSymbol(Scanner.ScanSymbols.numeral1));
|
|
RemoveSymbols(new ParseSymbol(Scanner.ScanSymbols.variable1));
|
|
InsertSymbols(new ParseSymbol(Scanner.ScanSymbols.rightparen1));
|
|
Expression();
|
|
RemoveSymbols(new ParseSymbol(Scanner.ScanSymbols.rightparen1));
|
|
InsertSymbols(addSymbols);
|
|
Expect(Scanner.ScanSymbols.rightparen1);
|
|
RemoveSymbols(addSymbols);
|
|
Symbol namedFunction = symbolTable.Find(Scanner.ScanSymbols.substring1);
|
|
Emit(Parser.ParserSymbols.call2,namedFunction.SymbolName,3);
|
|
}
|
|
// GETPRICE("MIDD",'07-13-2021','OPEN') 'OPEN'|'HIGH'|'LOW'|'CLOSE'
|
|
public void ParseGetPrice()
|
|
{
|
|
InsertSymbols(new ParseSymbol(Scanner.ScanSymbols.leftparen1));
|
|
Expect(Scanner.ScanSymbols.getprice1);
|
|
InsertSymbols(new ParseSymbol(Scanner.ScanSymbols.literal1));
|
|
InsertSymbols(new ParseSymbol(Scanner.ScanSymbols.variable1));
|
|
InsertSymbols(directiveSymbols);
|
|
Expect(Scanner.ScanSymbols.leftparen1);
|
|
RemoveSymbols(directiveSymbols);
|
|
RemoveSymbols(new ParseSymbol(Scanner.ScanSymbols.leftparen1));
|
|
RemoveSymbols(new ParseSymbol(Scanner.ScanSymbols.variable1));
|
|
RemoveSymbols(new ParseSymbol(Scanner.ScanSymbols.literal1));
|
|
InsertSymbols(new ParseSymbol(Scanner.ScanSymbols.comma1));
|
|
Expression();
|
|
RemoveSymbols(new ParseSymbol(Scanner.ScanSymbols.comma1));
|
|
InsertSymbols(new ParseSymbol(Scanner.ScanSymbols.literal1));
|
|
InsertSymbols(new ParseSymbol(Scanner.ScanSymbols.variable1));
|
|
Expect(Scanner.ScanSymbols.comma1);
|
|
RemoveSymbols(new ParseSymbol(Scanner.ScanSymbols.variable1));
|
|
RemoveSymbols(new ParseSymbol(Scanner.ScanSymbols.literal1));
|
|
InsertSymbols(new ParseSymbol(Scanner.ScanSymbols.comma1));
|
|
Expression();
|
|
RemoveSymbols(new ParseSymbol(Scanner.ScanSymbols.comma1));
|
|
InsertSymbols(new ParseSymbol(Scanner.ScanSymbols.literal1));
|
|
InsertSymbols(new ParseSymbol(Scanner.ScanSymbols.variable1));
|
|
Expect(Scanner.ScanSymbols.comma1);
|
|
RemoveSymbols(new ParseSymbol(Scanner.ScanSymbols.variable1));
|
|
RemoveSymbols(new ParseSymbol(Scanner.ScanSymbols.literal1));
|
|
InsertSymbols(new ParseSymbol(Scanner.ScanSymbols.rightparen1));
|
|
Expression();
|
|
RemoveSymbols(new ParseSymbol(Scanner.ScanSymbols.rightparen1));
|
|
InsertSymbols(addSymbols);
|
|
Expect(Scanner.ScanSymbols.rightparen1);
|
|
RemoveSymbols(addSymbols);
|
|
Symbol namedFunction = symbolTable.Find(Scanner.ScanSymbols.getprice1);
|
|
Emit(Parser.ParserSymbols.call2,namedFunction.SymbolName,3);
|
|
}
|
|
public void ParseConvert()
|
|
{
|
|
InsertSymbols(addSymbols);
|
|
InsertSymbols(mathSymbols);
|
|
InsertSymbols(new ParseSymbol(Scanner.ScanSymbols.leftparen1));
|
|
Expect(Scanner.ScanSymbols.convert1);
|
|
InsertSymbols(new ParseSymbol(Scanner.ScanSymbols.literal1));
|
|
InsertSymbols(new ParseSymbol(Scanner.ScanSymbols.variable1));
|
|
Expect(Scanner.ScanSymbols.leftparen1);
|
|
RemoveSymbols(new ParseSymbol(Scanner.ScanSymbols.leftparen1));
|
|
RemoveSymbols(new ParseSymbol(Scanner.ScanSymbols.variable1));
|
|
RemoveSymbols(new ParseSymbol(Scanner.ScanSymbols.literal1));
|
|
if (SymbolIn(new ParseSymbol(Scanner.ScanSymbols.literal1)))
|
|
{
|
|
Emit(Parser.ParserSymbols.push2,stringValue);
|
|
InsertSymbols(new ParseSymbol(Scanner.ScanSymbols.comma1));
|
|
Expect(Scanner.ScanSymbols.literal1);
|
|
RemoveSymbols(new ParseSymbol(Scanner.ScanSymbols.comma1));
|
|
}
|
|
else if (SymbolIn(new ParseSymbol(Scanner.ScanSymbols.variable1)))
|
|
{
|
|
VariableAccess();
|
|
}
|
|
else SyntaxError();
|
|
InsertSymbols(new ParseSymbol(Scanner.ScanSymbols.comma1));
|
|
RemoveSymbols(new ParseSymbol(Scanner.ScanSymbols.comma1));
|
|
InsertSymbols(new ParseSymbol(Scanner.ScanSymbols.literal1));
|
|
InsertSymbols(new ParseSymbol(Scanner.ScanSymbols.variable1));
|
|
Expect(Scanner.ScanSymbols.comma1);
|
|
RemoveSymbols(new ParseSymbol(Scanner.ScanSymbols.leftparen1));
|
|
RemoveSymbols(new ParseSymbol(Scanner.ScanSymbols.variable1));
|
|
InsertSymbols(new ParseSymbol(Scanner.ScanSymbols.rightparen1));
|
|
RemoveSymbols(new ParseSymbol(Scanner.ScanSymbols.literal1));
|
|
if (SymbolIn(new ParseSymbol(Scanner.ScanSymbols.literal1)))
|
|
{
|
|
Emit(Parser.ParserSymbols.push2,stringValue);
|
|
Expect(Scanner.ScanSymbols.literal1);
|
|
}
|
|
else if (SymbolIn(new ParseSymbol(Scanner.ScanSymbols.variable1)))
|
|
{
|
|
VariableAccess();
|
|
}
|
|
else SyntaxError();
|
|
RemoveSymbols(new ParseSymbol(Scanner.ScanSymbols.rightparen1));
|
|
InsertSymbols(addSymbols);
|
|
InsertSymbols(mathSymbols);
|
|
Expect(Scanner.ScanSymbols.rightparen1);
|
|
RemoveSymbols(addSymbols);
|
|
RemoveSymbols(mathSymbols);
|
|
Symbol namedFunction = symbolTable.Find(Scanner.ScanSymbols.convert1);
|
|
Emit(Parser.ParserSymbols.call2,namedFunction.SymbolName,2);
|
|
RemoveSymbols(addSymbols);
|
|
RemoveSymbols(mathSymbols);
|
|
}
|
|
public void ParseABS()
|
|
{
|
|
InsertSymbols(addSymbols);
|
|
InsertSymbols(mathSymbols);
|
|
InsertSymbols(new ParseSymbol(Scanner.ScanSymbols.leftparen1));
|
|
Expect(Scanner.ScanSymbols.abs1);
|
|
InsertSymbols(expressionSymbols);
|
|
RemoveSymbols(new ParseSymbol(Scanner.ScanSymbols.leftparen1));
|
|
Expect(Scanner.ScanSymbols.leftparen1);
|
|
InsertSymbols(new ParseSymbol(Scanner.ScanSymbols.rightparen1));
|
|
Expression();
|
|
RemoveSymbols(expressionSymbols);
|
|
RemoveSymbols(new ParseSymbol(Scanner.ScanSymbols.rightparen1));
|
|
InsertSymbols(addSymbols);
|
|
InsertSymbols(mathSymbols);
|
|
Expect(Scanner.ScanSymbols.rightparen1);
|
|
RemoveSymbols(addSymbols);
|
|
RemoveSymbols(mathSymbols);
|
|
Symbol namedFunction = symbolTable.Find(Scanner.ScanSymbols.abs1);
|
|
Emit(Parser.ParserSymbols.call2,namedFunction.SymbolName,1);
|
|
RemoveSymbols(addSymbols);
|
|
RemoveSymbols(mathSymbols);
|
|
}
|
|
public void ParseSQRT()
|
|
{
|
|
InsertSymbols(addSymbols);
|
|
InsertSymbols(mathSymbols);
|
|
InsertSymbols(new ParseSymbol(Scanner.ScanSymbols.leftparen1));
|
|
Expect(Scanner.ScanSymbols.sqrt1);
|
|
InsertSymbols(expressionSymbols);
|
|
RemoveSymbols(new ParseSymbol(Scanner.ScanSymbols.leftparen1));
|
|
Expect(Scanner.ScanSymbols.leftparen1);
|
|
InsertSymbols(new ParseSymbol(Scanner.ScanSymbols.rightparen1));
|
|
Expression();
|
|
RemoveSymbols(expressionSymbols);
|
|
RemoveSymbols(new ParseSymbol(Scanner.ScanSymbols.rightparen1));
|
|
InsertSymbols(addSymbols);
|
|
InsertSymbols(mathSymbols);
|
|
Expect(Scanner.ScanSymbols.rightparen1);
|
|
RemoveSymbols(addSymbols);
|
|
RemoveSymbols(mathSymbols);
|
|
Symbol namedFunction = symbolTable.Find(Scanner.ScanSymbols.sqrt1);
|
|
Emit(Parser.ParserSymbols.call2,namedFunction.SymbolName,1);
|
|
RemoveSymbols(addSymbols);
|
|
RemoveSymbols(mathSymbols);
|
|
}
|
|
public void ParsePOW()
|
|
{
|
|
InsertSymbols(addSymbols);
|
|
InsertSymbols(mathSymbols);
|
|
InsertSymbols(new ParseSymbol(Scanner.ScanSymbols.leftparen1));
|
|
Expect(Scanner.ScanSymbols.pow1);
|
|
InsertSymbols(new ParseSymbol(Scanner.ScanSymbols.numeral1));
|
|
InsertSymbols(new ParseSymbol(Scanner.ScanSymbols.variable1));
|
|
InsertSymbols(directiveSymbols);
|
|
Expect(Scanner.ScanSymbols.leftparen1);
|
|
RemoveSymbols(directiveSymbols);
|
|
RemoveSymbols(new ParseSymbol(Scanner.ScanSymbols.leftparen1));
|
|
RemoveSymbols(new ParseSymbol(Scanner.ScanSymbols.variable1));
|
|
RemoveSymbols(new ParseSymbol(Scanner.ScanSymbols.numeral1));
|
|
InsertSymbols(new ParseSymbol(Scanner.ScanSymbols.comma1));
|
|
Expression();
|
|
RemoveSymbols(new ParseSymbol(Scanner.ScanSymbols.comma1));
|
|
InsertSymbols(new ParseSymbol(Scanner.ScanSymbols.numeral1));
|
|
InsertSymbols(new ParseSymbol(Scanner.ScanSymbols.variable1));
|
|
InsertSymbols(directiveSymbols);
|
|
Expect(Scanner.ScanSymbols.comma1);
|
|
RemoveSymbols(directiveSymbols);
|
|
RemoveSymbols(new ParseSymbol(Scanner.ScanSymbols.leftparen1));
|
|
RemoveSymbols(new ParseSymbol(Scanner.ScanSymbols.variable1));
|
|
RemoveSymbols(new ParseSymbol(Scanner.ScanSymbols.numeral1));
|
|
InsertSymbols(new ParseSymbol(Scanner.ScanSymbols.rightparen1));
|
|
Expression();
|
|
RemoveSymbols(new ParseSymbol(Scanner.ScanSymbols.rightparen1));
|
|
InsertSymbols(addSymbols);
|
|
InsertSymbols(mathSymbols);
|
|
Expect(Scanner.ScanSymbols.rightparen1);
|
|
RemoveSymbols(addSymbols);
|
|
RemoveSymbols(mathSymbols);
|
|
Symbol namedFunction = symbolTable.Find(Scanner.ScanSymbols.pow1);
|
|
Emit(Parser.ParserSymbols.call2,namedFunction.SymbolName,2);
|
|
RemoveSymbols(addSymbols);
|
|
RemoveSymbols(mathSymbols);
|
|
}
|
|
// ******************************************************************************************************************************************************************************************************************
|
|
// ***************************************************************************************************** B U I L T - I N B O O L E A N **********************************************************************************************
|
|
// ******************************************************************************************************************************************************************************************************************
|
|
public void ParseIn()
|
|
{
|
|
int arguments = 0;
|
|
Symbol namedFunction = symbolTable.Find(Scanner.ScanSymbols.in1);
|
|
InsertSymbols(new ParseSymbol(Scanner.ScanSymbols.leftparen1));
|
|
Expect(Scanner.ScanSymbols.in1);
|
|
InsertSymbols(new ParseSymbol(Scanner.ScanSymbols.literal1));
|
|
InsertSymbols(new ParseSymbol(Scanner.ScanSymbols.variable1));
|
|
Expect(Scanner.ScanSymbols.leftparen1);
|
|
RemoveSymbols(new ParseSymbol(Scanner.ScanSymbols.leftparen1));
|
|
while (!IsInError)
|
|
{
|
|
if (SymbolIn(new ParseSymbol(Scanner.ScanSymbols.rightparen1))) break;
|
|
if (SymbolIn(new ParseSymbol(Scanner.ScanSymbols.literal1)))
|
|
{
|
|
Emit(Parser.ParserSymbols.push2,stringValue);
|
|
arguments++;
|
|
InsertSymbols(new ParseSymbol(Scanner.ScanSymbols.comma1));
|
|
InsertSymbols(new ParseSymbol(Scanner.ScanSymbols.rightparen1));
|
|
Expect(Scanner.ScanSymbols.literal1);
|
|
RemoveSymbols(new ParseSymbol(Scanner.ScanSymbols.comma1));
|
|
RemoveSymbols(new ParseSymbol(Scanner.ScanSymbols.rightparen1));
|
|
}
|
|
else if (SymbolIn(new ParseSymbol(Scanner.ScanSymbols.variable1)))
|
|
{
|
|
InsertSymbols(new ParseSymbol(Scanner.ScanSymbols.rightparen1));
|
|
VariableAccess();
|
|
RemoveSymbols(new ParseSymbol(Scanner.ScanSymbols.rightparen1));
|
|
arguments++;
|
|
}
|
|
if (SymbolIn(new ParseSymbol(Scanner.ScanSymbols.comma1)))
|
|
{
|
|
Expect(Scanner.ScanSymbols.comma1);
|
|
}
|
|
}
|
|
InsertSymbols(new ParseSymbol(Scanner.ScanSymbols.rightparen1));
|
|
Expect(Scanner.ScanSymbols.rightparen1);
|
|
RemoveSymbols(new ParseSymbol(Scanner.ScanSymbols.rightparen1));
|
|
RemoveSymbols(new ParseSymbol(Scanner.ScanSymbols.literal1));
|
|
RemoveSymbols(new ParseSymbol(Scanner.ScanSymbols.variable1));
|
|
Emit(Parser.ParserSymbols.call2,namedFunction.SymbolName,arguments);
|
|
}
|
|
public void ParseIsNull()
|
|
{
|
|
int arguments = 0;
|
|
Symbol namedFunction = symbolTable.Find(Scanner.ScanSymbols.isnull1);
|
|
InsertSymbols(new ParseSymbol(Scanner.ScanSymbols.leftparen1));
|
|
Expect(Scanner.ScanSymbols.isnull1);
|
|
InsertSymbols(new ParseSymbol(Scanner.ScanSymbols.literal1));
|
|
InsertSymbols(new ParseSymbol(Scanner.ScanSymbols.variable1));
|
|
Expect(Scanner.ScanSymbols.leftparen1);
|
|
RemoveSymbols(new ParseSymbol(Scanner.ScanSymbols.leftparen1));
|
|
while (!IsInError)
|
|
{
|
|
if (SymbolIn(new ParseSymbol(Scanner.ScanSymbols.rightparen1))) break;
|
|
if (SymbolIn(new ParseSymbol(Scanner.ScanSymbols.literal1)))
|
|
{
|
|
Emit(Parser.ParserSymbols.push2, stringValue);
|
|
arguments++;
|
|
InsertSymbols(new ParseSymbol(Scanner.ScanSymbols.comma1));
|
|
InsertSymbols(new ParseSymbol(Scanner.ScanSymbols.rightparen1));
|
|
Expect(Scanner.ScanSymbols.literal1);
|
|
RemoveSymbols(new ParseSymbol(Scanner.ScanSymbols.comma1));
|
|
RemoveSymbols(new ParseSymbol(Scanner.ScanSymbols.rightparen1));
|
|
}
|
|
else if (SymbolIn(new ParseSymbol(Scanner.ScanSymbols.variable1)))
|
|
{
|
|
InsertSymbols(new ParseSymbol(Scanner.ScanSymbols.rightparen1));
|
|
InsertSymbols(new ParseSymbol(Scanner.ScanSymbols.comma1));
|
|
VariableAccess();
|
|
RemoveSymbols(new ParseSymbol(Scanner.ScanSymbols.rightparen1));
|
|
RemoveSymbols(new ParseSymbol(Scanner.ScanSymbols.comma1));
|
|
arguments++;
|
|
}
|
|
else if (SymbolIn(new ParseSymbol(Scanner.ScanSymbols.numeral1)))
|
|
{
|
|
InsertSymbols(new ParseSymbol(Scanner.ScanSymbols.rightparen1));
|
|
InsertSymbols(new ParseSymbol(Scanner.ScanSymbols.comma1));
|
|
Emit(Parser.ParserSymbols.push2, numeralValue);
|
|
Expect(Scanner.ScanSymbols.numeral1);
|
|
arguments++;
|
|
RemoveSymbols(new ParseSymbol(Scanner.ScanSymbols.rightparen1));
|
|
RemoveSymbols(new ParseSymbol(Scanner.ScanSymbols.comma1));
|
|
}
|
|
else SyntaxError();
|
|
if (SymbolIn(new ParseSymbol(Scanner.ScanSymbols.comma1)))
|
|
{
|
|
Expect(Scanner.ScanSymbols.comma1);
|
|
}
|
|
}
|
|
InsertSymbols(new ParseSymbol(Scanner.ScanSymbols.rightparen1));
|
|
Expect(Scanner.ScanSymbols.rightparen1);
|
|
RemoveSymbols(new ParseSymbol(Scanner.ScanSymbols.rightparen1));
|
|
RemoveSymbols(new ParseSymbol(Scanner.ScanSymbols.literal1));
|
|
RemoveSymbols(new ParseSymbol(Scanner.ScanSymbols.variable1));
|
|
Emit(Parser.ParserSymbols.call2,namedFunction.SymbolName,arguments);
|
|
}
|
|
// *******************************************************************************************************************************************************************************************************************************************************************
|
|
// ************************************************************************************************************ E N D B U I L T - I N F U N C T I O N S ******************************************************************************************************************
|
|
// *******************************************************************************************************************************************************************************************************************************************************************
|
|
public void Term()
|
|
{
|
|
InsertSymbols(mathSymbols);
|
|
InsertSymbols(relationSymbols);
|
|
Factor();
|
|
RemoveSymbols(relationSymbols);
|
|
SimpleTerm();
|
|
RemoveSymbols(mathSymbols);
|
|
return;
|
|
}
|
|
public void SimpleTerm()
|
|
{
|
|
while (SymbolIn(mathSymbols))
|
|
{
|
|
Scanner.ScanSymbols currSymbol = currentSymbolType;
|
|
InsertSymbols(factorSymbols);
|
|
InsertSymbols(mathFunctionSymbols);
|
|
Expect(currentSymbolType);
|
|
RemoveSymbols(factorSymbols);
|
|
RemoveSymbols(mathFunctionSymbols);
|
|
Factor();
|
|
if (Scanner.ScanSymbols.asterisk1.Equals(currSymbol))
|
|
{
|
|
Emit(Parser.ParserSymbols.multiply2);
|
|
}
|
|
else if (Scanner.ScanSymbols.divide1.Equals(currSymbol))
|
|
{
|
|
Emit(Parser.ParserSymbols.divide2);
|
|
}
|
|
}
|
|
}
|
|
public void Factor()
|
|
{
|
|
if (SymbolIn(new ParseSymbol(Scanner.ScanSymbols.numeral1)))
|
|
{
|
|
Emit(Parser.ParserSymbols.push2, numeralValue);
|
|
Expect(currentSymbolType);
|
|
if (SymbolIn(relationSymbols)) Relation();
|
|
SyntaxCheck();
|
|
}
|
|
else if (SymbolIn(new ParseSymbol(Scanner.ScanSymbols.variable1)))
|
|
{
|
|
VariableAccess();
|
|
if (SymbolIn(new ParseSymbol(Scanner.ScanSymbols.in1))) ParseIn();
|
|
else if(SymbolIn(new ParseSymbol(Scanner.ScanSymbols.like1)))ParseLike();
|
|
else if(SymbolIn(new ParseSymbol(Scanner.ScanSymbols.like1)))ParseTrim();
|
|
else if (SymbolIn(relationSymbols)) Relation();
|
|
SyntaxCheck();
|
|
}
|
|
else if (SymbolIn(new ParseSymbol(Scanner.ScanSymbols.literal1)))
|
|
{
|
|
Emit(Parser.ParserSymbols.push2,stringValue);
|
|
Expect(currentSymbolType);
|
|
SyntaxCheck();
|
|
}
|
|
else if (SymbolIn(new ParseSymbol(Scanner.ScanSymbols.null1)))
|
|
{
|
|
EmitAsNull(Parser.ParserSymbols.push2);
|
|
Expect(currentSymbolType);
|
|
SyntaxCheck();
|
|
}
|
|
else if (SymbolIn(new ParseSymbol(Scanner.ScanSymbols.leftparen1)))
|
|
{
|
|
InsertSymbols(new ParseSymbol(Scanner.ScanSymbols.rightparen1));
|
|
InsertSymbols(expressionSymbols);
|
|
InsertSymbols(directiveSymbols);
|
|
Expect(currentSymbolType);
|
|
RemoveSymbols(directiveSymbols);
|
|
RemoveSymbols(expressionSymbols);
|
|
if (SymbolIn(directiveSymbols)) Directive();
|
|
Expression();
|
|
Relation();
|
|
Expect(Scanner.ScanSymbols.rightparen1);
|
|
RemoveSymbols(new ParseSymbol(Scanner.ScanSymbols.rightparen1));
|
|
SyntaxCheck();
|
|
}
|
|
else if (SymbolIn(directiveSymbols))
|
|
{
|
|
Directive();
|
|
}
|
|
else if (SymbolIn(new ParseSymbol(Scanner.ScanSymbols.minus1)))
|
|
{
|
|
SimpleExpression();
|
|
}
|
|
else
|
|
{
|
|
SyntaxError();
|
|
}
|
|
}
|
|
public void Expression()
|
|
{
|
|
while (SymbolIn(expressionSymbols)||SymbolIn(directiveSymbols))
|
|
{
|
|
SimpleExpression();
|
|
}
|
|
}
|
|
public void SimpleExpression()
|
|
{
|
|
InsertSymbols(addSymbols);
|
|
InsertSymbols(termSymbols);
|
|
InsertSymbols(signSymbols);
|
|
InsertSymbols(directiveSymbols);
|
|
InsertSymbols(new ParseSymbol(Scanner.ScanSymbols.variable1));
|
|
InsertSymbols(new ParseSymbol(Scanner.ScanSymbols.literal1));
|
|
InsertSymbols(new ParseSymbol(Scanner.ScanSymbols.null1));
|
|
SyntaxCheck();
|
|
RemoveSymbols(signSymbols);
|
|
RemoveSymbols(directiveSymbols);
|
|
if (SymbolIn(signSymbols))
|
|
{
|
|
Scanner.ScanSymbols currSymbol = currentSymbolType;
|
|
Expect(currentSymbolType);
|
|
if (Scanner.ScanSymbols.minus1.Equals(currSymbol))
|
|
{
|
|
if(SymbolIn(new ParseSymbol(Scanner.ScanSymbols.numeral1)))
|
|
{
|
|
Emit(Parser.ParserSymbols.push2, numeralValue);
|
|
Expect(Scanner.ScanSymbols.numeral1);
|
|
}
|
|
else if(SymbolIn(new ParseSymbol(Scanner.ScanSymbols.variable1)))
|
|
{
|
|
VariableAccess();
|
|
}
|
|
else SyntaxError();
|
|
Emit(Parser.ParserSymbols.negate2);
|
|
}
|
|
else if (Scanner.ScanSymbols.plus1.Equals(currSymbol))
|
|
{
|
|
if(SymbolIn(new ParseSymbol(Scanner.ScanSymbols.numeral1)))
|
|
{
|
|
Emit(Parser.ParserSymbols.push2, numeralValue);
|
|
Expect(Scanner.ScanSymbols.numeral1);
|
|
}
|
|
else if(SymbolIn(new ParseSymbol(Scanner.ScanSymbols.variable1)))
|
|
{
|
|
VariableAccess();
|
|
}
|
|
//else if(SymbolIn(new ParseSymbol(Scanner.ScanSymbols.convert1))) // sean 09/06 I think this needs to be al of the directive symbols
|
|
//{
|
|
// ParseConvert();
|
|
//}
|
|
else if(SymbolIn(directiveSymbols)) // sean 09/06 I think this needs to be al of the directive symbols
|
|
{
|
|
Directive();
|
|
}
|
|
else SyntaxError();
|
|
Emit(Parser.ParserSymbols.add2);
|
|
}
|
|
else if (Scanner.ScanSymbols.not1.Equals(currSymbol))
|
|
{
|
|
if(SymbolIn(new ParseSymbol(Scanner.ScanSymbols.numeral1)))
|
|
{
|
|
Emit(Parser.ParserSymbols.push2, numeralValue);
|
|
Expect(Scanner.ScanSymbols.numeral1);
|
|
}
|
|
else if(SymbolIn(new ParseSymbol(Scanner.ScanSymbols.variable1)))
|
|
{
|
|
VariableAccess();
|
|
}
|
|
else SyntaxError();
|
|
Emit(Parser.ParserSymbols.not2);
|
|
}
|
|
RemoveSymbols(termSymbols);
|
|
}
|
|
else
|
|
{
|
|
RemoveSymbols(termSymbols);
|
|
Term();
|
|
}
|
|
RemoveSymbols(new ParseSymbol(Scanner.ScanSymbols.variable1));
|
|
RemoveSymbols(new ParseSymbol(Scanner.ScanSymbols.literal1));
|
|
RemoveSymbols(new ParseSymbol(Scanner.ScanSymbols.null1));
|
|
while (SymbolIn(addSymbols))
|
|
{
|
|
Scanner.ScanSymbols currSymbol = currentSymbolType;
|
|
InsertSymbols(termSymbols);
|
|
InsertSymbols(new ParseSymbol(Scanner.ScanSymbols.variable1));
|
|
InsertSymbols(new ParseSymbol(Scanner.ScanSymbols.literal1));
|
|
InsertSymbols(new ParseSymbol(Scanner.ScanSymbols.null1));
|
|
InsertSymbols(new ParseSymbol(Scanner.ScanSymbols.isnull1));
|
|
InsertSymbols(stringManipulationSymbols);
|
|
Expect(currentSymbolType);
|
|
RemoveSymbols(stringManipulationSymbols);
|
|
RemoveSymbols(new ParseSymbol(Scanner.ScanSymbols.variable1));
|
|
RemoveSymbols(new ParseSymbol(Scanner.ScanSymbols.literal1));
|
|
RemoveSymbols(new ParseSymbol(Scanner.ScanSymbols.null1));
|
|
RemoveSymbols(new ParseSymbol(Scanner.ScanSymbols.isnull1));
|
|
RemoveSymbols(termSymbols);
|
|
Term();
|
|
if (Scanner.ScanSymbols.plus1.Equals(currSymbol))
|
|
{
|
|
Emit(ParserSymbols.add2);
|
|
}
|
|
else if (Scanner.ScanSymbols.minus1.Equals(currSymbol))
|
|
{
|
|
Emit(ParserSymbols.subtract2);
|
|
}
|
|
else SyntaxError();
|
|
}
|
|
RemoveSymbols(addSymbols);
|
|
}
|
|
// *********************************************************************************************************************************************************************************************************************
|
|
// ******************************************************************************************************* S Y M B O L M A N A G E M E N T **************************************************************************
|
|
// *********************************************************************************************************************************************************************************************************************
|
|
public bool NextSymbol()
|
|
{
|
|
numeralValue = 0.00;
|
|
int code = 0;
|
|
int result = Read(ref code);
|
|
if (result == 0xFFFF) return false;
|
|
currentSymbolType = (Scanner.ScanSymbols)code;
|
|
while (Scanner.ScanSymbols.newline1.Equals(currentSymbolType))
|
|
{
|
|
if (0xFFFF == Read(ref code)) return false;
|
|
currentSymbolType=(Scanner.ScanSymbols)code;
|
|
LineNumber++;
|
|
SymbolNumber=-1; // make sure the symbol number is relative zero so it conforms to the rest of the line numbers (which are relative zero)
|
|
}
|
|
if (Scanner.ScanSymbols.numeral1.Equals(currentSymbolType))
|
|
{
|
|
SymbolNumber++;
|
|
Read(ref numeralValue);
|
|
}
|
|
else if (Scanner.ScanSymbols.label1.Equals(currentSymbolType))
|
|
{
|
|
SymbolNumber++;
|
|
Read(ref stringValue);
|
|
}
|
|
else if (Scanner.ScanSymbols.literal1.Equals(currentSymbolType))
|
|
{
|
|
SymbolNumber++;
|
|
Read(ref stringValue);
|
|
}
|
|
else if (Scanner.ScanSymbols.variable1.Equals(currentSymbolType))
|
|
{
|
|
SymbolNumber++;
|
|
Read(ref stringValue);
|
|
}
|
|
else if(Scanner.ScanSymbols.unknown1.Equals(currentSymbolType))
|
|
{
|
|
SymbolNumber++;
|
|
Read(ref stringValue);
|
|
SyntaxError();
|
|
}
|
|
return true;
|
|
}
|
|
public bool SymbolIn(ParseSymbols parseSymbols)
|
|
{
|
|
return parseSymbols.SymbolIn(new ParseSymbol(currentSymbolType));
|
|
}
|
|
public bool SymbolIn(ParseSymbol parseSymbol)
|
|
{
|
|
return new ParseSymbol(currentSymbolType).Equals(parseSymbol);
|
|
}
|
|
public bool PeekSymbol(ParseSymbol parseSymbol)
|
|
{
|
|
Scanner.ScanSymbols peekSymbol;
|
|
int intPeek = 0;
|
|
// PeekIgnore(ref intPeek,(int)Scanner.ScanSymbols.newline1);
|
|
PeekIgnore(ref intPeek,new int[]{(int)Scanner.ScanSymbols.newline1,(int)Scanner.ScanSymbols.unknown1});
|
|
peekSymbol = (Scanner.ScanSymbols)intPeek;
|
|
if (new ParseSymbol(peekSymbol).Equals(parseSymbol)) return true;
|
|
return false;
|
|
}
|
|
public bool PeekSymbolIn(ParseSymbols parseSymbols)
|
|
{
|
|
Scanner.ScanSymbols peekSymbol;
|
|
int intPeek = 0;
|
|
PeekIgnore(ref intPeek,new int[]{(int)Scanner.ScanSymbols.newline1,(int)Scanner.ScanSymbols.unknown1});
|
|
peekSymbol = (Scanner.ScanSymbols)intPeek;
|
|
return parseSymbols.SymbolIn(peekSymbol);
|
|
}
|
|
public void Expect(Scanner.ScanSymbols symbol)
|
|
{
|
|
if (symbol.Equals(currentSymbolType)) NextSymbol();
|
|
else SyntaxError(symbol);
|
|
SyntaxCheck();
|
|
}
|
|
|
|
public long SymbolCount()
|
|
{
|
|
return parseSymbols.Count;
|
|
}
|
|
|
|
public void InsertSymbols(ParseSymbols groupSymbols)
|
|
{
|
|
parseSymbols.InsertSymbols(groupSymbols);
|
|
}
|
|
public void RemoveSymbols(ParseSymbols removeSymbols)
|
|
{
|
|
parseSymbols.RemoveSymbols(removeSymbols);
|
|
}
|
|
public void InsertSymbols(ParseSymbol parseSymbol)
|
|
{
|
|
parseSymbols.InsertSymbols(parseSymbol);
|
|
}
|
|
public void RemoveSymbols(ParseSymbol parseSymbol)
|
|
{
|
|
parseSymbols.RemoveSymbols(parseSymbol);
|
|
}
|
|
public bool IsInError { get; set; }
|
|
public int LineNumber { get; set; }
|
|
public int LastLineNumber { get; set; }
|
|
public int SymbolNumber { get; set; }
|
|
public int LastSymbolNumber { get; set; }
|
|
public int StatementNumber { get; set; }
|
|
public int LastStatementNumber { get; set; }
|
|
public String LastMessage { get; set; }
|
|
// **************************************************************************************************************************************************************************************************************
|
|
// ******************************************************************************************************* E R R O R H A N D L I N G **************************************************************************
|
|
// **************************************************************************************************************************************************************************************************************
|
|
public void SyntaxCheck()
|
|
{
|
|
if (!parseSymbols.SymbolIn(currentSymbolType)) SyntaxError();
|
|
}
|
|
public void SyntaxError(Scanner.ScanSymbols symbol)
|
|
{
|
|
ErrorExpect(symbol);
|
|
while (!parseSymbols.SymbolIn(currentSymbolType) && NextSymbol()) ;
|
|
}
|
|
public void SyntaxError(String specificError)
|
|
{
|
|
if (!IsInError)
|
|
{
|
|
LastMessage=String.Format("<Syntax Error> {0} at line: {1} statement: {2} symbol: {3}",specificError,LineNumber,StatementNumber,SymbolNumber);
|
|
LastLineNumber = LineNumber;
|
|
LastSymbolNumber = SymbolNumber;
|
|
LastStatementNumber = StatementNumber;
|
|
IsInError = true;
|
|
}
|
|
}
|
|
public void SyntaxError()
|
|
{
|
|
if (!IsInError)
|
|
{
|
|
if(Scanner.ScanSymbols.unknown1.Equals(currentSymbolType))LastMessage = String.Format("<Syntax Error> Unexpected Symbol '{0}' at line: {1} statement: {2} symbol: {3}",stringValue,LineNumber,StatementNumber,SymbolNumber);
|
|
else LastMessage = String.Format("<Syntax Error> Unexpected Symbol '{0}' at line: {1} statement: {2} symbol: {3}",Scanner.SymbolToLiteralString(currentSymbolType),LineNumber,StatementNumber,SymbolNumber);
|
|
LastLineNumber = LineNumber;
|
|
LastSymbolNumber = SymbolNumber;
|
|
LastStatementNumber = StatementNumber;
|
|
IsInError = true;
|
|
}
|
|
while (!parseSymbols.SymbolIn(currentSymbolType) && NextSymbol()) ;
|
|
}
|
|
void ErrorExpect(Scanner.ScanSymbols symbolType)
|
|
{
|
|
if (IsInError) return;
|
|
LastMessage=String.Format("<Syntax Error> Expected Symbol {0} at line: {1} statement: {2} symbol: {3}",Scanner.SymbolToLiteralString(symbolType),LineNumber,StatementNumber,SymbolNumber);
|
|
LastLineNumber = LineNumber;
|
|
LastSymbolNumber = SymbolNumber;
|
|
LastStatementNumber = StatementNumber;
|
|
IsInError = true;
|
|
}
|
|
public void Error(Parser.ErrorCodes errorCode, String message = null)
|
|
{
|
|
if (IsInError) return;
|
|
switch (errorCode)
|
|
{
|
|
case Parser.ErrorCodes.DivideByZero :
|
|
LastMessage = "<Divide by zero>";
|
|
LastLineNumber = LineNumber;
|
|
break;
|
|
}
|
|
}
|
|
// ***********************************************************************************************************************************************************************************************************************************************
|
|
// ***************************************************************************************************** C R E A T E S Y M B O L S ************************************************************************************************************
|
|
// ***********************************************************************************************************************************************************************************************************************************************
|
|
private void CreateDeclarationSymbols()
|
|
{
|
|
declarationSymbols.Clear();
|
|
declarationSymbols.Add(new ParseSymbol(Scanner.ScanSymbols.declare1));
|
|
}
|
|
private void CreateAssignmentStatementSymbols()
|
|
{
|
|
assignmentStatementSymbols.Clear();
|
|
assignmentStatementSymbols.Add(new ParseSymbol(Scanner.ScanSymbols.equal1));
|
|
}
|
|
private void CreateStatementSymbols()
|
|
{
|
|
statementSymbols.Clear();
|
|
statementSymbols.Add(new ParseSymbol(Scanner.ScanSymbols.variable1));
|
|
statementSymbols.Add(new ParseSymbol(Scanner.ScanSymbols.label1));
|
|
statementSymbols.Add(new ParseSymbol(Scanner.ScanSymbols.literal1));
|
|
statementSymbols.Add(new ParseSymbol(Scanner.ScanSymbols.if1));
|
|
statementSymbols.Add(new ParseSymbol(Scanner.ScanSymbols.while1));
|
|
statementSymbols.Add(new ParseSymbol(Scanner.ScanSymbols.for1));
|
|
statementSymbols.Add(new ParseSymbol(Scanner.ScanSymbols.declare1));
|
|
statementSymbols.Add(new ParseSymbol(Scanner.ScanSymbols.break1));
|
|
}
|
|
private void CreateSimpleExpressionSymbols()
|
|
{
|
|
simpleExpressionSymbols.Clear();
|
|
simpleExpressionSymbols.Add(new ParseSymbol(Scanner.ScanSymbols.plus1));
|
|
simpleExpressionSymbols.Add(new ParseSymbol(Scanner.ScanSymbols.minus1));
|
|
simpleExpressionSymbols.Add(new ParseSymbol(Scanner.ScanSymbols.leftparen1));
|
|
simpleExpressionSymbols.Add(new ParseSymbol(Scanner.ScanSymbols.numeral1));
|
|
}
|
|
private void CreateMathSymbols()
|
|
{
|
|
mathSymbols.Clear();
|
|
mathSymbols.Add(new ParseSymbol(Scanner.ScanSymbols.asterisk1));
|
|
mathSymbols.Add(new ParseSymbol(Scanner.ScanSymbols.divide1));
|
|
}
|
|
private void CreateTermSymbols()
|
|
{
|
|
termSymbols.Clear();
|
|
termSymbols.Add(new ParseSymbol(Scanner.ScanSymbols.leftparen1));
|
|
termSymbols.Add(new ParseSymbol(Scanner.ScanSymbols.numeral1));
|
|
}
|
|
private void CreateFactorSymbols()
|
|
{
|
|
factorSymbols.Clear();
|
|
factorSymbols.Add(new ParseSymbol(Scanner.ScanSymbols.leftparen1));
|
|
factorSymbols.Add(new ParseSymbol(Scanner.ScanSymbols.numeral1));
|
|
factorSymbols.Add(new ParseSymbol(Scanner.ScanSymbols.variable1));
|
|
}
|
|
private void CreateAddSymbols()
|
|
{
|
|
addSymbols.Clear();
|
|
addSymbols.Add(new ParseSymbol(Scanner.ScanSymbols.minus1));
|
|
addSymbols.Add(new ParseSymbol(Scanner.ScanSymbols.plus1));
|
|
}
|
|
private void CreateSignSymbols()
|
|
{
|
|
signSymbols.Clear();
|
|
signSymbols.Add(new ParseSymbol(Scanner.ScanSymbols.minus1));
|
|
signSymbols.Add(new ParseSymbol(Scanner.ScanSymbols.plus1));
|
|
signSymbols.Add(new ParseSymbol(Scanner.ScanSymbols.not1));
|
|
}
|
|
private void CreateExpressionSymbols()
|
|
{
|
|
expressionSymbols.Clear();
|
|
expressionSymbols.Add(new ParseSymbol(Scanner.ScanSymbols.leftparen1));
|
|
expressionSymbols.Add(new ParseSymbol(Scanner.ScanSymbols.minus1));
|
|
expressionSymbols.Add(new ParseSymbol(Scanner.ScanSymbols.plus1));
|
|
expressionSymbols.Add(new ParseSymbol(Scanner.ScanSymbols.numeral1));
|
|
expressionSymbols.Add(new ParseSymbol(Scanner.ScanSymbols.variable1));
|
|
expressionSymbols.Add(new ParseSymbol(Scanner.ScanSymbols.literal1));
|
|
expressionSymbols.Add(new ParseSymbol(Scanner.ScanSymbols.not1));
|
|
expressionSymbols.Add(new ParseSymbol(Scanner.ScanSymbols.null1));
|
|
}
|
|
private void CreateFunctionSymbols()
|
|
{
|
|
List<Symbol> symbols = new List<Symbol>(symbolTable.Values);
|
|
List<Symbol> directiveSymbolsList = (from Symbol symbol in symbols where symbol.TypeOfSymbol.Equals(Symbol.SymbolType.FunctionSymbol) select symbol).ToList();
|
|
foreach (Symbol symbol in directiveSymbolsList) directiveSymbols.Add(new ParseSymbol(symbol.Identifier));
|
|
}
|
|
private void CreateRelationSymbols()
|
|
{
|
|
relationSymbols.Clear();
|
|
relationSymbols.Add(new ParseSymbol(Scanner.ScanSymbols.less1));
|
|
relationSymbols.Add(new ParseSymbol(Scanner.ScanSymbols.lessequal1));
|
|
relationSymbols.Add(new ParseSymbol(Scanner.ScanSymbols.greater1));
|
|
relationSymbols.Add(new ParseSymbol(Scanner.ScanSymbols.greaterequal1));
|
|
relationSymbols.Add(new ParseSymbol(Scanner.ScanSymbols.notequal1));
|
|
relationSymbols.Add(new ParseSymbol(Scanner.ScanSymbols.equalequal1));
|
|
}
|
|
private void CreateLogicalSymbols()
|
|
{
|
|
logicalSymbols.Clear();
|
|
logicalSymbols.Add(new ParseSymbol(Scanner.ScanSymbols.andand1));
|
|
logicalSymbols.Add(new ParseSymbol(Scanner.ScanSymbols.oror1));
|
|
}
|
|
private void CreateMathFunctionSymbols()
|
|
{
|
|
mathFunctionSymbols.Clear();
|
|
mathFunctionSymbols.Add(new ParseSymbol(Scanner.ScanSymbols.abs1));
|
|
mathFunctionSymbols.Add(new ParseSymbol(Scanner.ScanSymbols.sqrt1));
|
|
mathFunctionSymbols.Add(new ParseSymbol(Scanner.ScanSymbols.pow1));
|
|
mathFunctionSymbols.Add(new ParseSymbol(Scanner.ScanSymbols.convert1));
|
|
}
|
|
private void CreateStringManipulationSymbols()
|
|
{
|
|
stringManipulationSymbols.Clear();
|
|
stringManipulationSymbols.Add(new ParseSymbol(Scanner.ScanSymbols.substring1));
|
|
stringManipulationSymbols.Add(new ParseSymbol(Scanner.ScanSymbols.trim1));
|
|
stringManipulationSymbols.Add(new ParseSymbol(Scanner.ScanSymbols.upper1));
|
|
stringManipulationSymbols.Add(new ParseSymbol(Scanner.ScanSymbols.lower1));
|
|
stringManipulationSymbols.Add(new ParseSymbol(Scanner.ScanSymbols.convert1));
|
|
}
|
|
public static String SymbolToString(Parser.ParserSymbols code)
|
|
{
|
|
switch (code)
|
|
{
|
|
case Parser.ParserSymbols.directive_clear_modified2 :
|
|
return "directive_clear_modified2";
|
|
case Parser.ParserSymbols.declare2 :
|
|
return "declare2";
|
|
case Parser.ParserSymbols.undefined2 :
|
|
return "undefined2";
|
|
case Parser.ParserSymbols.add2 :
|
|
return "add2";
|
|
case Parser.ParserSymbols.subtract2 :
|
|
return "subtract2" ;
|
|
case Parser.ParserSymbols.multiply2 :
|
|
return "multiply2";
|
|
case Parser.ParserSymbols.divide2 :
|
|
return "divide2";
|
|
case Parser.ParserSymbols.assign2 :
|
|
return "assign2";
|
|
case Parser.ParserSymbols.negate2 :
|
|
return "negate2";
|
|
case Parser.ParserSymbols.variableaccess2 :
|
|
return "variableaccess2";
|
|
case Parser.ParserSymbols.call2 :
|
|
return "call2";
|
|
case Parser.ParserSymbols.push2 :
|
|
return "push2";
|
|
case Parser.ParserSymbols.codeend2 :
|
|
return "codeend2";
|
|
case Parser.ParserSymbols.do2 :
|
|
return "do2";
|
|
case Parser.ParserSymbols.defaddr2 :
|
|
return "defaddr2";
|
|
case Parser.ParserSymbols.goto2 :
|
|
return "goto2";
|
|
case Parser.ParserSymbols.less2 :
|
|
return "less2";
|
|
case Parser.ParserSymbols.lessequal2 :
|
|
return "lessequal2";
|
|
case Parser.ParserSymbols.greater2 :
|
|
return "greater2";
|
|
case Parser.ParserSymbols.greaterequal2 :
|
|
return "greaterequal2";
|
|
case Parser.ParserSymbols.equalequal2 :
|
|
return "equalequal2" ;
|
|
case Parser.ParserSymbols.noop2 :
|
|
return "noop2" ;
|
|
case Parser.ParserSymbols.not2 :
|
|
return "not2" ;
|
|
case Parser.ParserSymbols.oror2 :
|
|
return "oror2" ;
|
|
case Parser.ParserSymbols.andand2 :
|
|
return "andand2" ;
|
|
default :
|
|
return "undefined code "+(int)code;
|
|
}
|
|
}
|
|
}
|
|
} |