Files
Axiom/Axiom.Core/Interpreter/Parser.cs
2026-03-19 16:23:20 -04:00

2040 lines
85 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.IO;
using System.Runtime.Remoting.Messaging;
// 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
DoForIncrement(); // emit the increment code e.g., I = I + 1
EndCapture(); // end the capture and retrieve the emitted code
DoForBlock(); // emit the BODY
EmitCapture(); // emit the code block we captured above 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;
}
}
}
}