diff --git a/lib/cli.js b/lib/cli.js
index 4bd502528..f5ffc7ff0 100755
--- a/lib/cli.js
+++ b/lib/cli.js
@@ -167,14 +167,14 @@ cli.processGrammars = function processGrammars(file, lexFile, jsonMode) {
grammar = ebnfParser.parse(file);
}
} catch (e) {
- throw new Error('Could not parse jison grammar');
+ throw new Error('Could not parse jison grammar\nError: ' + e);
}
try {
if (lexFile) {
grammar.lex = require('lex-parser').parse(lexFile);
}
} catch (e) {
- throw new Error('Could not parse lex grammar');
+ throw new Error('Could not parse lex grammar\nError: ' + e);
}
return grammar;
};
diff --git a/ports/csharp/Jison/Jison.v12.suo b/ports/csharp/Jison/Jison.v12.suo
new file mode 100644
index 000000000..c17dc66d2
Binary files /dev/null and b/ports/csharp/Jison/Jison.v12.suo differ
diff --git a/ports/csharp/Jison/Jison/Jison.csproj b/ports/csharp/Jison/Jison/Jison.csproj
index 59df70a60..173fd5861 100644
--- a/ports/csharp/Jison/Jison/Jison.csproj
+++ b/ports/csharp/Jison/Jison/Jison.csproj
@@ -71,18 +71,19 @@
True
Resources.resx
-
+
+
+
+
-
-
-
+
@@ -122,7 +123,5 @@
-
-
-
+
\ No newline at end of file
diff --git a/ports/csharp/Jison/Jison/Template.cs b/ports/csharp/Jison/Jison/Template.cs
index 40e224b7e..71c1fc8ff 100644
--- a/ports/csharp/Jison/Jison/Template.cs
+++ b/ports/csharp/Jison/Jison/Template.cs
@@ -6,745 +6,834 @@
/**/namespace Jison/**/
{
- public /**/class Parser/**/
- {
- public ParserSymbols Symbols;
- public Dictionary Terminals;
- public Dictionary Productions;
- public Dictionary Table;
- public Dictionary DefaultActions;
- public string Version = "0.4.2";
- public bool Debug = false;
-
- public const int None = 0;
- public const int Shift = 1;
- public const int Reduce = 2;
- public const int Accept = 3;
-
- public void Trace()
- {
-
- }
-
- /**/public Parser/**/()
- {
- //Setup Parser
- //@@PARSER_INJECT@@
-
- //Setup Lexer
- //@@LEXER_INJECT@@
- }
-
- public /**/ParserValue/**/ ParserPerformAction(ref /**/ParserValue/**/ thisS, ref /**/ParserValue/**/ yy, ref int yystate, ref JList**/ParserValue/**/> ss)
- {
- var so = ss.Count - 1;//@@ParserPerformActionInjection@@
- return null;
- }
-
- public ParserSymbol ParserLex()
- {
- var token = LexerLex();//end = 1
+ public /**/class Parser/**//**extends**/
+ {
+ public ParserSymbols Symbols;
+ public Dictionary Terminals;
+ public Dictionary Productions;
+ public Dictionary Table;
+ public Dictionary DefaultActions;
+ public string Version = "0.4.2";
+ public bool Debug = false;
+
+ public const int None = 0;
+ public const int Shift = 1;
+ public const int Reduce = 2;
+ public const int Accept = 3;
+ public JList**/ParserValue/**/> UnputStack = new JList**/ParserValue/**/>();
+
+ public void Trace()
+ {
+
+ }
+
+ /**/public Parser/**/()
+ {
+ //Setup Parser
+ //@@PARSER_INJECT@@
+
+ //Setup Lexer
+ //@@LEXER_INJECT@@
+ }
+
+ public /**/ParserValue/**/ ParserPerformAction(ref /**/ParserValue/**/ thisS, ref /**/ParserValue/**/ yy, ref int yystate, ref JList**/ParserValue/**/> ss)
+ {
+ var so = ss.Count - 1;//@@ParserPerformActionInjection@@
+ return null;
+ }
+
+ public ParserSymbol ParserLex()
+ {
+ var token = LexerLex();//end = 1
if (token != null)
{
return token;
}
- return Symbols["end"];
- }
-
- public void ParseError(string error, ParserError hash = null)
- {
- throw new InvalidOperationException(error);
- }
-
- public void LexerError(string error, LexerError hash = null)
- {
- throw new InvalidOperationException(error);
- }
-
- public /**/ParserValue/**/ Parse(string input)
- {
- if (Table == null) {
- throw new Exception("Empty table");
- }
- var stack = new JList
- {
- new ParserCachedAction(new ParserAction(0, Table[0]))
- };
- var vstack = new JList**/ParserValue/**/>
- {
- new /**/ParserValue/**/()
- };
- var yy = new /**/ParserValue/**/();
- var _yy = new /**/ParserValue/**/();
- var v = new /**/ParserValue/**/();
- int recovering = 0;
- ParserSymbol symbol = null;
- ParserAction action = null;
- string errStr = "";
- ParserSymbol preErrorSymbol = null;
- ParserState state = null;
-
- SetInput(input);
-
- while (true)
- {
- // retreive state number from top of stack
- state = stack.Last().Action.State;
-
- // use default actions if available
- if (state != null && DefaultActions.ContainsKey(state.Index))
- {
- action = DefaultActions[state.Index];
- }
- else
- {
- if (symbol == null)
- {
- symbol = ParserLex();
- }
- // read action for current state and first input
- if (state != null && state.Actions.ContainsKey(symbol.Index))
- {
- action = state.Actions[symbol.Index];
- }
- else
- {
- action = null;
- }
- }
-
- if (action == null)
- {
- if (recovering > 0)
- {
- // Report error
- var expected = new Stack{};
- foreach(var p in Table[state.Index].Actions)
- {
- expected.Push(Terminals[p.Value.Action].Name);
- }
-
- errStr = "Parse error on line " + (Yy.LineNo + 1).ToString() + ":" + '\n' +
- ShowPosition() + '\n' +
- "Expecting " + String.Join(", ", expected) +
- ", got '" +
- (symbol != null ? Terminals[symbol.Index].ToString() : "NOTHING") + "'";
-
- ParseError(errStr, new ParserError(Match, state, symbol, Yy.LineNo, yy.Loc, expected));
- }
- }
-
- /*if (state.IsArray()) {
- this.parseError("Parse Error: multiple actions possible at state: " + state + ", token: " + symbol);
- }*/
-
- if (state == null || action == null)
- {
- break;
- }
-
- switch (action.Action)
- {
- case Shift:
- stack.Push(new ParserCachedAction(action, symbol));
- vstack.Push(Yy.Clone());
-
- symbol = null;
- if (preErrorSymbol == null)
- { // normal execution/no error
- yy = Yy.Clone();
- if (recovering > 0) recovering--;
- } else { // error just occurred, resume old lookahead f/ before error
- symbol = preErrorSymbol;
- preErrorSymbol = null;
- }
- break;
-
- case Reduce:
- int len = Productions[action.State.Index].Len;
- // perform semantic action
- _yy = vstack[vstack.Count - len];
-
- if (Ranges != null)
- {
- Yy.Loc.Range = new ParserRange(
- vstack[vstack.Count - len].Loc.Range.X,
- vstack.Last().Loc.Range.Y
- );
- }
-
- var value = ParserPerformAction(ref _yy, ref yy, ref action.State.Index, ref vstack);
-
- if (value != null)
- {
- return value;
- }
-
- // pop off stack
- while (len > 0)
- {
- stack.Pop();
- vstack.Pop();
- len--;
- }
-
- if (_yy == null)
- {
- vstack.Push(new /**/ParserValue/**/());
- }
- else
- {
- vstack.Push(_yy.Clone());
- }
- var nextSymbol = Productions[action.State.Index].Symbol;
- // goto new state = table[STATE][NONTERMINAL]
- var nextState = stack.Last().Action.State;
- var nextAction = nextState.Actions[nextSymbol.Index];
-
- stack.Push(new ParserCachedAction(nextAction, nextSymbol));
-
- break;
- case Accept:
- return v;
- }
- }
-
- return v;
- }
-
- /* Jison generated lexer */
- public ParserSymbol Eof = new ParserSymbol("Eof", 1);
- public /**/ParserValue/**/ Yy = new /**/ParserValue/**/();
- public string Match = "";
- public string Matched = "";
- public Stack ConditionStack;
- public Dictionary Rules;
- public Dictionary Conditions;
- public bool Done = false;
- public bool Less;
- public bool _More;
- public string _Input;
- public int Offset;
- public DictionaryRanges;
- public bool Flex = false;
-
- public void SetInput(string input)
- {
- _Input = input;
- _More = Less = Done = false;
- Yy.LineNo = Yy.Leng = 0;
- Matched = Match = "";
- ConditionStack = new Stack();
- ConditionStack.Push("INITIAL");
-
- if (Ranges != null)
- {
- Yy.Loc = new ParserLocation(new ParserRange(0,0));
- } else {
- Yy.Loc = new ParserLocation();
- }
-
- Offset = 0;
- }
-
- public string Input()
- {
- string ch = _Input[0].ToString();
- Yy.Text += ch;
- Yy.Leng++;
- Offset++;
- Match += ch;
- Matched += ch;
- Match lines = Regex.Match(ch, "/(?:\r\n?|\n).*/");
- if (lines.Success) {
- Yy.LineNo++;
- Yy.Loc.LastLine++;
- } else {
- Yy.Loc.LastColumn++;
- }
-
- if (Ranges != null)
- {
- Yy.Loc.Range.Y++;
- }
-
- _Input = _Input.Substring(1);
- return ch;
- }
-
- public void Unput(string ch)
- {
- int len = ch.Length;
- var lines = Regex.Split(ch, "/(?:\r\n?|\n)/");
-
- _Input = ch + _Input;
- Yy.Text = Yy.Text.Substring(0, len - 1);
- Offset -= len;
- var oldLines = Regex.Split(Match, "/(?:\r\n?|\n)/");
- Match = Match.Substring(0, Match.Length - 1);
- Matched = Matched.Substring(0, Matched.Length - 1);
-
- if ((lines.Length - 1) > 0) Yy.LineNo -= lines.Length - 1;
- var r = Yy.Loc.Range;
-
- Yy.Loc = new ParserLocation(
- Yy.Loc.FirstLine,
- Yy.LineNo + 1,
- Yy.Loc.FirstColumn,
- (
- lines.Length > 0 ?
- (
- lines.Length == oldLines.Length ?
- Yy.Loc.FirstColumn :
- 0
- ) + oldLines[oldLines.Length - lines.Length].Length - lines[0].Length :
- Yy.Loc.FirstColumn - len
- )
- );
-
- if (Ranges.Count > 0) {
- Yy.Loc.Range = new ParserRange(r.X, r.X + Yy.Leng - len);
- }
- }
-
- public void More()
- {
- _More = true;
- }
-
- public string PastInput()
- {
- var past = Matched.Substring(0, Matched.Length - Match.Length);
- return (past.Length > 20 ? "..." + Regex.Replace(past.Substring(-20), "/\n/", "") : "");
- }
-
- public string UpcomingInput()
- {
- var next = Match;
- if (next.Length < 20)
- {
- next += _Input.Substring(0, (next.Length > 20 ? 20 - next.Length : next.Length));
- }
- return Regex.Replace(next.Substring(0, (next.Length > 20 ? 20 - next.Length : next.Length)) + (next.Length > 20 ? "..." : ""), "/\n/", "");
- }
-
- public string ShowPosition()
- {
- var pre = PastInput();
-
- var c = "";
- for (var i = 0; i < pre.Length; i++)
- {
- c += "-";
- }
-
- return pre + UpcomingInput() + '\n' + c + "^";
- }
-
- public ParserSymbol Next()
- {
- if (Done == true)
- {
- return Eof;
- }
-
- if (String.IsNullOrEmpty(_Input))
- {
- Done = true;
- }
-
- if (_More == false)
- {
- Yy.Text = "";
- Match = "";
- }
-
- var rules = CurrentRules();
- string match = "";
- bool matched = false;
- int index = 0;
- Regex rule;
- for (int i = 0; i < rules.Count; i++)
- {
- rule = Rules[rules[i]];
- var tempMatch = rule.Match(_Input);
- if (tempMatch.Success == true && (match != null || tempMatch.Length > match.Length)) {
- match = tempMatch.Value;
- matched = true;
- index = i;
- if (!Flex) {
- break;
- }
- }
- }
- if ( matched )
- {
- Match lineCount = Regex.Match(match, "/\n.*/");
-
- Yy.LineNo += lineCount.Length;
- Yy.Loc.FirstLine = Yy.Loc.LastLine;
- Yy.Loc.LastLine = Yy.LineNo + 1;
- Yy.Loc.FirstColumn = Yy.Loc.LastColumn;
- Yy.Loc.LastColumn = lineCount.Length > 0 ? lineCount.Length - 1 : Yy.Loc.LastColumn + match.Length;
-
- Yy.Text += match;
- Match += match;
- Matched += match;
-
- Yy.Leng = Yy.Text.Length;
- if (Ranges != null)
- {
- Yy.Loc.Range = new ParserRange(Offset, Offset += Yy.Leng);
- }
- _More = false;
- _Input = _Input.Substring(match.Length);
+ return Symbols["end"];
+ }
+
+ public void ParseError(string error, ParserError hash = null)
+ {
+ throw new InvalidOperationException(error);
+ }
+
+ public void LexerError(string error, LexerError hash = null)
+ {
+ throw new InvalidOperationException(error);
+ }
+
+ public /**/ParserValue/**/ Parse(string input)
+ {
+ if (Table == null) {
+ throw new Exception("Empty table");
+ }
+ var stack = new JList
+ {
+ new ParserCachedAction(new ParserAction(0, Table[0]))
+ };
+ var vstack = new JList**/ParserValue/**/>
+ {
+ new /**/ParserValue/**/()
+ };
+ var yy = new /**/ParserValue/**/();
+ var _yy = new /**/ParserValue/**/();
+ var v = new /**/ParserValue/**/();
+ int recovering = 0;
+ ParserSymbol symbol = null;
+ ParserAction action = null;
+ string errStr = "";
+ ParserSymbol preErrorSymbol = null;
+ ParserState state = null;
+
+ SetInput(input);
+
+ while (true)
+ {
+ // retreive state number from top of stack
+ state = stack.Last().Action.State;
+
+ // use default actions if available
+ if (state != null && DefaultActions.ContainsKey(state.Index))
+ {
+ action = DefaultActions[state.Index];
+ }
+ else
+ {
+ if (symbol == null)
+ {
+ symbol = ParserLex();
+ }
+ // read action for current state and first input
+ if (state != null && state.Actions.ContainsKey(symbol.Index))
+ {
+ action = state.Actions[symbol.Index];
+ }
+ else
+ {
+ action = null;
+ }
+ }
+
+ if (action == null)
+ {
+ if (recovering > 0)
+ {
+ // Report error
+ var expected = new Stack{};
+ foreach(var p in Table[state.Index].Actions)
+ {
+ expected.Push(Terminals[p.Value.Action].Name);
+ }
+
+ errStr = "Parse error on line " + (Yy.LineNo + 1).ToString() + ":" + '\n' +
+ ShowPosition() + '\n' +
+ "Expecting " + String.Join(", ", expected) +
+ ", got '" +
+ (symbol != null ? Terminals[symbol.Index].ToString() : "NOTHING") + "'";
+
+ ParseError(errStr, new ParserError(Match, state, symbol, Yy.LineNo, yy.Loc, expected));
+ }
+ }
+
+ /*if (state.IsArray()) {
+ this.parseError("Parse Error: multiple actions possible at state: " + state + ", token: " + symbol);
+ }*/
+
+ if (state == null || action == null)
+ {
+ break;
+ }
+
+ switch (action.Action)
+ {
+ case Shift:
+ stack.Push(new ParserCachedAction(action, symbol));
+ vstack.Push(Yy.Clone());
+
+ symbol = null;
+ if (preErrorSymbol == null)
+ { // normal execution/no error
+ yy = Yy.Clone();
+ if (recovering > 0) recovering--;
+ } else { // error just occurred, resume old lookahead f/ before error
+ symbol = preErrorSymbol;
+ preErrorSymbol = null;
+ }
+ break;
+
+ case Reduce:
+ int len = Productions[action.State.Index].Len;
+ // perform semantic action
+ _yy = vstack[vstack.Count - len];
+
+ if (Ranges != null)
+ {
+ Yy.Loc.Range = new ParserRange(
+ vstack[vstack.Count - len].Loc.Range.X,
+ vstack.Last().Loc.Range.Y
+ );
+ }
+
+ var value = ParserPerformAction(ref _yy, ref yy, ref action.State.Index, ref vstack);
+
+ if (value != null)
+ {
+ return value;
+ }
+
+ // pop off stack
+ while (len > 0)
+ {
+ stack.Pop();
+ vstack.Pop();
+ len--;
+ }
+
+ if (_yy == null)
+ {
+ vstack.Push(new /**/ParserValue/**/());
+ }
+ else
+ {
+ vstack.Push(_yy.Clone());
+ }
+ var nextSymbol = Productions[action.State.Index].Symbol;
+ // goto new state = table[STATE][NONTERMINAL]
+ var nextState = stack.Last().Action.State;
+ var nextAction = nextState.Actions[nextSymbol.Index];
+
+ stack.Push(new ParserCachedAction(nextAction, nextSymbol));
+
+ break;
+ case Accept:
+ return v;
+ }
+ }
+
+ return v;
+ }
+
+ /* Jison generated lexer */
+ public ParserSymbol Eof = new ParserSymbol("Eof", 1);
+ public /**/ParserValue/**/ Yy = new /**/ParserValue/**/();
+ public string Match = "";
+ public Stack ConditionStack;
+ public Dictionary Rules;
+ public Dictionary Conditions;
+ public bool Done = false;
+ public bool Less;
+ public bool _More;
+ public InputReader _Input;
+ public int Offset;
+ public DictionaryRanges;
+ public bool Flex = false;
+
+ public void SetInput(string input)
+ {
+ _Input = new InputReader(input);
+ _More = Less = Done = false;
+ Yy.LineNo = Yy.Leng = 0;
+ ConditionStack = new Stack();
+ ConditionStack.Push("INITIAL");
+
+ if (Ranges != null)
+ {
+ Yy.Loc = new ParserLocation(new ParserRange(0,0));
+ } else {
+ Yy.Loc = new ParserLocation();
+ }
+
+ Offset = 0;
+ }
+
+ public string Input()
+ {
+ string ch = _Input.Ch();
+ Yy.Text += ch;
+ Yy.Leng++;
+ Offset++;
+ Match += ch;
+ Match lines = Regex.Match(ch, "/(?:\r\n?|\n).*/");
+ if (lines.Success) {
+ Yy.LineNo++;
+ Yy.Loc.LastLine++;
+ } else {
+ Yy.Loc.LastColumn++;
+ }
+
+ if (Ranges != null)
+ {
+ Yy.Loc.Range.Y++;
+ }
+
+ return ch;
+ }
+
+ public void Unput(string ch)
+ {
+ var yy = new /**/ParserValue/**/();
+ int len = ch.Length;
+ var lines = Regex.Split(ch, "/(?:\r\n?|\n)/");
+
+ _Input.unCh(ch.Length);
+ yy.Text = Yy.Text.Substring(0, len - 1);
+ Offset -= len;
+ var oldLines = Regex.Split(Match, "/(?:\r\n?|\n)/");
+ Match = Match.Substring(0, Match.Length - 1);
+
+ if ((lines.Length - 1) > 0)
+ {
+ yy.LineNo -= Yy.LineNo - lines.Length - 1;
+ }
+ var r = Yy.Loc.Range;
+
+ yy.Loc = new ParserLocation(
+ Yy.Loc.FirstLine,
+ Yy.LineNo + 1,
+ Yy.Loc.FirstColumn,
+ (
+ lines.Length > 0 ?
+ (
+ lines.Length == oldLines.Length ?
+ Yy.Loc.FirstColumn :
+ 0
+ ) + oldLines[oldLines.Length - lines.Length].Length - lines[0].Length :
+ Yy.Loc.FirstColumn - len
+ )
+ );
+
+ if (Ranges.Count > 0) {
+ yy.Loc.Range = new ParserRange(r.X, r.X + Yy.Leng - len);
+ }
+
+ UnputStack.Push(yy);
+ }
+
+ public void More()
+ {
+ _More = true;
+ }
+
+ public string PastInput()
+ {
+ var past = _Input.ToString().Substring(0, _Input.Position - Match.Length);
+ return (past.Length > 20 ? "..." + Regex.Replace(past.Substring(20), "/\n/", "") : "");
+ }
+
+ public string UpcomingInput()
+ {
+ var next = Match;
+ if (next.Length < 20)
+ {
+ next += _Input.ToString().Substring(0, (next.Length > 20 ? 20 - next.Length : next.Length));
+ }
+ return Regex.Replace(next.Substring(0, (next.Length > 20 ? 20 - next.Length : next.Length)) + (next.Length > 20 ? "..." : ""), "/\n/", "");
+ }
+
+ public string ShowPosition()
+ {
+ var pre = PastInput();
+
+ var c = "";
+ for (var i = 0; i < pre.Length; i++)
+ {
+ c += "-";
+ }
+
+ return pre + UpcomingInput() + '\n' + c + "^";
+ }
+
+ public ParserSymbol Next()
+ {
+ if (UnputStack.Count > 0)
+ {
+ Yy = UnputStack.Pop();
+ }
+
+ if (Done == true)
+ {
+ return Eof;
+ }
+
+ if (_Input.Done)
+ {
+ Done = true;
+ }
+
+ if (_More == false)
+ {
+ Yy.Text = "";
+ Match = "";
+ }
+
+ var rules = CurrentRules();
+ string match = "";
+ bool matched = false;
+ int index = 0;
+ Regex rule;
+ for (int i = 0; i < rules.Count; i++)
+ {
+ rule = Rules[rules[i]];
+ var tempMatch = _Input.Match(rule);
+ if (tempMatch.Success && tempMatch.Length > match.Length) {
+ match = tempMatch.Value;
+ matched = true;
+ index = i;
+ if (!Flex) {
+ break;
+ }
+ }
+ }
+ if ( matched )
+ {
+ Match lineCount = Regex.Match(match, "/\n.*/");
+
+ Yy.LineNo += lineCount.Length;
+ Yy.Loc.FirstLine = Yy.Loc.LastLine;
+ Yy.Loc.LastLine = Yy.LineNo + 1;
+ Yy.Loc.FirstColumn = Yy.Loc.LastColumn;
+ Yy.Loc.LastColumn = lineCount.Length > 0 ? lineCount.Length - 1 : Yy.Loc.LastColumn + match.Length;
+
+ Yy.Text += match;
+ Match += match;
+
+ Yy.Leng = Yy.Text.Length;
+ if (Ranges != null)
+ {
+ Yy.Loc.Range = new ParserRange(Offset, Offset += Yy.Leng);
+ }
+ _More = false;
+ _Input.AddMatch(match);
var ruleIndex = rules[index];
var nextCondition = ConditionStack.Peek();
dynamic action = LexerPerformAction(ruleIndex, nextCondition);
- ParserSymbol token = Symbols[action];
-
- if (Done == true && String.IsNullOrEmpty(_Input) == false)
- {
- Done = false;
- }
-
- if (token.Index > -1) {
- return token;
- } else {
- return null;
- }
- }
-
- if (String.IsNullOrEmpty(_Input)) {
- return Symbols["EOF"];
- } else
- {
- LexerError("Lexical error on line " + (Yy.LineNo + 1) + ". Unrecognized text.\n" + ShowPosition(), new LexerError("", -1, Yy.LineNo));
- return null;
- }
- }
-
- public ParserSymbol LexerLex()
- {
- var r = Next();
-
- while (r == null)
- {
- r = Next();
- }
-
- return r;
- }
-
- public void Begin(string condition)
- {
- ConditionStack.Push(condition);
- }
-
- public string PopState()
- {
- return ConditionStack.Pop();
- }
-
- public List CurrentRules()
- {
- var peek = ConditionStack.Peek();
- return Conditions[peek].Rules;
- }
-
- public dynamic LexerPerformAction(int avoidingNameCollisions, string Yy_Start)
- {
- //@@LexerPerformActionInjection@@
- return -1;
- }
- }
-
- public class ParserLocation
- {
- public int FirstLine = 1;
- public int LastLine = 0;
- public int FirstColumn = 1;
- public int LastColumn = 0;
- public ParserRange Range;
-
- public ParserLocation()
- {
- }
-
- public ParserLocation(ParserRange range)
- {
- Range = range;
- }
-
- public ParserLocation(int firstLine, int lastLine, int firstColumn, int lastColumn)
- {
- FirstLine = firstLine;
- LastLine = lastLine;
- FirstColumn = firstColumn;
- LastColumn = lastColumn;
- }
-
- public ParserLocation(int firstLine, int lastLine, int firstColumn, int lastColumn, ParserRange range)
- {
- FirstLine = firstLine;
- LastLine = lastLine;
- FirstColumn = firstColumn;
- LastColumn = lastColumn;
- Range = range;
- }
- }
-
- public class LexerConditions
- {
- public List Rules;
- public bool Inclusive;
-
- public LexerConditions(List rules, bool inclusive)
- {
- Rules = rules;
- Inclusive = inclusive;
- }
- }
-
- public class ParserProduction
- {
- public int Len = 0;
- public ParserSymbol Symbol;
-
- public ParserProduction(ParserSymbol symbol)
- {
- Symbol = symbol;
- }
-
- public ParserProduction(ParserSymbol symbol, int len)
- {
- Symbol = symbol;
- Len = len;
- }
- }
-
- public class ParserCachedAction
- {
- public ParserAction Action;
- public ParserSymbol Symbol;
-
- public ParserCachedAction(ParserAction action)
- {
- Action = action;
- }
-
- public ParserCachedAction(ParserAction action, ParserSymbol symbol)
- {
- Action = action;
- Symbol = symbol;
- }
- }
-
- public class ParserAction
- {
- public int Action;
- public ParserState State;
- public ParserSymbol Symbol;
-
- public ParserAction(int action)
- {
- Action = action;
- }
-
- public ParserAction(int action, ref ParserState state)
- {
- Action = action;
- State = state;
- }
-
- public ParserAction(int action, ParserState state)
- {
- Action = action;
- State = state;
- }
-
- public ParserAction(int action, ref ParserSymbol symbol)
- {
- Action = action;
- Symbol = symbol;
- }
- }
-
- public class ParserSymbol
- {
- public string Name;
- public int Index = -1;
- public IDictionary Symbols = new Dictionary();
- public IDictionary SymbolsByName = new Dictionary();
-
- public ParserSymbol()
- {
- }
-
- public ParserSymbol(string name, int index)
- {
- Name = name;
- Index = index;
- }
-
- public void AddAction(ParserSymbol p)
- {
- Symbols.Add(p.Index, p);
- SymbolsByName.Add(p.Name, p);
- }
- }
-
- public class ParserError
- {
- public String Text;
- public ParserState State;
- public ParserSymbol Symbol;
- public int LineNo;
- public ParserLocation Loc;
- public Stack Expected;
-
- public ParserError(String text, ParserState state, ParserSymbol symbol, int lineNo, ParserLocation loc, Stack expected)
- {
- Text = text;
- State = state;
- Symbol = symbol;
- LineNo = lineNo;
- Loc = loc;
- Expected = expected;
- }
- }
-
- public class LexerError
- {
- public String Text;
- public int Token;
- public int LineNo;
-
- public LexerError(String text, int token, int lineNo)
- {
- Text = text;
- Token = token;
- LineNo = lineNo;
- }
- }
-
- public class ParserState
- {
- public int Index;
- public Dictionary Actions = new Dictionary();
-
- public ParserState(int index)
- {
- Index = index;
- }
-
- public void SetActions(ref Dictionary actions)
- {
- Actions = actions;
- }
- }
-
- public class ParserRange
- {
- public int X;
- public int Y;
-
- public ParserRange(int x, int y)
- {
- X = x;
- Y = y;
- }
- }
-
- public class ParserSymbols
- {
- private Dictionary SymbolsString = new Dictionary();
- private Dictionary SymbolsInt = new Dictionary();
-
- public void Add(ParserSymbol symbol)
- {
- SymbolsInt.Add(symbol.Index, symbol);
- SymbolsString.Add(symbol.Name, symbol);
- }
-
- public ParserSymbol this[char name]
- {
- get
- {
- return SymbolsString[name.ToString()];
- }
- }
-
- public ParserSymbol this[string name]
- {
- get
- {
- return SymbolsString[name];
- }
- }
-
- public ParserSymbol this[int index]
- {
- get
- {
- if (index < 0)
- {
- return new ParserSymbol();
- }
- return SymbolsInt[index];
- }
- }
- }
-
- public class ParserValue
- {
- public string Text;
- public ParserLocation Loc;
- public int Leng = 0;
- public int LineNo = 0;
-
- public ParserValue()
- {
- }
-
- public ParserValue(ParserValue parserValue)
- {
- Text = parserValue.Text;
- Leng = parserValue.Leng;
- Loc = parserValue.Loc;
- LineNo = parserValue.LineNo;
- }
-
- public ParserValue Clone()
- {
- return new ParserValue(this);
- }
- }
-
- public class JList : List where T : class
- {
- public void Push(T item)
- {
- Add(item);
- }
-
- public void Pop()
- {
- RemoveAt(Count - 1);
- }
-
- new public T this[int index]
- {
- get
- {
- if (index >= Count || index < 0 || Count == 0)
- {
- return null;
- }
- return base[index];
- }
- }
- }
+ ParserSymbol token = Symbols[action];
+
+ if (Done == true || _Input.Done)
+ {
+ Done = false;
+ }
+
+ if (token.Index > -1) {
+ return token;
+ } else {
+ return null;
+ }
+ }
+
+ if (_Input.Done) {
+ return Symbols["EOF"];
+ } else
+ {
+ LexerError("Lexical error on line " + (Yy.LineNo + 1) + ". Unrecognized text.\n" + ShowPosition(), new LexerError("", -1, Yy.LineNo));
+ return null;
+ }
+ }
+
+ public ParserSymbol LexerLex()
+ {
+ var r = Next();
+
+ while (r == null)
+ {
+ r = Next();
+ }
+
+ return r;
+ }
+
+ public void Begin(string condition)
+ {
+ ConditionStack.Push(condition);
+ }
+
+ public string PopState()
+ {
+ return ConditionStack.Pop();
+ }
+
+ public List CurrentRules()
+ {
+ var peek = ConditionStack.Peek();
+ return Conditions[peek].Rules;
+ }
+
+ public dynamic LexerPerformAction(int avoidingNameCollisions, string Yy_Start)
+ {
+ //@@LexerPerformActionInjection@@
+ return -1;
+ }
+ }
+
+ public class ParserLocation
+ {
+ public int FirstLine = 1;
+ public int LastLine = 0;
+ public int FirstColumn = 1;
+ public int LastColumn = 0;
+ public ParserRange Range;
+
+ public ParserLocation()
+ {
+ }
+
+ public ParserLocation(ParserRange range)
+ {
+ Range = range;
+ }
+
+ public ParserLocation(int firstLine, int lastLine, int firstColumn, int lastColumn)
+ {
+ FirstLine = firstLine;
+ LastLine = lastLine;
+ FirstColumn = firstColumn;
+ LastColumn = lastColumn;
+ }
+
+ public ParserLocation(int firstLine, int lastLine, int firstColumn, int lastColumn, ParserRange range)
+ {
+ FirstLine = firstLine;
+ LastLine = lastLine;
+ FirstColumn = firstColumn;
+ LastColumn = lastColumn;
+ Range = range;
+ }
+
+ public ParserLocation Clone()
+ {
+ var parserLocation = new ParserLocation(FirstLine, LastLine,FirstColumn,LastColumn);
+
+ if (Range != null)
+ {
+ parserLocation.Range = Range.Clone();
+ }
+
+ return parserLocation;
+ }
+ }
+
+ public class LexerConditions
+ {
+ public List Rules;
+ public bool Inclusive;
+
+ public LexerConditions(List rules, bool inclusive)
+ {
+ Rules = rules;
+ Inclusive = inclusive;
+ }
+ }
+
+ public class ParserProduction
+ {
+ public int Len = 0;
+ public ParserSymbol Symbol;
+
+ public ParserProduction(ParserSymbol symbol)
+ {
+ Symbol = symbol;
+ }
+
+ public ParserProduction(ParserSymbol symbol, int len)
+ {
+ Symbol = symbol;
+ Len = len;
+ }
+ }
+
+ public class ParserCachedAction
+ {
+ public ParserAction Action;
+ public ParserSymbol Symbol;
+
+ public ParserCachedAction(ParserAction action)
+ {
+ Action = action;
+ }
+
+ public ParserCachedAction(ParserAction action, ParserSymbol symbol)
+ {
+ Action = action;
+ Symbol = symbol;
+ }
+ }
+
+ public class ParserAction
+ {
+ public int Action;
+ public ParserState State;
+ public ParserSymbol Symbol;
+
+ public ParserAction(int action)
+ {
+ Action = action;
+ }
+
+ public ParserAction(int action, ref ParserState state)
+ {
+ Action = action;
+ State = state;
+ }
+
+ public ParserAction(int action, ParserState state)
+ {
+ Action = action;
+ State = state;
+ }
+
+ public ParserAction(int action, ref ParserSymbol symbol)
+ {
+ Action = action;
+ Symbol = symbol;
+ }
+ }
+
+ public class ParserSymbol
+ {
+ public string Name;
+ public int Index = -1;
+ public IDictionary Symbols = new Dictionary();
+ public IDictionary SymbolsByName = new Dictionary();
+
+ public ParserSymbol()
+ {
+ }
+
+ public ParserSymbol(string name, int index)
+ {
+ Name = name;
+ Index = index;
+ }
+
+ public void AddAction(ParserSymbol p)
+ {
+ Symbols.Add(p.Index, p);
+ SymbolsByName.Add(p.Name, p);
+ }
+ }
+
+ public class ParserError
+ {
+ public String Text;
+ public ParserState State;
+ public ParserSymbol Symbol;
+ public int LineNo;
+ public ParserLocation Loc;
+ public Stack Expected;
+
+ public ParserError(String text, ParserState state, ParserSymbol symbol, int lineNo, ParserLocation loc, Stack expected)
+ {
+ Text = text;
+ State = state;
+ Symbol = symbol;
+ LineNo = lineNo;
+ Loc = loc;
+ Expected = expected;
+ }
+ }
+
+ public class LexerError
+ {
+ public String Text;
+ public int Token;
+ public int LineNo;
+
+ public LexerError(String text, int token, int lineNo)
+ {
+ Text = text;
+ Token = token;
+ LineNo = lineNo;
+ }
+ }
+
+ public class ParserState
+ {
+ public int Index;
+ public Dictionary Actions = new Dictionary();
+
+ public ParserState(int index)
+ {
+ Index = index;
+ }
+
+ public void SetActions(ref Dictionary actions)
+ {
+ Actions = actions;
+ }
+ }
+
+ public class ParserRange
+ {
+ public int X;
+ public int Y;
+
+ public ParserRange(int x, int y)
+ {
+ X = x;
+ Y = y;
+ }
+
+ public ParserRange Clone()
+ {
+ var parserRange = new ParserRange(X, Y);
+ return parserRange;
+ }
+ }
+
+ public class ParserSymbols
+ {
+ private Dictionary SymbolsString = new Dictionary();
+ private Dictionary SymbolsInt = new Dictionary();
+
+ public void Add(ParserSymbol symbol)
+ {
+ SymbolsInt.Add(symbol.Index, symbol);
+ SymbolsString.Add(symbol.Name, symbol);
+ }
+
+ public ParserSymbol this[char name]
+ {
+ get
+ {
+ return SymbolsString[name.ToString()];
+ }
+ }
+
+ public ParserSymbol this[string name]
+ {
+ get
+ {
+ return SymbolsString[name];
+ }
+ }
+
+ public ParserSymbol this[int index]
+ {
+ get
+ {
+ if (index < 0)
+ {
+ return new ParserSymbol();
+ }
+ return SymbolsInt[index];
+ }
+ }
+ }
+
+ public class ParserValue
+ {
+ public string Text;
+ public ParserLocation Loc;
+ public int Leng = 0;
+ public int LineNo = 0;
+
+ public ParserValue()
+ {
+ }
+
+ public ParserValue(string text, ParserLocation loc, int leng, int lineNo)
+ {
+ Text = text;
+ Loc = loc;
+ Leng = leng;
+ LineNo = lineNo;
+ }
+
+ public ParserValue Clone()
+ {
+ var parserValue = new ParserValue();
+ parserValue.Text = this.Text;
+
+
+ return parserValue;
+ }
+ }
+
+ public class JList : List where T : class
+ {
+ public void Push(T item)
+ {
+ Add(item);
+ }
+
+ public T Pop()
+ {
+ var i = Math.Max(0, Count);
+ if (i == 0)
+ {
+ return null;
+ }
+
+ var val = this[i];
+ RemoveAt(i);
+ return val;
+ }
+
+ new public T this[int index]
+ {
+ get
+ {
+ if (index >= Count || index < 0 || Count == 0)
+ {
+ return null;
+ }
+ return base[index];
+ }
+ }
+ }
+
+
+ public class InputReader
+ {
+
+ public bool Done = false;
+ public string Input;
+ public int Length;
+ public JList Matches = new JList();
+ public int Position = 0;
+
+ public InputReader(string input)
+ {
+ Input = input;
+ Length = input.Length;
+ }
+
+ public void AddMatch (string match) {
+ Matches.Push(match);
+ Position += match.Length;
+ Done = (Position >= Length);
+ }
+
+ public string Ch()
+ {
+ var ch = Input[Position].ToString();
+ AddMatch(ch);
+ return ch;
+ }
+
+ public void unCh(int chLength)
+ {
+ Position -= chLength;
+ Position = Math.Max(0, Position);
+ Done = (Position >= Length);
+ }
+
+ public string Substring(int start, int end) {
+ start = (start != 0 ? Position + start : Position);
+ end = (end != 0 ? start + end : Length);
+ return Input.Substring(start, end);
+ }
+
+ public Match Match(Regex rule) {
+ var match = rule.Match(Input, Position);
+ return match;
+ }
+
+ public new string ToString()
+ {
+ return String.Join("", Matches.ToArray());
+ }
+ }
}
\ No newline at end of file
diff --git a/ports/csharp/Jison/Jison/Test.cs b/ports/csharp/Jison/Jison/Test.cs
index 1dd965950..d85161ede 100644
--- a/ports/csharp/Jison/Jison/Test.cs
+++ b/ports/csharp/Jison/Jison/Test.cs
@@ -1,7 +1,6 @@
using System;
-using jQuerySheet;
-namespace jQuerySheet
+namespace Sheet
{
public class Test
{
@@ -11,30 +10,19 @@ public Test ()
public static void Main()
{
- Spreadsheet.Spreadsheets = new SpreadsheetsDictionary();
- var spreadsheetsDictionary = new SpreadsheetDictionary();
- Spreadsheet.Spreadsheets.Add(0, spreadsheetsDictionary);
- var row = new RowDictionary();
- spreadsheetsDictionary.Add(0, row);
+ var spreadsheets = new Spreadsheets();
+ var spreadsheet = spreadsheets.AddSpreadsheet();
- var cellA1 = new Cell(0, 0, 0);
- cellA1.Value = "250";
- var cellB1 = new Cell(0, 0, 1);
- cellB1.Value = "250";
- var cellC1 = new Cell(0, 0, 2);
- cellC1.Formula = "800 - SUM(A1:B1) + 100";
- cellC1.HasFormula = true;
+ var row = spreadsheet.AddRow();
- row.Add(0, cellA1);
- row.Add(1, cellB1);
- row.Add(2, cellC1);
+ var cellA1 = row.AddCell("250");
+ var cellB1 = row.AddCell("250");
+ var cellC1 = row.AddCell("800 - (SUM(A1:B1) + 100)", true);
- //var spreadsheet = new Spreadsheet();
- //spreadsheet.Calc();
-
- var parsedCell = Spreadsheet.Spreadsheets[0][0][2];
- var value = parsedCell.UpdateValue();
- value = value;
+ var cell = spreadsheet["C", 1];
+ var value = cell.UpdateValue();
+ Console.Write(value.ToDouble());
+ Console.Read();
}
}
}
diff --git a/ports/csharp/Jison/Jison/Test/Cell.cs b/ports/csharp/Jison/Jison/Test/Cell.cs
index c24a9d242..4343987af 100644
--- a/ports/csharp/Jison/Jison/Test/Cell.cs
+++ b/ports/csharp/Jison/Jison/Test/Cell.cs
@@ -1,14 +1,10 @@
using System;
using System.Collections.Generic;
-namespace jQuerySheet
+namespace Sheet
{
public class Cell
{
- public Cell ()
- {
- }
-
public int Row;
public int Col;
public int Spreadsheet;
@@ -16,12 +12,15 @@ public Cell ()
public Boolean HasFormula;
public string Formula;
public Expression Exp;
-
public DateTime CalcLast = new DateTime();
public int CalcCount = 0;
-
public Stack State = new Stack();
-
+ public Row Parent;
+
+ public Cell()
+ {
+ }
+
public Cell(int spreadsheet, int row, int col)
{
Spreadsheet = spreadsheet;
@@ -41,23 +40,25 @@ public Expression UpdateValue()
if (HasFormula && State.Count < 1) {
State.Push ("Parsing");
CalcCount++;
- var formula = new Formula ();
+ var formula = new Formula();
+ formula.Setup(this);
var value = formula.Parse (Formula);
State.Pop ();
return value;
- } else {
- var exp = new Expression();
- double num;
- if (double.TryParse(Value, out num))
- {
- exp.Set(num);
- }
- else
- {
- exp.Set(Value);
- }
- return exp;
}
+
+ var exp = new Expression();
+ double num;
+ if (double.TryParse(Value, out num))
+ {
+ exp.Set(num);
+ }
+ else
+ {
+ exp.Set(Value);
+ }
+ return exp;
+
}
}
}
diff --git a/ports/csharp/Jison/Jison/Test/Expression.cs b/ports/csharp/Jison/Jison/Test/Expression.cs
index 769d100f2..d5ed45fb9 100644
--- a/ports/csharp/Jison/Jison/Test/Expression.cs
+++ b/ports/csharp/Jison/Jison/Test/Expression.cs
@@ -1,29 +1,53 @@
using System;
using System.Collections.Generic;
+using Jison;
-namespace jQuerySheet
+namespace Sheet
{
public class Expression : ParserValue
{
public bool ValueSet = false;
public string Type;
+ public bool BoolValue;
+ public double DoubleValue;
+ public List Children;
+
+ public Expression()
+ {
+ }
- public Expression(){}
- public Expression(Expression value)
- {
- Text = value.Text;
- Leng = value.Leng;
- Loc = value.Loc;
- LineNo = value.LineNo;
- ValueSet = value.ValueSet;
- BoolValue = value.BoolValue;
- Children = value.Children;
- DoubleValue = value.DoubleValue;
- }
-
- public Expression Clone()
+ public new Expression Clone()
{
- return new Expression(this);
+ var expression = new Expression();
+ expression.Text = Text;
+ if (Loc != null)
+ {
+ expression.Loc = Loc.Clone();
+ }
+ expression.Leng = Leng;
+ expression.LineNo = LineNo;
+
+ expression.ValueSet = ValueSet;
+ expression.Type = Type;
+ expression.ValueSet = ValueSet;
+ expression.BoolValue = BoolValue;
+
+ if (Children != null)
+ {
+ expression.Children = new JList();
+
+ foreach (var child in Children)
+ {
+ if (this != child)
+ {
+ expression.Children.Add(child.Clone());
+ }
+ }
+ }
+
+ expression.DoubleValue = DoubleValue;
+
+ return expression;
}
public Expression(string value)
@@ -31,12 +55,12 @@ public Expression(string value)
Text = value;
}
- public bool BoolValue;
public bool ToBool()
{
ValueSet = true;
BoolValue = Convert.ToBoolean (Text);
Type = "bool";
+ Text = BoolValue.ToString();
return BoolValue;
}
public void Set(bool value) {
@@ -45,11 +69,14 @@ public void Set(bool value) {
Type = "bool";
}
-
- public double DoubleValue;
public double ToDouble()
{
- ValueSet = true;
+ if (Type == "double")
+ {
+ return DoubleValue;
+ }
+
+ ValueSet = true;
if (!String.IsNullOrEmpty (Text) || DoubleValue != 0) {
double num;
if (double.TryParse(Text, out num)) {
@@ -87,35 +114,33 @@ public void Add(Expression value)
value.ToDouble();
DoubleValue += value.DoubleValue;
Type = "double";
+ Text = DoubleValue.ToString();
}
public void Set(double value) {
DoubleValue = value;
+ Text = value.ToString();
ValueSet = true;
Type = "double";
}
-
public string ToString()
{
ValueSet = true;
- Type = "string";
return Text;
}
+
public void Set(string value) {
Text = value;
ValueSet = true;
Type = "string";
}
+
public void Concat(Expression value)
{
Text += value.Text;
Type = "string";
}
-
-
-
-
- public List Children;
+
public void Push(Expression value)
{
if (Children == null) {
diff --git a/ports/csharp/Jison/Jison/Test/Formula.cs b/ports/csharp/Jison/Jison/Test/Formula.cs
index bc1ec4011..f88b6bb60 100644
--- a/ports/csharp/Jison/Jison/Test/Formula.cs
+++ b/ports/csharp/Jison/Jison/Test/Formula.cs
@@ -4,9 +4,9 @@
using System.Linq;
-namespace jQuerySheet
+namespace Sheet
{
- public class Formula
+ public class Formula : FormulaBase
{
public ParserSymbols Symbols;
public Dictionary Terminals;
@@ -20,6 +20,7 @@ public class Formula
public const int Shift = 1;
public const int Reduce = 2;
public const int Accept = 3;
+ public JList UnputStack = new JList();
public void Trace()
{
@@ -1729,42 +1730,42 @@ public Formula()
Rules = new Dictionary
{
- {0, new Regex(@"^(?:\s+)")},
- {1, new Regex(@"^(?:""(\\[""]|[^""])*"")")},
- {2, new Regex(@"^(?:'(\\[']|[^'])*')")},
- {3, new Regex(@"^(?:[A-Za-z]{1,}[A-Za-z_0-9]+(?=[(]))")},
- {4, new Regex(@"^(?:([0]?[1-9]|1[0-2])[:][0-5][0-9]([:][0-5][0-9])?[ ]?(AM|am|aM|Am|PM|pm|pM|Pm))")},
- {5, new Regex(@"^(?:([0]?[0-9]|1[0-9]|2[0-3])[:][0-5][0-9]([:][0-5][0-9])?)")},
- {6, new Regex(@"^(?:SHEET[0-9]+)")},
- {7, new Regex(@"^(?:\$[A-Za-z]+\$[0-9]+)")},
- {8, new Regex(@"^(?:[A-Za-z]+[0-9]+)")},
- {9, new Regex(@"^(?:[A-Za-z]+(?=[(]))")},
- {10, new Regex(@"^(?:[A-Za-z]{1,}[A-Za-z_0-9]+)")},
- {11, new Regex(@"^(?:[A-Za-z_]+)")},
- {12, new Regex(@"^(?:[0-9]+)")},
- {13, new Regex(@"^(?:\\s)")},
- {14, new Regex(@"^(?:[.])")},
- {15, new Regex(@"^(?::)")},
- {16, new Regex(@"^(?:;)")},
- {17, new Regex(@"^(?:,)")},
- {18, new Regex(@"^(?:\*)")},
- {19, new Regex(@"^(?:\/)")},
- {20, new Regex(@"^(?:-)")},
- {21, new Regex(@"^(?:\+)")},
- {22, new Regex(@"^(?:\^)")},
- {23, new Regex(@"^(?:\()")},
- {24, new Regex(@"^(?:\))")},
- {25, new Regex(@"^(?:>)")},
- {26, new Regex(@"^(?:<)")},
- {27, new Regex(@"^(?:NOT\b)")},
- {28, new Regex(@"^(?:E\b)")},
- {29, new Regex(@"^(?:"")")},
- {30, new Regex(@"^(?:')")},
- {31, new Regex(@"^(?:!)")},
- {32, new Regex(@"^(?:=)")},
- {33, new Regex(@"^(?:%)")},
- {34, new Regex(@"^(?:[#])")},
- {35, new Regex(@"^(?:$)")}
+ {0, new Regex(@"\G(?:\s+)")},
+ {1, new Regex(@"\G(?:""(\\[""]|[^""])*"")")},
+ {2, new Regex(@"\G(?:'(\\[']|[^'])*')")},
+ {3, new Regex(@"\G(?:[A-Za-z]{1,}[A-Za-z_0-9]+(?=[(]))")},
+ {4, new Regex(@"\G(?:([0]?[1-9]|1[0-2])[:][0-5][0-9]([:][0-5][0-9])?[ ]?(AM|am|aM|Am|PM|pm|pM|Pm))")},
+ {5, new Regex(@"\G(?:([0]?[0-9]|1[0-9]|2[0-3])[:][0-5][0-9]([:][0-5][0-9])?)")},
+ {6, new Regex(@"\G(?:SHEET[0-9]+)")},
+ {7, new Regex(@"\G(?:\$[A-Za-z]+\$[0-9]+)")},
+ {8, new Regex(@"\G(?:[A-Za-z]+[0-9]+)")},
+ {9, new Regex(@"\G(?:[A-Za-z]+(?=[(]))")},
+ {10, new Regex(@"\G(?:[A-Za-z]{1,}[A-Za-z_0-9]+)")},
+ {11, new Regex(@"\G(?:[A-Za-z_]+)")},
+ {12, new Regex(@"\G(?:[0-9]+)")},
+ {13, new Regex(@"\G(?:\\s)")},
+ {14, new Regex(@"\G(?:[.])")},
+ {15, new Regex(@"\G(?::)")},
+ {16, new Regex(@"\G(?:;)")},
+ {17, new Regex(@"\G(?:,)")},
+ {18, new Regex(@"\G(?:\*)")},
+ {19, new Regex(@"\G(?:\/)")},
+ {20, new Regex(@"\G(?:-)")},
+ {21, new Regex(@"\G(?:\+)")},
+ {22, new Regex(@"\G(?:\^)")},
+ {23, new Regex(@"\G(?:\()")},
+ {24, new Regex(@"\G(?:\))")},
+ {25, new Regex(@"\G(?:>)")},
+ {26, new Regex(@"\G(?:<)")},
+ {27, new Regex(@"\G(?:NOT\b)")},
+ {28, new Regex(@"\G(?:E\b)")},
+ {29, new Regex(@"\G(?:"")")},
+ {30, new Regex(@"\G(?:')")},
+ {31, new Regex(@"\G(?:!)")},
+ {32, new Regex(@"\G(?:=)")},
+ {33, new Regex(@"\G(?:%)")},
+ {34, new Regex(@"\G(?:[#])")},
+ {35, new Regex(@"\G(?:$)")}
};
Conditions = new Dictionary
@@ -1793,10 +1794,12 @@ public Expression ParserPerformAction(ref Expression thisS, ref Expression yy, r
break;
case 3:
-
+ //
+
break;
case 4:
-
+ //
+
break;
case 5:
@@ -1842,7 +1845,8 @@ public Expression ParserPerformAction(ref Expression thisS, ref Expression yy, r
break;
case 9:
-
+ //
+ thisS = ss[so - 1];
break;
case 10:
@@ -1863,7 +1867,8 @@ public Expression ParserPerformAction(ref Expression thisS, ref Expression yy, r
break;
case 12:
-
+ //
+
ss[so-3].Set(ss[so-3].Text != ss[so].Text);
thisS = ss[so-3];
@@ -1871,7 +1876,8 @@ public Expression ParserPerformAction(ref Expression thisS, ref Expression yy, r
break;
case 13:
-
+ //
+
ss[so-2].Set(ss[so-2].Text != ss[so].Text);
thisS = ss[so-2];
@@ -1970,47 +1976,47 @@ public Expression ParserPerformAction(ref Expression thisS, ref Expression yy, r
- thisS = Spreadsheet.CellValue(Location.ParseFixed(ss[so].Text));
+ thisS = MySpreadsheets.CellValue(MySpreadsheet.ParseFixed(ss[so].Text));
break;
case 29:
-
-
-
- thisS = Spreadsheet.CellValue(Location.ParseFixed(ss[so-2].Text), Location.ParseFixed(ss[so].Text));
+
+
+
+ thisS = MySpreadsheets.CellValue(MySpreadsheet.ParseFixed(ss[so - 2].Text), MySpreadsheet.ParseFixed(ss[so].Text));
break;
case 30:
-
-
-
- thisS = Spreadsheet.CellValue(Location.Parse(ss[so].Text));
+
+
+
+ thisS = MySpreadsheets.CellValue(MySpreadsheet.Parse(ss[so].Text));
break;
case 31:
-
-
-
- thisS = Spreadsheet.CellValue(Location.Parse(ss[so-2].Text), Location.Parse(ss[so].Text));
+
+
+
+ thisS = MySpreadsheets.CellValue(MySpreadsheet.Parse(ss[so - 2].Text), MySpreadsheet.Parse(ss[so].Text));
break;
case 32:
-
-
-
- thisS = Spreadsheet.CellValue(Location.ParseRemote(ss[so-2].Text, ss[so].Text));
+
+
+
+ thisS = MySpreadsheets.CellValue(MySpreadsheet.ParseRemote(ss[so - 2].Text, ss[so].Text));
break;
case 33:
-
-
-
- thisS = Spreadsheet.CellValue(Location.ParseRemote(ss[so-4].Text, ss[so-2].Text), Location.ParseRemote(ss[so-4].Text, ss[so].Text));
+
+
+
+ thisS = MySpreadsheets.CellValue(MySpreadsheet.ParseRemote(ss[so - 4].Text, ss[so - 2].Text), MySpreadsheet.ParseRemote(ss[so - 4].Text, ss[so].Text));
break;
@@ -2281,24 +2287,22 @@ public Expression Parse(string input)
public ParserSymbol Eof = new ParserSymbol("Eof", 1);
public Expression Yy = new Expression();
public string Match = "";
- public string Matched = "";
public Stack ConditionStack;
public Dictionary Rules;
public Dictionary Conditions;
public bool Done = false;
public bool Less;
public bool _More;
- public string _Input;
+ public InputReader _Input;
public int Offset;
public DictionaryRanges;
public bool Flex = false;
public void SetInput(string input)
{
- _Input = input;
+ _Input = new InputReader(input);
_More = Less = Done = false;
Yy.LineNo = Yy.Leng = 0;
- Matched = Match = "";
ConditionStack = new Stack();
ConditionStack.Push("INITIAL");
@@ -2314,12 +2318,11 @@ public void SetInput(string input)
public string Input()
{
- string ch = _Input[0].ToString();
+ string ch = _Input.Ch();
Yy.Text += ch;
Yy.Leng++;
Offset++;
Match += ch;
- Matched += ch;
Match lines = Regex.Match(ch, "/(?:\r\n?|\n).*/");
if (lines.Success) {
Yy.LineNo++;
@@ -2333,26 +2336,28 @@ public string Input()
Yy.Loc.Range.Y++;
}
- _Input = _Input.Substring(1);
return ch;
}
public void Unput(string ch)
{
+ var yy = new Expression();
int len = ch.Length;
var lines = Regex.Split(ch, "/(?:\r\n?|\n)/");
- _Input = ch + _Input;
- Yy.Text = Yy.Text.Substring(0, len - 1);
+ _Input.unCh(ch.Length);
+ yy.Text = Yy.Text.Substring(0, len - 1);
Offset -= len;
var oldLines = Regex.Split(Match, "/(?:\r\n?|\n)/");
Match = Match.Substring(0, Match.Length - 1);
- Matched = Matched.Substring(0, Matched.Length - 1);
- if ((lines.Length - 1) > 0) Yy.LineNo -= lines.Length - 1;
+ if ((lines.Length - 1) > 0)
+ {
+ yy.LineNo -= Yy.LineNo - lines.Length - 1;
+ }
var r = Yy.Loc.Range;
- Yy.Loc = new ParserLocation(
+ yy.Loc = new ParserLocation(
Yy.Loc.FirstLine,
Yy.LineNo + 1,
Yy.Loc.FirstColumn,
@@ -2368,8 +2373,10 @@ public void Unput(string ch)
);
if (Ranges.Count > 0) {
- Yy.Loc.Range = new ParserRange(r.X, r.X + Yy.Leng - len);
+ yy.Loc.Range = new ParserRange(r.X, r.X + Yy.Leng - len);
}
+
+ UnputStack.Push(yy);
}
public void More()
@@ -2379,8 +2386,8 @@ public void More()
public string PastInput()
{
- var past = Matched.Substring(0, Matched.Length - Match.Length);
- return (past.Length > 20 ? "..." + Regex.Replace(past.Substring(-20), "/\n/", "") : "");
+ var past = _Input.ToString().Substring(0, _Input.Position - Match.Length);
+ return (past.Length > 20 ? "..." + Regex.Replace(past.Substring(20), "/\n/", "") : "");
}
public string UpcomingInput()
@@ -2388,7 +2395,7 @@ public string UpcomingInput()
var next = Match;
if (next.Length < 20)
{
- next += _Input.Substring(0, (next.Length > 20 ? 20 - next.Length : next.Length));
+ next += _Input.ToString().Substring(0, (next.Length > 20 ? 20 - next.Length : next.Length));
}
return Regex.Replace(next.Substring(0, (next.Length > 20 ? 20 - next.Length : next.Length)) + (next.Length > 20 ? "..." : ""), "/\n/", "");
}
@@ -2408,12 +2415,17 @@ public string ShowPosition()
public ParserSymbol Next()
{
- if (Done == true)
+ if (UnputStack.Count > 0)
+ {
+ Yy = UnputStack.Pop();
+ }
+
+ if (Done == true)
{
return Eof;
}
- if (String.IsNullOrEmpty(_Input))
+ if (_Input.Done)
{
Done = true;
}
@@ -2432,8 +2444,8 @@ public ParserSymbol Next()
for (int i = 0; i < rules.Count; i++)
{
rule = Rules[rules[i]];
- var tempMatch = rule.Match(_Input);
- if (tempMatch.Success == true && (match != null || tempMatch.Length > match.Length)) {
+ var tempMatch = _Input.Match(rule);
+ if (tempMatch.Success && tempMatch.Length > match.Length) {
match = tempMatch.Value;
matched = true;
index = i;
@@ -2454,7 +2466,6 @@ public ParserSymbol Next()
Yy.Text += match;
Match += match;
- Matched += match;
Yy.Leng = Yy.Text.Length;
if (Ranges != null)
@@ -2462,13 +2473,13 @@ public ParserSymbol Next()
Yy.Loc.Range = new ParserRange(Offset, Offset += Yy.Leng);
}
_More = false;
- _Input = _Input.Substring(match.Length);
+ _Input.AddMatch(match);
var ruleIndex = rules[index];
var nextCondition = ConditionStack.Peek();
dynamic action = LexerPerformAction(ruleIndex, nextCondition);
ParserSymbol token = Symbols[action];
- if (Done == true && String.IsNullOrEmpty(_Input) == false)
+ if (Done == true || _Input.Done)
{
Done = false;
}
@@ -2480,7 +2491,7 @@ public ParserSymbol Next()
}
}
- if (String.IsNullOrEmpty(_Input)) {
+ if (_Input.Done) {
return Symbols["EOF"];
} else
{
@@ -2655,6 +2666,18 @@ public ParserLocation(int firstLine, int lastLine, int firstColumn, int lastColu
LastColumn = lastColumn;
Range = range;
}
+
+ public ParserLocation Clone()
+ {
+ var parserLocation = new ParserLocation(FirstLine, LastLine,FirstColumn,LastColumn);
+
+ if (Range != null)
+ {
+ parserLocation.Range = Range.Clone();
+ }
+
+ return parserLocation;
+ }
}
public class LexerConditions
@@ -2817,6 +2840,12 @@ public ParserRange(int x, int y)
X = x;
Y = y;
}
+
+ public ParserRange Clone()
+ {
+ var parserRange = new ParserRange(X, Y);
+ return parserRange;
+ }
}
public class ParserSymbols
@@ -2869,18 +2898,22 @@ public class ParserValue
public ParserValue()
{
}
-
- public ParserValue(ParserValue parserValue)
- {
- Text = parserValue.Text;
- Leng = parserValue.Leng;
- Loc = parserValue.Loc;
- LineNo = parserValue.LineNo;
- }
+
+ public ParserValue(string text, ParserLocation loc, int leng, int lineNo)
+ {
+ Text = text;
+ Loc = loc;
+ Leng = leng;
+ LineNo = lineNo;
+ }
public ParserValue Clone()
{
- return new ParserValue(this);
+ var parserValue = new ParserValue();
+ parserValue.Text = this.Text;
+
+
+ return parserValue;
}
}
@@ -2891,9 +2924,17 @@ public void Push(T item)
Add(item);
}
- public void Pop()
+ public T Pop()
{
- RemoveAt(Count - 1);
+ var i = Math.Max(0, Count - 1);
+ if (i == 0)
+ {
+ return null;
+ }
+
+ var val = this[i];
+ RemoveAt(i);
+ return val;
}
new public T this[int index]
@@ -2908,4 +2949,57 @@ public void Pop()
}
}
}
+
+
+ public class InputReader
+ {
+
+ public bool Done = false;
+ public string Input;
+ public int Length;
+ public JList Matches = new JList();
+ public int Position = 0;
+
+ public InputReader(string input)
+ {
+ Input = input;
+ Length = input.Length;
+ }
+
+ public void AddMatch (string match) {
+ Matches.Push(match);
+ Position += match.Length;
+ Done = (Position >= Length);
+ }
+
+ public string Ch()
+ {
+ var ch = Input[Position].ToString();
+ AddMatch(ch);
+ return ch;
+ }
+
+ public void unCh(int chLength)
+ {
+ Position -= chLength;
+ Position = Math.Max(0, Position);
+ Done = (Position >= Length);
+ }
+
+ public string Substring(int start, int end) {
+ start = (start != 0 ? Position + start : Position);
+ end = (end != 0 ? start + end : Length);
+ return Input.Substring(start, end);
+ }
+
+ public Match Match(Regex rule) {
+ var match = rule.Match(Input, Position);
+ return match;
+ }
+
+ public new string ToString()
+ {
+ return String.Join("", Matches.ToArray());
+ }
+ }
}
\ No newline at end of file
diff --git a/ports/csharp/Jison/Jison/Test/FormulaBase.cs b/ports/csharp/Jison/Jison/Test/FormulaBase.cs
new file mode 100644
index 000000000..324e88c62
--- /dev/null
+++ b/ports/csharp/Jison/Jison/Test/FormulaBase.cs
@@ -0,0 +1,21 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Sheet
+{
+ public class FormulaBase
+ {
+ public Cell Parent;
+ public Spreadsheet MySpreadsheet;
+ public Spreadsheets MySpreadsheets;
+
+ public void Setup(Cell cell)
+ {
+ Parent = cell;
+ MySpreadsheet = cell.Parent.Parent;
+ MySpreadsheets = MySpreadsheet.Parent;
+ }
+ }
+}
diff --git a/ports/csharp/Jison/Jison/Test/Functions.cs b/ports/csharp/Jison/Jison/Test/Functions.cs
index 4edce4b0a..af43a4242 100644
--- a/ports/csharp/Jison/Jison/Test/Functions.cs
+++ b/ports/csharp/Jison/Jison/Test/Functions.cs
@@ -2,7 +2,7 @@
using System.Collections.Generic;
using Jison;
-namespace jQuerySheet
+namespace Sheet
{
public static class Functions
{
@@ -39,7 +39,7 @@ public static Expression Sum(Expression value)
return firstChild;
}
- value.ToDouble ();
+ value.ToDouble();
return value;
}
}
diff --git a/ports/csharp/Jison/Jison/Test/Location.cs b/ports/csharp/Jison/Jison/Test/Location.cs
index 6864d4aec..edb812ab8 100644
--- a/ports/csharp/Jison/Jison/Test/Location.cs
+++ b/ports/csharp/Jison/Jison/Test/Location.cs
@@ -2,7 +2,7 @@
using System.Collections.Generic;
using System.Text.RegularExpressions;
-namespace jQuerySheet
+namespace Sheet
{
public class Location
{
@@ -48,26 +48,6 @@ public Location ()
static readonly public Regex Cell = new Regex("^([A-Z]+)([0-9]+)");
- public static Location Parse(string id)
- {
- return new Location(id);
- }
-
- public static Location ParseRemote(string sheet, string id)
- {
- return new Location(sheet, id);
- }
-
- public static Location ParseFixed(string id)
- {
- return new Location(id, true);
- }
-
- public static Location ParseRemoteFixed(string sheet, string id)
- {
- return new Location(sheet, id, true);
- }
-
public void ParseCellId(string id)
{
var match = Cell.Match(id);
@@ -76,7 +56,6 @@ public void ParseCellId(string id)
Col = Alphabet[match.Groups[1].Value];
Row = Convert.ToInt32(match.Groups[2].Value) - 1;
}
- Sheet = Spreadsheet.ActiveSpreadsheet;
}
public void ParseSheetId(string sheet)
@@ -85,9 +64,10 @@ public void ParseSheetId(string sheet)
Sheet = Convert.ToInt32(sheet);
}
- public Location(string id)
+ public Location(Spreadsheet spreadsheet, string id)
{
ParseCellId(id);
+ Sheet = spreadsheet.Index;
}
public Location(string sheet, string id)
diff --git a/ports/csharp/Jison/Jison/Test/Row.cs b/ports/csharp/Jison/Jison/Test/Row.cs
new file mode 100644
index 000000000..fe130b720
--- /dev/null
+++ b/ports/csharp/Jison/Jison/Test/Row.cs
@@ -0,0 +1,51 @@
+using System;
+using System.Collections.Generic;
+
+namespace Sheet
+{
+ public class Row: Dictionary
+ {
+ public Spreadsheet Parent;
+ public int CellIndex = -1;
+
+ public Row ()
+ {
+ }
+
+ public Cell AddCell()
+ {
+ return AddCell("", false);
+ }
+
+ public Cell AddCell(string value)
+ {
+ return AddCell(value, false);
+ }
+
+ public Cell AddCell(string value, bool isFormula)
+ {
+ var cell = new Cell();
+ CellIndex++;
+ cell.Parent = this;
+
+ if (isFormula)
+ {
+ cell.Formula = value;
+ cell.HasFormula = true;
+ }
+ else
+ {
+ cell.Value = value;
+ }
+
+ Add(CellIndex, cell);
+ return cell;
+ }
+
+ public Cell this[string col]
+ {
+ get { return this[Location.Alphabet[col]]; }
+ }
+ }
+}
+
diff --git a/ports/csharp/Jison/Jison/Test/RowDictionary.cs b/ports/csharp/Jison/Jison/Test/RowDictionary.cs
deleted file mode 100644
index a29ecd704..000000000
--- a/ports/csharp/Jison/Jison/Test/RowDictionary.cs
+++ /dev/null
@@ -1,13 +0,0 @@
-using System;
-using System.Collections.Generic;
-
-namespace jQuerySheet
-{
- public class RowDictionary : Dictionary
- {
- public RowDictionary ()
- {
- }
- }
-}
-
diff --git a/ports/csharp/Jison/Jison/Test/Spreadsheet.cs b/ports/csharp/Jison/Jison/Test/Spreadsheet.cs
index 44be3f8fe..a8fdc7f10 100644
--- a/ports/csharp/Jison/Jison/Test/Spreadsheet.cs
+++ b/ports/csharp/Jison/Jison/Test/Spreadsheet.cs
@@ -1,73 +1,67 @@
-using System;
-using System.Text;
-using System.Threading.Tasks;
+using System;
using System.Collections.Generic;
-namespace jQuerySheet
+namespace Sheet
{
- public class Spreadsheet
- {
- static public int ActiveSpreadsheet = 0;
- static public SpreadsheetsDictionary Spreadsheets;
-
-
- public SpreadsheetsDictionary Calc()
+ public class Spreadsheet : Dictionary
+ {
+ public Spreadsheets Parent;
+ public int Index;
+ public int RowIndex = -1;
+ public Row AddRow()
{
- foreach (var Spreadsheet in Spreadsheets.Values) {
- foreach (var row in Spreadsheet.Values) {
- foreach (var cell in row) {
- cell.Value.UpdateValue();
- }
- }
- }
-
- return Spreadsheets;
+ var row = new Row();
+ RowIndex++;
+ row.Parent = this;
+ Add(RowIndex, row);
+ return row;
}
- public static DateTime CalcLast;
+ public Cell this[string colString, int rowInt]
+ {
+ get {
+ var row = this[rowInt - 1];
+
+ var colInt = Location.Alphabet[colString];
+ var cell = row[colInt];
+ return cell;
+ }
+ }
- public static Expression UpdateCellValue(Cell cell)
+ public Cell this[int colInt, int rowInt]
{
- if (cell.HasFormula && cell.State.Count < 1)
+ get
{
- cell.State.Push("Parsing");
- cell.CalcCount++;
- cell.CalcLast = CalcLast;
- var formula = new Formula();
- var value = formula.Parse(cell.Formula);
- cell.State.Pop();
- return value;
+ var row = this[rowInt];
+ var cell = row[colInt];
+ return cell;
}
- return cell.Exp;
}
- public static Expression CellValue(int spreadsheet, int row, int col)
- {
- var cell = Spreadsheets[spreadsheet][row][col];
- var value = UpdateCellValue(cell);
- return value;
- }
+ public Spreadsheet(int index)
+ : base() {
+ Index = index;
+ }
- public static Expression CellValue(Location loc)
+ public Location Parse(string id)
{
- var cell = Spreadsheets[loc.Sheet][loc.Row][loc.Col];
- var value = UpdateCellValue(cell);
- return value;
+ return new Location(this, id);
}
- public static Expression CellValue(Location locStart, Location locEnd)
+ public Location ParseRemote(string sheet, string id)
{
- var range = new Expression();
+ return new Location(sheet, id);
+ }
- for (var row = locStart.Row; row <= locEnd.Row; row++)
- {
- for (var col = locStart.Col; col <= locEnd.Col; col++)
- {
- range.Push(Spreadsheets[locStart.Sheet][row][col].UpdateValue());
- }
- }
+ public Location ParseFixed(string id)
+ {
+ return new Location(id, true);
+ }
- return range;
+ public Location ParseRemoteFixed(string sheet, string id)
+ {
+ return new Location(sheet, id, true);
}
- }
+ }
}
+
diff --git a/ports/csharp/Jison/Jison/Test/SpreadsheetDictionary.cs b/ports/csharp/Jison/Jison/Test/SpreadsheetDictionary.cs
deleted file mode 100644
index a4441bf0c..000000000
--- a/ports/csharp/Jison/Jison/Test/SpreadsheetDictionary.cs
+++ /dev/null
@@ -1,19 +0,0 @@
-using System;
-using System.Collections.Generic;
-using jQuerySheet;
-
-namespace jQuerySheet
-{
- public class SpreadsheetDictionary : Dictionary
- {
- public int RowIndex = -1;
- public RowDictionary ActiveRow;
- public void AddRow()
- {
- ActiveRow = new RowDictionary();
- RowIndex++;
- Add (RowIndex, ActiveRow);
- }
- }
-}
-
diff --git a/ports/csharp/Jison/Jison/Test/Spreadsheets.cs b/ports/csharp/Jison/Jison/Test/Spreadsheets.cs
new file mode 100644
index 000000000..7831afec8
--- /dev/null
+++ b/ports/csharp/Jison/Jison/Test/Spreadsheets.cs
@@ -0,0 +1,88 @@
+using System;
+using System.Linq;
+using System.Collections.Generic;
+
+namespace Sheet
+{
+ public class Spreadsheets : Dictionary
+ {
+ public int ActiveSpreadsheet = -1;
+ public int SpreadsheetIndex = -1;
+
+ public void Calc()
+ {
+ foreach (var spreadsheet in Values) {
+ foreach (var row in spreadsheet.Values) {
+ foreach (var cell in row) {
+ cell.Value.UpdateValue();
+ }
+ }
+ }
+ }
+
+ public DateTime CalcLast;
+
+ public Expression UpdateCellValue(Cell cell)
+ {
+ if (cell.HasFormula && cell.State.Count < 1)
+ {
+ cell.State.Push("Parsing");
+ cell.CalcCount++;
+ cell.CalcLast = CalcLast;
+ var formula = new Formula();
+ var value = formula.Parse(cell.Formula);
+ cell.State.Pop();
+ return value;
+ }
+ return cell.Exp;
+ }
+
+ public Expression CellValue(int spreadsheet, int row, int col)
+ {
+ Cell cell = Values.ElementAt(spreadsheet)
+ .Values.ElementAt(row)
+ .Values.ElementAt(col);
+
+ var value = UpdateCellValue(cell);
+ return value;
+ }
+
+ public Expression CellValue(Location loc)
+ {
+ Cell cell = Values.ElementAt(loc.Sheet)
+ .Values.ElementAt(loc.Row)
+ .Values.ElementAt(loc.Col);
+
+ var value = UpdateCellValue(cell);
+ return value;
+ }
+
+ public Expression CellValue(Location locStart, Location locEnd)
+ {
+ var range = new Expression();
+
+ for (var row = locStart.Row; row <= locEnd.Row; row++)
+ {
+ for (var col = locStart.Col; col <= locEnd.Col; col++)
+ {
+ range.Push(
+ Values.ElementAt(locStart.Sheet)
+ .Values.ElementAt(row)
+ .Values.ElementAt(col).UpdateValue()
+ );
+ }
+ }
+
+ return range;
+ }
+
+ public Spreadsheet AddSpreadsheet()
+ {
+ SpreadsheetIndex++;
+ var spreadsheet = new Spreadsheet(SpreadsheetIndex);
+ spreadsheet.Parent = this;
+ Add(SpreadsheetIndex, spreadsheet);
+ return spreadsheet;
+ }
+ }
+}
diff --git a/ports/csharp/Jison/Jison/Test/SpreadsheetsDictionary.cs b/ports/csharp/Jison/Jison/Test/SpreadsheetsDictionary.cs
deleted file mode 100644
index 0c0dfa11e..000000000
--- a/ports/csharp/Jison/Jison/Test/SpreadsheetsDictionary.cs
+++ /dev/null
@@ -1,10 +0,0 @@
-using System;
-using System.Collections.Generic;
-
-namespace jQuerySheet
-{
- public class SpreadsheetsDictionary : Dictionary
- {
- }
-}
-
diff --git a/ports/csharp/Jison/Jison/Test/formula.jison b/ports/csharp/Jison/Jison/Test/formula.jison
index 9814f4636..c37e931a8 100644
--- a/ports/csharp/Jison/Jison/Test/formula.jison
+++ b/ports/csharp/Jison/Jison/Test/formula.jison
@@ -1,5 +1,6 @@
//option parserValue:Expression
-//option namespace:jQuerySheet
+//option namespace:Sheet
+//option extends:FormulaBase
/* description: Parses end evaluates mathematical expressions. */
/* lexical grammar */
@@ -204,7 +205,10 @@ expression :
{
//js
$$ = yy.handler.number.apply(yy.obj, [$2]);
- //
+
+ /*cs
+ $$ = $2;
+ */
}
| expression '<' '=' expression
{
@@ -417,7 +421,7 @@ cell :
//php $$ = $this->fixedCellValue($1);
/*cs
- $$ = Spreadsheet.CellValue(Location.ParseFixed($1.Text));
+ $$ = MySpreadsheets.CellValue(MySpreadsheet.ParseFixed($1.Text));
*/
}
| FIXEDCELL ':' FIXEDCELL
@@ -428,7 +432,7 @@ cell :
//php $$ = $this->fixedCellRangeValue($1, $3);
/*cs
- $$ = Spreadsheet.CellValue(Location.ParseFixed($1.Text), Location.ParseFixed($3.Text));
+ $$ = MySpreadsheets.CellValue(MySpreadsheet.ParseFixed($1.Text), MySpreadsheet.ParseFixed($3.Text));
*/
}
| CELL
@@ -439,7 +443,7 @@ cell :
//php $$ = $this->cellValue($1);
/*cs
- $$ = Spreadsheet.CellValue(Location.Parse($1.Text));
+ $$ = MySpreadsheets.CellValue(MySpreadsheet.Parse($1.Text));
*/
}
| CELL ':' CELL
@@ -450,7 +454,7 @@ cell :
//php $$ = $this->cellRangeValue($1, $3);
/*cs
- $$ = Spreadsheet.CellValue(Location.Parse($1.Text), Location.Parse($3.Text));
+ $$ = MySpreadsheets.CellValue(MySpreadsheet.Parse($1.Text), MySpreadsheet.Parse($3.Text));
*/
}
| SHEET '!' CELL
@@ -461,7 +465,7 @@ cell :
//php $$ = $this->remoteCellValue($1, $3);
/*cs
- $$ = Spreadsheet.CellValue(Location.ParseRemote($1.Text, $3.Text));
+ $$ = MySpreadsheets.CellValue(MySpreadsheet.ParseRemote($1.Text, $3.Text));
*/
}
| SHEET '!' CELL ':' CELL
@@ -472,7 +476,7 @@ cell :
//php $$ = $this->remoteCellRangeValue($1, $3, $5);
/*cs
- $$ = Spreadsheet.CellValue(Location.ParseRemote($1.Text, $3.Text), Location.ParseRemote($1.Text, $5.Text));
+ $$ = MySpreadsheets.CellValue(MySpreadsheet.ParseRemote($1.Text, $3.Text), MySpreadsheet.ParseRemote($1.Text, $5.Text));
*/
}
;
diff --git a/ports/csharp/Jison/Jison/bin/Debug/Jison.exe b/ports/csharp/Jison/Jison/bin/Debug/Jison.exe
deleted file mode 100755
index 2d64ad580..000000000
Binary files a/ports/csharp/Jison/Jison/bin/Debug/Jison.exe and /dev/null differ
diff --git a/ports/csharp/Jison/Jison/bin/Debug/Jison.exe.config b/ports/csharp/Jison/Jison/bin/Debug/Jison.exe.config
deleted file mode 100644
index 8e1564635..000000000
--- a/ports/csharp/Jison/Jison/bin/Debug/Jison.exe.config
+++ /dev/null
@@ -1,6 +0,0 @@
-
-
-
-
-
-
\ No newline at end of file
diff --git a/ports/csharp/Jison/Jison/bin/Debug/Jison.pdb b/ports/csharp/Jison/Jison/bin/Debug/Jison.pdb
deleted file mode 100644
index 3c2fef7fb..000000000
Binary files a/ports/csharp/Jison/Jison/bin/Debug/Jison.pdb and /dev/null differ
diff --git a/ports/csharp/Jison/Jison/bin/Debug/Jison.vshost.exe b/ports/csharp/Jison/Jison/bin/Debug/Jison.vshost.exe
deleted file mode 100644
index 8c8451740..000000000
Binary files a/ports/csharp/Jison/Jison/bin/Debug/Jison.vshost.exe and /dev/null differ
diff --git a/ports/csharp/Jison/Jison/bin/Debug/Jison.vshost.exe.config b/ports/csharp/Jison/Jison/bin/Debug/Jison.vshost.exe.config
deleted file mode 100644
index 8e1564635..000000000
--- a/ports/csharp/Jison/Jison/bin/Debug/Jison.vshost.exe.config
+++ /dev/null
@@ -1,6 +0,0 @@
-
-
-
-
-
-
\ No newline at end of file
diff --git a/ports/csharp/Jison/Jison/build.bat b/ports/csharp/Jison/Jison/build.bat
new file mode 100644
index 000000000..a25546ea3
--- /dev/null
+++ b/ports/csharp/Jison/Jison/build.bat
@@ -0,0 +1 @@
+node csharp.js Test\formula.jison
\ No newline at end of file
diff --git a/ports/csharp/Jison/Jison/csharp.js b/ports/csharp/Jison/Jison/csharp.js
index 76c5d8adf..4da738d95 100644
--- a/ports/csharp/Jison/Jison/csharp.js
+++ b/ports/csharp/Jison/Jison/csharp.js
@@ -24,9 +24,10 @@ exec("jison " + process.argv[2], function (error) {
String.prototype.trim=function(){return this.replace(/^\s+|\s+$/g, '');};
- var fileName = process.argv[2].replace(/(.jison|.json)/, '')
+ var jisonFileName = process.argv[2],
+ fileName = jisonFileName.replace('.jison', ''),
comments = require(path.resolve(__dirname, '../../../comments.js')),
- requirePath = fileName + '.js';
+ requirePath = path.resolve(jisonFileName).replace('.jison', '') + '.js';
console.log("Opening newly created jison js file: " + fileName + '.js');
@@ -85,27 +86,31 @@ exec("jison " + process.argv[2], function (error) {
}
str = comments.parse(str);
- str = str.replace(/(\d)\n/g, function () {
+ str = str.replace(/(\d)(\n|\r\n)/g, function () {
return arguments[1] + ';\n';
});
return str;
}
- var FileName = fileName.charAt(0).toUpperCase() + fileName.slice(1);
- var ClassName = FileName.replace(/^.*[\\\/]/, '').charAt(0).toUpperCase() + FileName.replace(/^.*[\\\/]/, '').slice(1);
+ function capitaliseFirstLetter(string) {
+ return string.charAt(0).toUpperCase() + string.slice(1);
+ }
+
+ var FileName = capitaliseFirstLetter(fileName);
var option = {
'using': '',
'namespace': 'Jison',
- 'class': ClassName,
+ 'class': capitaliseFirstLetter(FileName.split(/[/\\]/g).pop()),
'fileName': FileName + '.cs',
+ 'extends': '',
'parserValue': ''
};
-
- if (fileName.search(/jison/) !== -1) {
+ if (jisonFileName.match(/jison$/i)) {
var parserDefinition = fs.readFileSync(fileName + '.jison', "utf8");
parserDefinition = parserDefinition.split(/\n/g);
+
for (var i = 0; i < parserDefinition.length; i++) {
if (parserDefinition[i].match('//option')) {
parserDefinition[i] = parserDefinition[i].replace('//option ', '').trim();
@@ -115,7 +120,11 @@ exec("jison " + process.argv[2], function (error) {
}
}
- console.log(option);
+ console.log("\nUsing options:");
+ for (i in option) {
+ console.log(i + ' = ' + option[i]);
+ }
+ console.log("\n");
var parserRaw = fs.readFileSync(__dirname + "/Template.cs", "utf8");
@@ -147,19 +156,19 @@ exec("jison " + process.argv[2], function (error) {
for (var i in this.symbolsByIndex) {
var symbol = this.symbolsByIndex[i];
- result += '\t\t\tvar symbol' + symbol.index + ' = new ParserSymbol("' + symbol.name + '", ' + symbol.index + ');\n';
- this.symbols.push('\t\t\tSymbols.Add(symbol' + symbol.index + ')');
+ result += ' var symbol' + symbol.index + ' = new ParserSymbol("' + symbol.name + '", ' + symbol.index + ');\n';
+ this.symbols.push(' Symbols.Add(symbol' + symbol.index + ')');
}
- result += '\n\n\t\t\tSymbols = new ParserSymbols();\n';
+ result += '\n\n Symbols = new ParserSymbols();\n';
result += this.symbols.join(';\n') + ';\n\n';
for (var i in terminals) {
- this.terminals.push('\t\t\t\t\t{' + i + ', symbol' + i + '}');
+ this.terminals.push(' {' + i + ', symbol' + i + '}');
}
- result += '\t\t\tTerminals = new Dictionary\n\t\t\t\t{\n' + this.terminals.join(',\n') + '\n\t\t\t\t};\n\n';
+ result += ' Terminals = new Dictionary\n {\n' + this.terminals.join(',\n') + '\n };\n\n';
for (var i in table) {
var items = [];
@@ -170,50 +179,50 @@ exec("jison " + process.argv[2], function (error) {
if (item.join) { //is array
if (item.length == 1) {
action = item[0];
- items.push('\t\t\t\t\t{' + j + ', new ParserAction(' + actions[action] + ')}');
+ items.push(' {' + j + ', new ParserAction(' + actions[action] + ')}');
} else {
action = item[0];
state = item[1];
- items.push('\t\t\t\t\t{' + j + ', new ParserAction(' + actions[action] + ', ref table' + state + ')}');
+ items.push(' {' + j + ', new ParserAction(' + actions[action] + ', ref table' + state + ')}');
}
} else {
state = item;
- items.push('\t\t\t\t\t{' + j + ', new ParserAction(' + actions[action] + ', ref table' + state + ')}');
+ items.push(' {' + j + ', new ParserAction(' + actions[action] + ', ref table' + state + ')}');
}
}
- this.tableInstantiation.push('\t\t\tvar table' + i + ' = new ParserState(' + i + ')');
- this.tableDefinition.push('\t\t\tvar tableDefinition' + i + ' = new Dictionary\n\t\t\t\t{\n' + items.join(',\n') + '\n\t\t\t\t}');
- this.tableSetActions.push('\t\t\ttable' + i + '.SetActions(ref tableDefinition' + i + ')');
- this.table.push('\t\t\t\t\t{' + i + ', table' + i + '}');
+ this.tableInstantiation.push(' var table' + i + ' = new ParserState(' + i + ')');
+ this.tableDefinition.push(' var tableDefinition' + i + ' = new Dictionary\n {\n' + items.join(',\n') + '\n }');
+ this.tableSetActions.push(' table' + i + '.SetActions(ref tableDefinition' + i + ')');
+ this.table.push(' {' + i + ', table' + i + '}');
}
result += this.tableInstantiation.join(';\n') + ';\n\n';
result += this.tableDefinition.join(';\n\n') + ';\n\n';
result += this.tableSetActions.join(';\n') + ';\n\n';
- result += '\t\t\tTable = new Dictionary\n\t\t\t\t{\n' + this.table.join(',\n') + '\n\t\t\t\t};\n\n';
+ result += ' Table = new Dictionary\n {\n' + this.table.join(',\n') + '\n };\n\n';
for (var i in defaultActions) {
var action = defaultActions[i][0];
var state = defaultActions[i][1];
- this.defaultActions.push('\t\t\t\t\t{' + i + ', new ParserAction(' + actions[action] +', ref table' + state + ')}');
+ this.defaultActions.push(' {' + i + ', new ParserAction(' + actions[action] +', ref table' + state + ')}');
}
- result += '\t\t\tDefaultActions = new Dictionary\n\t\t\t\t{\n' + this.defaultActions.join(',\n') + '\n\t\t\t\t};\n\n';
+ result += ' DefaultActions = new Dictionary\n {\n' + this.defaultActions.join(',\n') + '\n };\n\n';
for (var i in productions) {
var production = productions[i];
if (production.join) {
var symbol = production[0],
len = production[1];
- this.productions.push('\t\t\t\t\t{' + i + ', new ParserProduction(symbol' + this.symbolsByIndex[symbol].index + ',' + len + ')}');
+ this.productions.push(' {' + i + ', new ParserProduction(symbol' + this.symbolsByIndex[symbol].index + ',' + len + ')}');
} else {
var symbol = production;
- this.productions.push('\t\t\t\t\t{' + i + ', new ParserProduction(symbol' + this.symbolsByIndex[symbol].index + ')}');
+ this.productions.push(' {' + i + ', new ParserProduction(symbol' + this.symbolsByIndex[symbol].index + ')}');
}
}
- result += '\t\t\tProductions = new Dictionary\n\t\t\t\t{\t\t\t\t\n' + this.productions.join(',\n') + '\n\t\t\t\t};\n\n\n';
+ result += ' Productions = new Dictionary\n { \n' + this.productions.join(',\n') + '\n };\n\n\n';
return result;
}
@@ -224,16 +233,16 @@ exec("jison " + process.argv[2], function (error) {
this.conditions = [];
for (var i in rules) {
- this.rules.push('\t\t\t\t\t{' + i + ', new Regex(@"' + rules[i].substring(1, rules[i].length - 1).replace(/"/g, '""') + '")}');
+ this.rules.push(' {' + i + ', new Regex(@"\\G' + rules[i].substring(2, rules[i].length - 1).replace(/"/g, '""') + '")}');
}
- result += '\t\t\tRules = new Dictionary\n\t\t\t\t{\n' + this.rules.join(',\n') + '\n\t\t\t\t};\n\n';
+ result += ' Rules = new Dictionary\n {\n' + this.rules.join(',\n') + '\n };\n\n';
for (var i in conditions) {
- this.conditions.push('\t\t\t\t\t{"' + i + '", new LexerConditions(new List { ' + conditions[i].rules.join(',') + ' }, ' + conditions[i].inclusive + ')}');
+ this.conditions.push(' {"' + i + '", new LexerConditions(new List { ' + conditions[i].rules.join(',') + ' }, ' + conditions[i].inclusive + ')}');
}
- result += '\t\t\tConditions = new Dictionary\n\t\t\t\t{\n' + this.conditions.join(',\n') + '\n\t\t\t\t};\n\n';
+ result += ' Conditions = new Dictionary\n {\n' + this.conditions.join(',\n') + '\n };\n\n';
return result;
}
@@ -242,6 +251,7 @@ exec("jison " + process.argv[2], function (error) {
.replace(new RegExp('//@@USING_INJECT@@', 'g'),(option.using ? 'using ' + option.using.split(',').join(';\nusing ') + ';' : ''))
.replace(new RegExp('[/][*][*][/]namespace Jison[/][*][*][/]', 'g'), 'namespace ' + option.namespace)
.replace(new RegExp('[/][*][*][/]class Parser[/][*][*][/]', 'g'), 'class ' + option.class)
+ .replace(new RegExp('[/][*][*]extends[*][*][/]', 'g'), (option.extends ? ' : ' + option.extends : ''))
.replace(new RegExp('[/][*][*][/]public Parser[/][*][*][/]', 'g'), 'public ' + option.class)
.replace(new RegExp('[/][*][*][/]ParserValue[/][*][*][/]', 'g'), (option.parserValue || 'ParserValue'))
.replace('new Parser(', 'new ' + option.class + '(')
diff --git a/ports/csharp/Jison/Jison/formula.js b/ports/csharp/Jison/Jison/formula.js
new file mode 100644
index 000000000..e4068a9b4
--- /dev/null
+++ b/ports/csharp/Jison/Jison/formula.js
@@ -0,0 +1,1305 @@
+/* parser generated by jison 0.4.13 */
+/*
+ Returns a Parser object of the following structure:
+
+ Parser: {
+ yy: {}
+ }
+
+ Parser.prototype: {
+ yy: {},
+ trace: function(),
+ symbols_: {associative list: name ==> number},
+ terminals_: {associative list: number ==> name},
+ productions_: [...],
+ performAction: function anonymous(yytext, yyleng, yylineno, yy, yystate, $$, _$),
+ table: [...],
+ defaultActions: {...},
+ parseError: function(str, hash),
+ parse: function(input),
+
+ lexer: {
+ EOF: 1,
+ parseError: function(str, hash),
+ setInput: function(input),
+ input: function(),
+ unput: function(str),
+ more: function(),
+ less: function(n),
+ pastInput: function(),
+ upcomingInput: function(),
+ showPosition: function(),
+ test_match: function(regex_match_array, rule_index),
+ next: function(),
+ lex: function(),
+ begin: function(condition),
+ popState: function(),
+ _currentRules: function(),
+ topState: function(),
+ pushState: function(condition),
+
+ options: {
+ ranges: boolean (optional: true ==> token location info will include a .range[] member)
+ flex: boolean (optional: true ==> flex-like lexing behaviour where the rules are tested exhaustively to find the longest match)
+ backtrack_lexer: boolean (optional: true ==> lexer regexes are tested in order and for each matching regex the action code is invoked; the lexer terminates the scan when a token is returned by the action code)
+ },
+
+ performAction: function(yy, yy_, $avoiding_name_collisions, YY_START),
+ rules: [...],
+ conditions: {associative list: name ==> set},
+ }
+ }
+
+
+ token location info (@$, _$, etc.): {
+ first_line: n,
+ last_line: n,
+ first_column: n,
+ last_column: n,
+ range: [start_number, end_number] (where the numbers are indexes into the input string, regular zero-based)
+ }
+
+
+ the parseError function receives a 'hash' object with these members for lexer and parser errors: {
+ text: (matched text)
+ token: (the produced terminal token, if any)
+ line: (yylineno)
+ }
+ while parser (grammar) errors will also provide these members, i.e. parser errors deliver a superset of attributes: {
+ loc: (yylloc)
+ expected: (string describing the set of expected tokens)
+ recoverable: (boolean: TRUE when the parser has a error recovery rule available for this particular error)
+ }
+*/
+var formula = (function(){
+var parser = {trace: function trace() { },
+yy: {},
+symbols_: {"error":2,"expressions":3,"expression":4,"EOF":5,"variableSequence":6,"TIME_AMPM":7,"TIME_24":8,"number":9,"STRING":10,"=":11,"+":12,"(":13,")":14,"<":15,">":16,"NOT":17,"-":18,"*":19,"/":20,"^":21,"E":22,"FUNCTION":23,"expseq":24,"cell":25,"FIXEDCELL":26,":":27,"CELL":28,"SHEET":29,"!":30,";":31,",":32,"VARIABLE":33,"DECIMAL":34,"NUMBER":35,"%":36,"#":37,"$accept":0,"$end":1},
+terminals_: {5:"EOF",7:"TIME_AMPM",8:"TIME_24",10:"STRING",11:"=",12:"+",13:"(",14:")",15:"<",16:">",17:"NOT",18:"-",19:"*",20:"/",21:"^",22:"E",23:"FUNCTION",26:"FIXEDCELL",27:":",28:"CELL",29:"SHEET",30:"!",31:";",32:",",33:"VARIABLE",34:"DECIMAL",35:"NUMBER",36:"%",37:"#"},
+productions_: [0,[3,2],[4,1],[4,1],[4,1],[4,1],[4,1],[4,3],[4,3],[4,3],[4,4],[4,4],[4,4],[4,3],[4,3],[4,3],[4,3],[4,3],[4,3],[4,3],[4,2],[4,2],[4,1],[4,3],[4,4],[4,1],[4,1],[4,2],[25,1],[25,3],[25,1],[25,3],[25,3],[25,5],[24,1],[24,3],[24,3],[6,1],[6,3],[9,1],[9,3],[9,2],[2,3],[2,4]],
+performAction: function anonymous(yytext, yyleng, yylineno, yy, yystate /* action[1] */, $$ /* vstack */, _$ /* lstack */) {
+/* this == yyval */
+
+var $0 = $$.length - 1;
+switch (yystate) {
+case 1:return $$[$0-1];
+break;
+case 2:
+ //js
+ this.$ = yy.handler.variable.apply(yy.obj, $$[$0]);
+
+ //php this.$ = $this->variable($$[$0]);
+
+ /*cs
+ this.$ = $$[$0];
+ */
+
+break;
+case 3:
+ //js
+ this.$ = yy.handler.time.apply(yy.obj, [$$[$0], true]);
+ //
+
+break;
+case 4:
+ //js
+ this.$ = yy.handler.time.apply(yy.obj, [$$[$0]]);
+ //
+
+break;
+case 5:
+ //js
+ this.$ = yy.handler.number.apply(yy.obj, [$$[$0]]);
+
+ //php this.$ = $$[$0] * 1;
+
+ /*cs
+ $$[$0].ToDouble();
+ this.$ = $$[$0];
+ */
+
+break;
+case 6:
+ //js
+ this.$ = $$[$0].substring(1, $$[$0].length - 1);
+
+ //php this.$ = substr($$[$0], 1, -1);
+
+ /*cs
+ $$[$0].ToString();
+ this.$ = $$[$0];
+ */
+
+break;
+case 7:
+ //js
+ yy.obj.html.pop();
+ this.$ = yy.handler.callFunction.apply(yy.obj, ['EQUAL', [$$[$0-2], $$[$0]]]);
+
+ //php this.$ = $$[$0-2] == $$[$0];
+
+ /*cs
+ $$[$0-2].Set($$[$0-2].Text == $$[$0].Text);
+ this.$ = $$[$0-2];
+ */
+
+break;
+case 8:
+ //js
+ this.$ = yy.handler.performMath.apply(yy.obj, ['+', $$[$0-2], $$[$0]]);
+ yy.obj.html.pop();
+ yy.obj.html.pop();
+ yy.obj.html.push(null);
+
+ /*php
+ if (is_numeric($$[$0-2]) && is_numeric($$[$0])) {
+ this.$ = $$[$0-2] + $$[$0];
+ } else {
+ this.$ = $$[$0-2] . $$[$0];
+ }
+ */
+
+ /*cs
+ if ($$[$0-2].IsNumeric()) {
+ $$[$0-2].ToDouble();
+ $$[$0-2].Add($$[$0]);
+ this.$ = $$[$0-2];
+ } else {
+ $$[$0-2].ToString();
+ $$[$0-2].Concat($$[$0]);
+ this.$ = $$[$0-2];
+ }
+ */
+
+break;
+case 9:
+ //js
+ this.$ = yy.handler.number.apply(yy.obj, [$$[$0-1]]);
+ //
+
+break;
+case 10:
+ //js
+ this.$ = yy.handler.callFunction.apply(yy.obj, ['LESS_EQUAL', [$$[$0-3], $$[$0-1]]]);
+
+ //php this.$ = ($$[$0-3] * 1) <= ($$[$0] * 1);
+
+ /*cs
+ $$[$0-3].Set($$[$0-3].ToDouble() <= $$[$0].ToDouble());
+ this.$ = $$[$0-3];
+ */
+
+break;
+case 11:
+ //js
+ this.$ = yy.handler.callFunction.apply(yy.obj, ['GREATER_EQUAL', [$$[$0-3], $$[$0-1]]]);
+
+ //php this.$ = ($$[$0-3] * 1) >= ($$[$0] * 1);
+
+ /*cs
+ $$[$0-3].Set($$[$0-3].ToDouble() >= $$[$0].ToDouble());
+ this.$ = $$[$0-3];
+ */
+
+break;
+case 12:
+ //js|php
+ this.$ = ($$[$0-3] * 1) != ($$[$0] * 1);
+
+ //js
+ if (isNaN(this.$)) this.$ = 0;
+ yy.obj.html.pop();
+ yy.obj.html.pop();
+ yy.obj.html.push(null);
+ //
+
+ /*cs
+ $$[$0-3].Set($$[$0-3].Text != $$[$0].Text);
+ this.$ = $$[$0-3];
+ */
+
+break;
+case 13:
+ //js|php
+ this.$ = $$[$0-2] != $$[$0];
+
+ //js
+ yy.obj.html.pop();
+ yy.obj.html.pop();
+ yy.obj.html.push(null);
+ //
+
+ /*cs
+ $$[$0-2].Set($$[$0-2].Text != $$[$0].Text);
+ this.$ = $$[$0-2];
+ */
+
+break;
+case 14:
+ //js
+ this.$ = yy.handler.callFunction.apply(yy.obj, ['GREATER', [$$[$0-2], $$[$0]]]);
+
+ //php this.$ = ($$[$0-2] * 1) > ($$[$0] * 1);
+
+ /*cs
+ $$[$0-2].Set($$[$0-2].ToDouble() > $$[$0].ToDouble());
+ this.$ = $$[$0-2];
+ */
+
+break;
+case 15:
+ //js
+ this.$ = yy.handler.callFunction.apply(yy.obj, ['LESS', [$$[$0-2], $$[$0]]]);
+
+ //php this.$ = ($$[$0-2] * 1) < ($$[$0] * 1);
+
+ /*cs
+ $$[$0-2].Set($$[$0-2].ToDouble() < $$[$0].ToDouble());
+ this.$ = $$[$0-2];
+ */
+
+break;
+case 16:
+ //js|php
+ this.$ = ($$[$0-2] * 1) - ($$[$0] * 1);
+
+ //js
+ this.$ = yy.handler.performMath.apply(yy.obj, ['-', $$[$0-2], $$[$0]]);
+ yy.obj.html.pop();
+ yy.obj.html.pop();
+ yy.obj.html.push(null);
+
+ /*cs
+ $$[$0-2].Set($$[$0-2].ToDouble() - $$[$0].ToDouble());
+ this.$ = $$[$0-2];
+ */
+
+break;
+case 17:
+ //js
+ this.$ = yy.handler.performMath.apply(yy.obj, ['*', $$[$0-2], $$[$0]]);
+ yy.obj.html.pop();
+ yy.obj.html.pop();
+ yy.obj.html.push(null);
+
+ //php this.$ = ($$[$0-2] * 1) * ($$[$0] * 1);
+
+ /*cs
+ $$[$0-2].Set($$[$0-2].ToDouble() * $$[$0].ToDouble());
+ this.$ = $$[$0-2];
+ */
+
+break;
+case 18:
+ //js
+ this.$ = yy.handler.performMath.apply(yy.obj, ['/', $$[$0-2], $$[$0]]);
+ yy.obj.html.pop();
+ yy.obj.html.pop();
+ yy.obj.html.push(null);
+
+ //php this.$ = ($$[$0-2] * 1) / ($$[$0] * 1);
+
+ /*cs
+ $$[$0-2].Set($$[$0-2].ToDouble() / $$[$0].ToDouble());
+ this.$ = $$[$0-2];
+ */
+
+break;
+case 19:
+ //js
+ var n1 = yy.handler.number.apply(yy.obj, [$$[$0-2]]),
+ n2 = yy.handler.number.apply(yy.obj, [$$[$0]]);
+
+ this.$ = yy.handler.performMath.apply(yy.obj, ['^', $$[$0-2], $$[$0]]);
+ yy.obj.html.pop();
+ yy.obj.html.pop();
+ yy.obj.html.push(null);
+
+ //php this.$ = pow(($$[$0-2] * 1), ($$[$0] * 1));
+
+ /*cs
+ $$[$0-2].Set(Math.Pow($$[$0-2].ToDouble(), $$[$0].ToDouble()));
+ this.$ = $$[$0-2];
+ */
+
+break;
+case 20:
+ //js
+ var n1 = yy.handler.number.apply(yy.obj, [$$[$0]]);
+ this.$ = n1 * -1;
+ if (isNaN(this.$)) this.$ = 0;
+
+ //php this.$ = $$[$0-1] * 1;
+
+ /*cs
+ $$[$0].Set(-$$[$0].ToDouble());
+ this.$ = $$[$0];
+ */
+
+break;
+case 21:
+ //js
+ var n1 = yy.handler.number.apply(yy.obj, [$$[$0]]);
+ this.$ = n1 * 1;
+ if (isNaN(this.$)) this.$ = 0;
+
+ //php this.$ = $$[$0-1] * 1;
+
+ /*cs
+ $$[$0].Set($$[$0].ToDouble());
+ this.$ = $$[$0];
+ */
+
+break;
+case 22:/*this.$ = Math.E;*/;
+break;
+case 23:
+ //js
+ this.$ = yy.handler.callFunction.apply(yy.obj, [$$[$0-2], '']);
+
+ //php this.$ = $this->callFunction($$[$0-2]);
+
+ /*cs
+ this.$ = Functions.Call($$[$0-2].Text);
+ */
+
+break;
+case 24:
+ //js
+ this.$ = yy.handler.callFunction.apply(yy.obj, [$$[$0-3], $$[$0-1]]);
+
+ //php this.$ = $this->callFunction($$[$0-3], $$[$0-1]);
+
+ /*cs
+ this.$ = Functions.Call($$[$0-3].Text, $$[$0-1]);
+ */
+
+break;
+case 28:
+ //js
+ this.$ = yy.handler.fixedCellValue.apply(yy.obj, [$$[$0]]);
+
+ //php this.$ = $this->fixedCellValue($$[$0]);
+
+ /*cs
+ this.$ = Spreadsheet.CellValue(Location.ParseFixed($$[$0].Text));
+ */
+
+break;
+case 29:
+ //js
+ this.$ = yy.handler.fixedCellRangeValue.apply(yy.obj, [$$[$0-2], $$[$0]]);
+
+ //php this.$ = $this->fixedCellRangeValue($$[$0-2], $$[$0]);
+
+ /*cs
+ this.$ = Spreadsheet.CellValue(Location.ParseFixed($$[$0-2].Text), Location.ParseFixed($$[$0].Text));
+ */
+
+break;
+case 30:
+ //js
+ this.$ = yy.handler.cellValue.apply(yy.obj, [$$[$0]]);
+
+ //php this.$ = $this->cellValue($$[$0]);
+
+ /*cs
+ this.$ = Spreadsheet.CellValue(Location.Parse($$[$0].Text));
+ */
+
+break;
+case 31:
+ //js
+ this.$ = yy.handler.cellRangeValue.apply(yy.obj, [$$[$0-2], $$[$0]]);
+
+ //php this.$ = $this->cellRangeValue($$[$0-2], $$[$0]);
+
+ /*cs
+ this.$ = Spreadsheet.CellValue(Location.Parse($$[$0-2].Text), Location.Parse($$[$0].Text));
+ */
+
+break;
+case 32:
+ //js
+ this.$ = yy.handler.remoteCellValue.apply(yy.obj, [$$[$0-2], $$[$0]]);
+
+ //php this.$ = $this->remoteCellValue($$[$0-2], $$[$0]);
+
+ /*cs
+ this.$ = Spreadsheet.CellValue(Location.ParseRemote($$[$0-2].Text, $$[$0].Text));
+ */
+
+break;
+case 33:
+ //js
+ this.$ = yy.handler.remoteCellRangeValue.apply(yy.obj, [$$[$0-4], $$[$0-2], $$[$0]]);
+
+ //php this.$ = $this->remoteCellRangeValue($$[$0-4], $$[$0-2], $$[$0]);
+
+ /*cs
+ this.$ = Spreadsheet.CellValue(Location.ParseRemote($$[$0-4].Text, $$[$0-2].Text), Location.ParseRemote($$[$0-4].Text, $$[$0].Text));
+ */
+
+break;
+case 34:
+ //js
+ this.$ = [$$[$0]];
+
+ //php this.$ = array($$[$0]);
+
+ /*cs
+ this.$ = $$[$0];
+ */
+
+break;
+case 35:
+ //js
+ $$[$0-2].push($$[$0]);
+ this.$ = $$[$0-2];
+
+ /*php
+ $$[$0-2][] = $$[$0];
+ this.$ = $$[$0-2];
+ */
+
+ /*cs
+ $$[$0-2].Push($$[$0]);
+ this.$ = $$[$0-2];
+ */
+
+break;
+case 36:
+ //js
+ $$[$0-2].push($$[$0]);
+ this.$ = $$[$0-2];
+
+ /*php
+ $$[$0-2][] = $$[$0];
+ this.$ = $$[$0-2];
+ */
+
+ /*cs
+ $$[$0-2].Push($$[$0]);
+ this.$ = $$[$0-2];
+ */
+
+break;
+case 37:
+ //js
+ this.$ = [$$[$0]];
+
+ //php this.$ = array($$[$0]);
+
+ /*cs
+ this.$ = $$[$0];
+ */
+
+break;
+case 38:
+ //js
+ this.$ = ($.isArray($$[$0-2]) ? $$[$0-2] : [$$[$0-2]]);
+ this.$.push($$[$0]);
+
+ /*php
+ this.$ = (is_array($$[$0-2]) ? $$[$0-2] : array());
+ this.$[] = $$[$0];
+ */
+
+ /*cs
+ $$[$0-2].Push($$[$0]);
+ this.$ = $$[$0-2];
+ */
+
+break;
+case 39:
+ //js|php
+ this.$ = $$[$0] * 1;
+
+ /*cs
+ $$[$0].ToDouble();
+ this.$ = $$[$0];
+ */
+
+break;
+case 40:
+ //js
+ this.$ =($$[$0-2] + '.' + $$[$0]) * 1;
+
+ //php this.$ = $$[$0-2] . '.' . $$[$0];
+
+ /*cs
+ $$[$0-2].Text += "." + $$[$0].Text;
+ $$[$0-2].ToDouble();
+ this.$ = $$[$0-2];
+ */
+
+break;
+case 41:
+ //js
+ yy.obj.html.push($$[$0-1] + $$[$0]);
+
+ //js|php
+ this.$ = $$[$0-1] * 0.01;
+
+ /*cs
+ $$[$0-1].Set($$[$0-1].ToDouble() * 0.01);
+ this.$ = $$[$0-1];
+ */
+
+break;
+case 42:
+ //js
+ this.$ = $$[$0-2] + $$[$0-1] + $$[$0];
+
+ //php this.$ = $$[$0-2] . $$[$0-1] . $$[$0];
+
+ /*cs
+ $$[$0-2].Set($$[$0-2].Text + $$[$0-1].Text + $$[$0].Text);
+ this.$ = $$[$0-2];
+ */
+
+break;
+case 43:
+ //js
+ this.$ = $$[$0-2] + $$[$0-1] + $$[$0];
+
+ //php this.$ = $$[$0-2] . $$[$0-1] . $$[$0];
+
+ /*cs
+ $$[$0-3].Set($$[$0-3].Text + $$[$0-2].Text + $$[$0-1].Text + $$[$0].Text);
+ this.$ = $$[$0-3];
+ */
+
+break;
+}
+},
+table: [{2:14,3:1,4:2,6:3,7:[1,4],8:[1,5],9:6,10:[1,7],12:[1,10],13:[1,8],18:[1,9],22:[1,11],23:[1,12],25:13,26:[1,17],28:[1,18],29:[1,19],33:[1,15],35:[1,16],37:[1,20]},{1:[3]},{5:[1,21],11:[1,22],12:[1,23],15:[1,24],16:[1,25],17:[1,26],18:[1,27],19:[1,28],20:[1,29],21:[1,30]},{5:[2,2],11:[2,2],12:[2,2],14:[2,2],15:[2,2],16:[2,2],17:[2,2],18:[2,2],19:[2,2],20:[2,2],21:[2,2],31:[2,2],32:[2,2],34:[1,31]},{5:[2,3],11:[2,3],12:[2,3],14:[2,3],15:[2,3],16:[2,3],17:[2,3],18:[2,3],19:[2,3],20:[2,3],21:[2,3],31:[2,3],32:[2,3]},{5:[2,4],11:[2,4],12:[2,4],14:[2,4],15:[2,4],16:[2,4],17:[2,4],18:[2,4],19:[2,4],20:[2,4],21:[2,4],31:[2,4],32:[2,4]},{5:[2,5],11:[2,5],12:[2,5],14:[2,5],15:[2,5],16:[2,5],17:[2,5],18:[2,5],19:[2,5],20:[2,5],21:[2,5],31:[2,5],32:[2,5],36:[1,32]},{5:[2,6],11:[2,6],12:[2,6],14:[2,6],15:[2,6],16:[2,6],17:[2,6],18:[2,6],19:[2,6],20:[2,6],21:[2,6],31:[2,6],32:[2,6]},{2:14,4:33,6:3,7:[1,4],8:[1,5],9:6,10:[1,7],12:[1,10],13:[1,8],18:[1,9],22:[1,11],23:[1,12],25:13,26:[1,17],28:[1,18],29:[1,19],33:[1,15],35:[1,16],37:[1,20]},{2:14,4:34,6:3,7:[1,4],8:[1,5],9:6,10:[1,7],12:[1,10],13:[1,8],18:[1,9],22:[1,11],23:[1,12],25:13,26:[1,17],28:[1,18],29:[1,19],33:[1,15],35:[1,16],37:[1,20]},{2:14,4:35,6:3,7:[1,4],8:[1,5],9:6,10:[1,7],12:[1,10],13:[1,8],18:[1,9],22:[1,11],23:[1,12],25:13,26:[1,17],28:[1,18],29:[1,19],33:[1,15],35:[1,16],37:[1,20]},{5:[2,22],11:[2,22],12:[2,22],14:[2,22],15:[2,22],16:[2,22],17:[2,22],18:[2,22],19:[2,22],20:[2,22],21:[2,22],31:[2,22],32:[2,22]},{13:[1,36]},{5:[2,25],11:[2,25],12:[2,25],14:[2,25],15:[2,25],16:[2,25],17:[2,25],18:[2,25],19:[2,25],20:[2,25],21:[2,25],31:[2,25],32:[2,25]},{2:37,5:[2,26],11:[2,26],12:[2,26],14:[2,26],15:[2,26],16:[2,26],17:[2,26],18:[2,26],19:[2,26],20:[2,26],21:[2,26],31:[2,26],32:[2,26],33:[1,38],37:[1,20]},{5:[2,37],11:[2,37],12:[2,37],14:[2,37],15:[2,37],16:[2,37],17:[2,37],18:[2,37],19:[2,37],20:[2,37],21:[2,37],31:[2,37],32:[2,37],34:[2,37],37:[1,39]},{5:[2,39],11:[2,39],12:[2,39],14:[2,39],15:[2,39],16:[2,39],17:[2,39],18:[2,39],19:[2,39],20:[2,39],21:[2,39],31:[2,39],32:[2,39],34:[1,40],36:[2,39]},{5:[2,28],11:[2,28],12:[2,28],14:[2,28],15:[2,28],16:[2,28],17:[2,28],18:[2,28],19:[2,28],20:[2,28],21:[2,28],27:[1,41],31:[2,28],32:[2,28]},{5:[2,30],11:[2,30],12:[2,30],14:[2,30],15:[2,30],16:[2,30],17:[2,30],18:[2,30],19:[2,30],20:[2,30],21:[2,30],27:[1,42],31:[2,30],32:[2,30]},{30:[1,43]},{33:[1,44]},{1:[2,1]},{2:14,4:45,6:3,7:[1,4],8:[1,5],9:6,10:[1,7],12:[1,10],13:[1,8],18:[1,9],22:[1,11],23:[1,12],25:13,26:[1,17],28:[1,18],29:[1,19],33:[1,15],35:[1,16],37:[1,20]},{2:14,4:46,6:3,7:[1,4],8:[1,5],9:6,10:[1,7],12:[1,10],13:[1,8],18:[1,9],22:[1,11],23:[1,12],25:13,26:[1,17],28:[1,18],29:[1,19],33:[1,15],35:[1,16],37:[1,20]},{2:14,4:49,6:3,7:[1,4],8:[1,5],9:6,10:[1,7],11:[1,47],12:[1,10],13:[1,8],16:[1,48],18:[1,9],22:[1,11],23:[1,12],25:13,26:[1,17],28:[1,18],29:[1,19],33:[1,15],35:[1,16],37:[1,20]},{2:14,4:51,6:3,7:[1,4],8:[1,5],9:6,10:[1,7],11:[1,50],12:[1,10],13:[1,8],18:[1,9],22:[1,11],23:[1,12],25:13,26:[1,17],28:[1,18],29:[1,19],33:[1,15],35:[1,16],37:[1,20]},{2:14,4:52,6:3,7:[1,4],8:[1,5],9:6,10:[1,7],12:[1,10],13:[1,8],18:[1,9],22:[1,11],23:[1,12],25:13,26:[1,17],28:[1,18],29:[1,19],33:[1,15],35:[1,16],37:[1,20]},{2:14,4:53,6:3,7:[1,4],8:[1,5],9:6,10:[1,7],12:[1,10],13:[1,8],18:[1,9],22:[1,11],23:[1,12],25:13,26:[1,17],28:[1,18],29:[1,19],33:[1,15],35:[1,16],37:[1,20]},{2:14,4:54,6:3,7:[1,4],8:[1,5],9:6,10:[1,7],12:[1,10],13:[1,8],18:[1,9],22:[1,11],23:[1,12],25:13,26:[1,17],28:[1,18],29:[1,19],33:[1,15],35:[1,16],37:[1,20]},{2:14,4:55,6:3,7:[1,4],8:[1,5],9:6,10:[1,7],12:[1,10],13:[1,8],18:[1,9],22:[1,11],23:[1,12],25:13,26:[1,17],28:[1,18],29:[1,19],33:[1,15],35:[1,16],37:[1,20]},{2:14,4:56,6:3,7:[1,4],8:[1,5],9:6,10:[1,7],12:[1,10],13:[1,8],18:[1,9],22:[1,11],23:[1,12],25:13,26:[1,17],28:[1,18],29:[1,19],33:[1,15],35:[1,16],37:[1,20]},{33:[1,57]},{5:[2,41],11:[2,41],12:[2,41],14:[2,41],15:[2,41],16:[2,41],17:[2,41],18:[2,41],19:[2,41],20:[2,41],21:[2,41],31:[2,41],32:[2,41],36:[2,41]},{11:[1,22],12:[1,23],14:[1,58],15:[1,24],16:[1,25],17:[1,26],18:[1,27],19:[1,28],20:[1,29],21:[1,30]},{5:[2,20],11:[2,20],12:[2,20],14:[2,20],15:[2,20],16:[2,20],17:[2,20],18:[2,20],19:[1,28],20:[1,29],21:[1,30],31:[2,20],32:[2,20]},{5:[2,21],11:[2,21],12:[2,21],14:[2,21],15:[2,21],16:[2,21],17:[2,21],18:[2,21],19:[1,28],20:[1,29],21:[1,30],31:[2,21],32:[2,21]},{2:14,4:61,6:3,7:[1,4],8:[1,5],9:6,10:[1,7],12:[1,10],13:[1,8],14:[1,59],18:[1,9],22:[1,11],23:[1,12],24:60,25:13,26:[1,17],28:[1,18],29:[1,19],33:[1,15],35:[1,16],37:[1,20]},{5:[2,27],11:[2,27],12:[2,27],14:[2,27],15:[2,27],16:[2,27],17:[2,27],18:[2,27],19:[2,27],20:[2,27],21:[2,27],31:[2,27],32:[2,27]},{37:[1,39]},{33:[1,62]},{35:[1,63]},{26:[1,64]},{28:[1,65]},{28:[1,66]},{30:[1,67]},{5:[2,7],11:[2,7],12:[1,23],14:[2,7],15:[1,24],16:[1,25],17:[1,26],18:[1,27],19:[1,28],20:[1,29],21:[1,30],31:[2,7],32:[2,7]},{5:[2,8],11:[2,8],12:[2,8],14:[2,8],15:[2,8],16:[2,8],17:[2,8],18:[2,8],19:[1,28],20:[1,29],21:[1,30],31:[2,8],32:[2,8]},{2:14,4:68,6:3,7:[1,4],8:[1,5],9:6,10:[1,7],12:[1,10],13:[1,8],18:[1,9],22:[1,11],23:[1,12],25:13,26:[1,17],28:[1,18],29:[1,19],33:[1,15],35:[1,16],37:[1,20]},{2:14,4:69,6:3,7:[1,4],8:[1,5],9:6,10:[1,7],12:[1,10],13:[1,8],18:[1,9],22:[1,11],23:[1,12],25:13,26:[1,17],28:[1,18],29:[1,19],33:[1,15],35:[1,16],37:[1,20]},{5:[2,15],11:[2,15],12:[1,23],14:[2,15],15:[2,15],16:[2,15],17:[2,15],18:[1,27],19:[1,28],20:[1,29],21:[1,30],31:[2,15],32:[2,15]},{2:14,4:70,6:3,7:[1,4],8:[1,5],9:6,10:[1,7],12:[1,10],13:[1,8],18:[1,9],22:[1,11],23:[1,12],25:13,26:[1,17],28:[1,18],29:[1,19],33:[1,15],35:[1,16],37:[1,20]},{5:[2,14],11:[2,14],12:[1,23],14:[2,14],15:[2,14],16:[2,14],17:[2,14],18:[1,27],19:[1,28],20:[1,29],21:[1,30],31:[2,14],32:[2,14]},{5:[2,13],11:[2,13],12:[1,23],14:[2,13],15:[1,24],16:[1,25],17:[2,13],18:[1,27],19:[1,28],20:[1,29],21:[1,30],31:[2,13],32:[2,13]},{5:[2,16],11:[2,16],12:[2,16],14:[2,16],15:[2,16],16:[2,16],17:[2,16],18:[2,16],19:[1,28],20:[1,29],21:[1,30],31:[2,16],32:[2,16]},{5:[2,17],11:[2,17],12:[2,17],14:[2,17],15:[2,17],16:[2,17],17:[2,17],18:[2,17],19:[2,17],20:[2,17],21:[1,30],31:[2,17],32:[2,17]},{5:[2,18],11:[2,18],12:[2,18],14:[2,18],15:[2,18],16:[2,18],17:[2,18],18:[2,18],19:[2,18],20:[2,18],21:[1,30],31:[2,18],32:[2,18]},{5:[2,19],11:[2,19],12:[2,19],14:[2,19],15:[2,19],16:[2,19],17:[2,19],18:[2,19],19:[2,19],20:[2,19],21:[2,19],31:[2,19],32:[2,19]},{5:[2,38],11:[2,38],12:[2,38],14:[2,38],15:[2,38],16:[2,38],17:[2,38],18:[2,38],19:[2,38],20:[2,38],21:[2,38],31:[2,38],32:[2,38],34:[2,38]},{5:[2,9],11:[2,9],12:[2,9],14:[2,9],15:[2,9],16:[2,9],17:[2,9],18:[2,9],19:[2,9],20:[2,9],21:[2,9],31:[2,9],32:[2,9]},{5:[2,23],11:[2,23],12:[2,23],14:[2,23],15:[2,23],16:[2,23],17:[2,23],18:[2,23],19:[2,23],20:[2,23],21:[2,23],31:[2,23],32:[2,23]},{14:[1,71],31:[1,72],32:[1,73]},{11:[1,22],12:[1,23],14:[2,34],15:[1,24],16:[1,25],17:[1,26],18:[1,27],19:[1,28],20:[1,29],21:[1,30],31:[2,34],32:[2,34]},{30:[1,74]},{5:[2,40],11:[2,40],12:[2,40],14:[2,40],15:[2,40],16:[2,40],17:[2,40],18:[2,40],19:[2,40],20:[2,40],21:[2,40],31:[2,40],32:[2,40],36:[2,40]},{5:[2,29],11:[2,29],12:[2,29],14:[2,29],15:[2,29],16:[2,29],17:[2,29],18:[2,29],19:[2,29],20:[2,29],21:[2,29],31:[2,29],32:[2,29]},{5:[2,31],11:[2,31],12:[2,31],14:[2,31],15:[2,31],16:[2,31],17:[2,31],18:[2,31],19:[2,31],20:[2,31],21:[2,31],31:[2,31],32:[2,31]},{5:[2,32],11:[2,32],12:[2,32],14:[2,32],15:[2,32],16:[2,32],17:[2,32],18:[2,32],19:[2,32],20:[2,32],21:[2,32],27:[1,75],31:[2,32],32:[2,32]},{5:[2,42],11:[2,42],12:[2,42],14:[2,42],15:[2,42],16:[2,42],17:[2,42],18:[2,42],19:[2,42],20:[2,42],21:[2,42],31:[2,42],32:[2,42],33:[2,42],37:[2,42]},{5:[2,10],11:[2,10],12:[1,23],14:[2,10],15:[2,10],16:[2,10],17:[2,10],18:[1,27],19:[1,28],20:[1,29],21:[1,30],31:[2,10],32:[2,10]},{5:[2,12],11:[2,12],12:[1,23],14:[2,12],15:[2,12],16:[2,12],17:[2,12],18:[1,27],19:[1,28],20:[1,29],21:[1,30],31:[2,12],32:[2,12]},{5:[2,11],11:[2,11],12:[1,23],14:[2,11],15:[2,11],16:[2,11],17:[2,11],18:[1,27],19:[1,28],20:[1,29],21:[1,30],31:[2,11],32:[2,11]},{5:[2,24],11:[2,24],12:[2,24],14:[2,24],15:[2,24],16:[2,24],17:[2,24],18:[2,24],19:[2,24],20:[2,24],21:[2,24],31:[2,24],32:[2,24]},{2:14,4:76,6:3,7:[1,4],8:[1,5],9:6,10:[1,7],12:[1,10],13:[1,8],18:[1,9],22:[1,11],23:[1,12],25:13,26:[1,17],28:[1,18],29:[1,19],33:[1,15],35:[1,16],37:[1,20]},{2:14,4:77,6:3,7:[1,4],8:[1,5],9:6,10:[1,7],12:[1,10],13:[1,8],18:[1,9],22:[1,11],23:[1,12],25:13,26:[1,17],28:[1,18],29:[1,19],33:[1,15],35:[1,16],37:[1,20]},{5:[2,43],11:[2,43],12:[2,43],14:[2,43],15:[2,43],16:[2,43],17:[2,43],18:[2,43],19:[2,43],20:[2,43],21:[2,43],31:[2,43],32:[2,43],33:[2,43],37:[2,43]},{28:[1,78]},{11:[1,22],12:[1,23],14:[2,35],15:[1,24],16:[1,25],17:[1,26],18:[1,27],19:[1,28],20:[1,29],21:[1,30],31:[2,35],32:[2,35]},{11:[1,22],12:[1,23],14:[2,36],15:[1,24],16:[1,25],17:[1,26],18:[1,27],19:[1,28],20:[1,29],21:[1,30],31:[2,36],32:[2,36]},{5:[2,33],11:[2,33],12:[2,33],14:[2,33],15:[2,33],16:[2,33],17:[2,33],18:[2,33],19:[2,33],20:[2,33],21:[2,33],31:[2,33],32:[2,33]}],
+defaultActions: {21:[2,1]},
+parseError: function parseError(str, hash) {
+ if (hash.recoverable) {
+ this.trace(str);
+ } else {
+ throw new Error(str);
+ }
+},
+parse: function parse(input) {
+ var self = this,
+ stack = [0],
+ vstack = [null], // semantic value stack
+ lstack = [], // location stack
+ table = this.table,
+ yytext = '',
+ yylineno = 0,
+ yyleng = 0,
+ recovering = 0,
+ TERROR = 2,
+ EOF = 1;
+
+ var args = lstack.slice.call(arguments, 1);
+
+ //this.reductionCount = this.shiftCount = 0;
+
+ this.lexer.setInput(input);
+ this.lexer.yy = this.yy;
+ this.yy.lexer = this.lexer;
+ this.yy.parser = this;
+ if (typeof this.lexer.yylloc == 'undefined') {
+ this.lexer.yylloc = {};
+ }
+ var yyloc = this.lexer.yylloc;
+ lstack.push(yyloc);
+
+ var ranges = this.lexer.options && this.lexer.options.ranges;
+
+ if (typeof this.yy.parseError === 'function') {
+ this.parseError = this.yy.parseError;
+ } else {
+ this.parseError = Object.getPrototypeOf(this).parseError;
+ }
+
+ function popStack (n) {
+ stack.length = stack.length - 2 * n;
+ vstack.length = vstack.length - n;
+ lstack.length = lstack.length - n;
+ }
+
+ function lex() {
+ var token;
+ token = self.lexer.lex() || EOF; // $end = 1
+ // if token isn't its numeric value, convert
+ if (typeof token !== 'number') {
+ token = self.symbols_[token] || token;
+ }
+ return token;
+ }
+
+ var symbol, preErrorSymbol, state, action, a, r, yyval = {}, p, len, newState, expected;
+ while (true) {
+ // retreive state number from top of stack
+ state = stack[stack.length - 1];
+
+ // use default actions if available
+ if (this.defaultActions[state]) {
+ action = this.defaultActions[state];
+ } else {
+ if (symbol === null || typeof symbol == 'undefined') {
+ symbol = lex();
+ }
+ // read action for current state and first input
+ action = table[state] && table[state][symbol];
+ }
+
+_handle_error:
+ // handle parse error
+ if (typeof action === 'undefined' || !action.length || !action[0]) {
+ var error_rule_depth;
+ var errStr = '';
+
+ // Return the rule stack depth where the nearest error rule can be found.
+ // Return FALSE when no error recovery rule was found.
+ function locateNearestErrorRecoveryRule(state) {
+ var stack_probe = stack.length - 1;
+ var depth = 0;
+
+ // try to recover from error
+ for(;;) {
+ // check for error recovery rule in this state
+ if ((TERROR.toString()) in table[state]) {
+ return depth;
+ }
+ if (state === 0 || stack_probe < 2) {
+ return false; // No suitable error recovery rule available.
+ }
+ stack_probe -= 2; // popStack(1): [symbol, action]
+ state = stack[stack_probe];
+ ++depth;
+ }
+ }
+
+ if (!recovering) {
+ // first see if there's any chance at hitting an error recovery rule:
+ error_rule_depth = locateNearestErrorRecoveryRule(state);
+
+ // Report error
+ expected = [];
+ for (p in table[state]) {
+ if (this.terminals_[p] && p > TERROR) {
+ expected.push("'"+this.terminals_[p]+"'");
+ }
+ }
+ if (this.lexer.showPosition) {
+ errStr = 'Parse error on line '+(yylineno+1)+":\n"+this.lexer.showPosition()+"\nExpecting "+expected.join(', ') + ", got '" + (this.terminals_[symbol] || symbol)+ "'";
+ } else {
+ errStr = 'Parse error on line '+(yylineno+1)+": Unexpected " +
+ (symbol == EOF ? "end of input" :
+ ("'"+(this.terminals_[symbol] || symbol)+"'"));
+ }
+ this.parseError(errStr, {
+ text: this.lexer.match,
+ token: this.terminals_[symbol] || symbol,
+ line: this.lexer.yylineno,
+ loc: yyloc,
+ expected: expected,
+ recoverable: (error_rule_depth !== false)
+ });
+ } else if (preErrorSymbol !== EOF) {
+ error_rule_depth = locateNearestErrorRecoveryRule(state);
+ }
+
+ // just recovered from another error
+ if (recovering == 3) {
+ if (symbol === EOF || preErrorSymbol === EOF) {
+ throw new Error(errStr || 'Parsing halted while starting to recover from another error.');
+ }
+
+ // discard current lookahead and grab another
+ yyleng = this.lexer.yyleng;
+ yytext = this.lexer.yytext;
+ yylineno = this.lexer.yylineno;
+ yyloc = this.lexer.yylloc;
+ symbol = lex();
+ }
+
+ // try to recover from error
+ if (error_rule_depth === false) {
+ throw new Error(errStr || 'Parsing halted. No suitable error recovery rule available.');
+ }
+ popStack(error_rule_depth);
+
+ preErrorSymbol = (symbol == TERROR ? null : symbol); // save the lookahead token
+ symbol = TERROR; // insert generic error symbol as new lookahead
+ state = stack[stack.length-1];
+ action = table[state] && table[state][TERROR];
+ recovering = 3; // allow 3 real symbols to be shifted before reporting a new error
+ }
+
+ // this shouldn't happen, unless resolve defaults are off
+ if (action[0] instanceof Array && action.length > 1) {
+ throw new Error('Parse Error: multiple actions possible at state: '+state+', token: '+symbol);
+ }
+
+ switch (action[0]) {
+ case 1: // shift
+ //this.shiftCount++;
+
+ stack.push(symbol);
+ vstack.push(this.lexer.yytext);
+ lstack.push(this.lexer.yylloc);
+ stack.push(action[1]); // push state
+ symbol = null;
+ if (!preErrorSymbol) { // normal execution/no error
+ yyleng = this.lexer.yyleng;
+ yytext = this.lexer.yytext;
+ yylineno = this.lexer.yylineno;
+ yyloc = this.lexer.yylloc;
+ if (recovering > 0) {
+ recovering--;
+ }
+ } else {
+ // error just occurred, resume old lookahead f/ before error
+ symbol = preErrorSymbol;
+ preErrorSymbol = null;
+ }
+ break;
+
+ case 2:
+ // reduce
+ //this.reductionCount++;
+
+ len = this.productions_[action[1]][1];
+
+ // perform semantic action
+ yyval.$ = vstack[vstack.length-len]; // default to $$ = $1
+ // default location, uses first token for firsts, last for lasts
+ yyval._$ = {
+ first_line: lstack[lstack.length-(len||1)].first_line,
+ last_line: lstack[lstack.length-1].last_line,
+ first_column: lstack[lstack.length-(len||1)].first_column,
+ last_column: lstack[lstack.length-1].last_column
+ };
+ if (ranges) {
+ yyval._$.range = [lstack[lstack.length-(len||1)].range[0], lstack[lstack.length-1].range[1]];
+ }
+ r = this.performAction.apply(yyval, [yytext, yyleng, yylineno, this.yy, action[1], vstack, lstack].concat(args));
+
+ if (typeof r !== 'undefined') {
+ return r;
+ }
+
+ // pop off stack
+ if (len) {
+ stack = stack.slice(0,-1*len*2);
+ vstack = vstack.slice(0, -1*len);
+ lstack = lstack.slice(0, -1*len);
+ }
+
+ stack.push(this.productions_[action[1]][0]); // push nonterminal (reduce)
+ vstack.push(yyval.$);
+ lstack.push(yyval._$);
+ // goto new state = table[STATE][NONTERMINAL]
+ newState = table[stack[stack.length-2]][stack[stack.length-1]];
+ stack.push(newState);
+ break;
+
+ case 3:
+ // accept
+ return true;
+ }
+
+ }
+
+ return true;
+}};
+
+if (typeof(window) !== 'undefined') {
+ window.Formula = function(handler) {
+ var formulaLexer = function () {};
+ formulaLexer.prototype = formula.lexer;
+
+ var formulaParser = function () {
+ this.lexer = new formulaLexer();
+ this.yy = {};
+ };
+
+ formulaParser.prototype = formula;
+ var newParser = new formulaParser;
+ newParser.setObj = function(obj) {
+ newParser.yy.obj = obj;
+ };
+ newParser.yy.handler = handler;
+ return newParser;
+ };
+}/* generated by jison-lex 0.2.1 */
+var lexer = (function(){
+var lexer = {
+
+EOF:1,
+
+parseError:function parseError(str, hash) {
+ if (this.yy.parser) {
+ this.yy.parser.parseError(str, hash);
+ } else {
+ throw new Error(str);
+ }
+ },
+
+// resets the lexer, sets new input
+setInput:function (input) {
+ this._input = input;
+ this._more = this._backtrack = this.done = false;
+ this.yylineno = this.yyleng = 0;
+ this.yytext = this.matched = this.match = '';
+ this.conditionStack = ['INITIAL'];
+ this.yylloc = {
+ first_line: 1,
+ first_column: 0,
+ last_line: 1,
+ last_column: 0
+ };
+ if (this.options.ranges) {
+ this.yylloc.range = [0,0];
+ }
+ this.offset = 0;
+ return this;
+ },
+
+// consumes and returns one char from the input
+input:function () {
+ var ch = this._input[0];
+ this.yytext += ch;
+ this.yyleng++;
+ this.offset++;
+ this.match += ch;
+ this.matched += ch;
+ var lines = ch.match(/(?:\r\n?|\n).*/g);
+ if (lines) {
+ this.yylineno++;
+ this.yylloc.last_line++;
+ } else {
+ this.yylloc.last_column++;
+ }
+ if (this.options.ranges) {
+ this.yylloc.range[1]++;
+ }
+
+ this._input = this._input.slice(1);
+ return ch;
+ },
+
+// unshifts one char (or a string) into the input
+unput:function (ch) {
+ var len = ch.length;
+ var lines = ch.split(/(?:\r\n?|\n)/g);
+
+ this._input = ch + this._input;
+ this.yytext = this.yytext.substr(0, this.yytext.length - len - 1);
+ //this.yyleng -= len;
+ this.offset -= len;
+ var oldLines = this.match.split(/(?:\r\n?|\n)/g);
+ this.match = this.match.substr(0, this.match.length - 1);
+ this.matched = this.matched.substr(0, this.matched.length - 1);
+
+ if (lines.length - 1) {
+ this.yylineno -= lines.length - 1;
+ }
+ var r = this.yylloc.range;
+
+ this.yylloc = {
+ first_line: this.yylloc.first_line,
+ last_line: this.yylineno + 1,
+ first_column: this.yylloc.first_column,
+ last_column: lines ?
+ (lines.length === oldLines.length ? this.yylloc.first_column : 0)
+ + oldLines[oldLines.length - lines.length].length - lines[0].length :
+ this.yylloc.first_column - len
+ };
+
+ if (this.options.ranges) {
+ this.yylloc.range = [r[0], r[0] + this.yyleng - len];
+ }
+ this.yyleng = this.yytext.length;
+ return this;
+ },
+
+// When called from action, caches matched text and appends it on next action
+more:function () {
+ this._more = true;
+ return this;
+ },
+
+// When called from action, signals the lexer that this rule fails to match the input, so the next matching rule (regex) should be tested instead.
+reject:function () {
+ if (this.options.backtrack_lexer) {
+ this._backtrack = true;
+ } else {
+ return this.parseError('Lexical error on line ' + (this.yylineno + 1) + '. You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n' + this.showPosition(), {
+ text: "",
+ token: null,
+ line: this.yylineno
+ });
+
+ }
+ return this;
+ },
+
+// retain first n characters of the match
+less:function (n) {
+ this.unput(this.match.slice(n));
+ },
+
+// displays already matched input, i.e. for error messages
+pastInput:function () {
+ var past = this.matched.substr(0, this.matched.length - this.match.length);
+ return (past.length > 20 ? '...':'') + past.substr(-20).replace(/\n/g, "");
+ },
+
+// displays upcoming input, i.e. for error messages
+upcomingInput:function () {
+ var next = this.match;
+ if (next.length < 20) {
+ next += this._input.substr(0, 20-next.length);
+ }
+ return (next.substr(0,20) + (next.length > 20 ? '...' : '')).replace(/\n/g, "");
+ },
+
+// displays the character position where the lexing error occurred, i.e. for error messages
+showPosition:function () {
+ var pre = this.pastInput();
+ var c = new Array(pre.length + 1).join("-");
+ return pre + this.upcomingInput() + "\n" + c + "^";
+ },
+
+// test the lexed token: return FALSE when not a match, otherwise return token
+test_match:function (match, indexed_rule) {
+ var token,
+ lines,
+ backup;
+
+ if (this.options.backtrack_lexer) {
+ // save context
+ backup = {
+ yylineno: this.yylineno,
+ yylloc: {
+ first_line: this.yylloc.first_line,
+ last_line: this.last_line,
+ first_column: this.yylloc.first_column,
+ last_column: this.yylloc.last_column
+ },
+ yytext: this.yytext,
+ match: this.match,
+ matches: this.matches,
+ matched: this.matched,
+ yyleng: this.yyleng,
+ offset: this.offset,
+ _more: this._more,
+ _input: this._input,
+ yy: this.yy,
+ conditionStack: this.conditionStack.slice(0),
+ done: this.done
+ };
+ if (this.options.ranges) {
+ backup.yylloc.range = this.yylloc.range.slice(0);
+ }
+ }
+
+ lines = match[0].match(/(?:\r\n?|\n).*/g);
+ if (lines) {
+ this.yylineno += lines.length;
+ }
+ this.yylloc = {
+ first_line: this.yylloc.last_line,
+ last_line: this.yylineno + 1,
+ first_column: this.yylloc.last_column,
+ last_column: lines ?
+ lines[lines.length - 1].length - lines[lines.length - 1].match(/\r?\n?/)[0].length :
+ this.yylloc.last_column + match[0].length
+ };
+ this.yytext += match[0];
+ this.match += match[0];
+ this.matches = match;
+ this.yyleng = this.yytext.length;
+ if (this.options.ranges) {
+ this.yylloc.range = [this.offset, this.offset += this.yyleng];
+ }
+ this._more = false;
+ this._backtrack = false;
+ this._input = this._input.slice(match[0].length);
+ this.matched += match[0];
+ token = this.performAction.call(this, this.yy, this, indexed_rule, this.conditionStack[this.conditionStack.length - 1]);
+ if (this.done && this._input) {
+ this.done = false;
+ }
+ if (token) {
+ return token;
+ } else if (this._backtrack) {
+ // recover context
+ for (var k in backup) {
+ this[k] = backup[k];
+ }
+ return false; // rule action called reject() implying the next rule should be tested instead.
+ }
+ return false;
+ },
+
+// return next match in input
+next:function () {
+ if (this.done) {
+ return this.EOF;
+ }
+ if (!this._input) {
+ this.done = true;
+ }
+
+ var token,
+ match,
+ tempMatch,
+ index;
+ if (!this._more) {
+ this.yytext = '';
+ this.match = '';
+ }
+ var rules = this._currentRules();
+ for (var i = 0; i < rules.length; i++) {
+ tempMatch = this._input.match(this.rules[rules[i]]);
+ if (tempMatch && (!match || tempMatch[0].length > match[0].length)) {
+ match = tempMatch;
+ index = i;
+ if (this.options.backtrack_lexer) {
+ token = this.test_match(tempMatch, rules[i]);
+ if (token !== false) {
+ return token;
+ } else if (this._backtrack) {
+ match = false;
+ continue; // rule action called reject() implying a rule MISmatch.
+ } else {
+ // else: this is a lexer rule which consumes input without producing a token (e.g. whitespace)
+ return false;
+ }
+ } else if (!this.options.flex) {
+ break;
+ }
+ }
+ }
+ if (match) {
+ token = this.test_match(match, rules[index]);
+ if (token !== false) {
+ return token;
+ }
+ // else: this is a lexer rule which consumes input without producing a token (e.g. whitespace)
+ return false;
+ }
+ if (this._input === "") {
+ return this.EOF;
+ } else {
+ return this.parseError('Lexical error on line ' + (this.yylineno + 1) + '. Unrecognized text.\n' + this.showPosition(), {
+ text: "",
+ token: null,
+ line: this.yylineno
+ });
+ }
+ },
+
+// return next match that has a token
+lex:function lex() {
+ var r = this.next();
+ if (r) {
+ return r;
+ } else {
+ return this.lex();
+ }
+ },
+
+// activates a new lexer condition state (pushes the new lexer condition state onto the condition stack)
+begin:function begin(condition) {
+ this.conditionStack.push(condition);
+ },
+
+// pop the previously active lexer condition state off the condition stack
+popState:function popState() {
+ var n = this.conditionStack.length - 1;
+ if (n > 0) {
+ return this.conditionStack.pop();
+ } else {
+ return this.conditionStack[0];
+ }
+ },
+
+// produce the lexer rule set which is active for the currently active lexer condition state
+_currentRules:function _currentRules() {
+ if (this.conditionStack.length && this.conditionStack[this.conditionStack.length - 1]) {
+ return this.conditions[this.conditionStack[this.conditionStack.length - 1]].rules;
+ } else {
+ return this.conditions["INITIAL"].rules;
+ }
+ },
+
+// return the currently active lexer condition state; when an index argument is provided it produces the N-th previous condition state, if available
+topState:function topState(n) {
+ n = this.conditionStack.length - 1 - Math.abs(n || 0);
+ if (n >= 0) {
+ return this.conditionStack[n];
+ } else {
+ return "INITIAL";
+ }
+ },
+
+// alias for begin(condition)
+pushState:function pushState(condition) {
+ this.begin(condition);
+ },
+
+// return the number of states currently on the stack
+stateStackSize:function stateStackSize() {
+ return this.conditionStack.length;
+ },
+options: {},
+performAction: function anonymous(yy,yy_,$avoiding_name_collisions,YY_START) {
+
+var YYSTATE=YY_START;
+switch($avoiding_name_collisions) {
+case 0:/* skip whitespace */
+break;
+case 1:return 10;
+break;
+case 2:return 10;
+break;
+case 3:return 23;
+break;
+case 4:return 7;
+break;
+case 5:return 8;
+break;
+case 6:
+ //js
+ if (yy.obj.type == 'cell') return 29;
+ return 33;
+
+ /*php
+ if ($this->type == 'cell') return 29;
+ return 33;
+ */
+
+ /*cs
+ return 29;
+ //return 33;
+ */
+
+break;
+case 7:
+ //js
+ if (yy.obj.type == 'cell') return 26;
+ return 33;
+
+ /*php
+ if ($this->type == 'cell') return 26;
+ return 33;
+ */
+
+ /*cs
+ return 26;
+ //return 33;
+ */
+
+break;
+case 8:
+ //js
+ if (yy.obj.type == 'cell') return 28;
+ return 33;
+
+ /*php
+ if ($this->type == 'cell') return 28;
+ return 33;
+ */
+
+ /*cs
+ return 28;
+ //return 33;
+ */
+
+break;
+case 9:return 23;
+break;
+case 10:return 33;
+break;
+case 11:return 33;
+break;
+case 12:return 35;
+break;
+case 13:/* skip whitespace */
+break;
+case 14:return 34;
+break;
+case 15:return 27;
+break;
+case 16:return 31;
+break;
+case 17:return 32;
+break;
+case 18:return 19;
+break;
+case 19:return 20;
+break;
+case 20:return 18;
+break;
+case 21:return 12;
+break;
+case 22:return 21;
+break;
+case 23:return 13;
+break;
+case 24:return 14;
+break;
+case 25:return 16;
+break;
+case 26:return 15;
+break;
+case 27:return 17;
+break;
+case 28:return 22;
+break;
+case 29:return '"';
+break;
+case 30:return "'";
+break;
+case 31:return "!";
+break;
+case 32:return 11;
+break;
+case 33:return 36;
+break;
+case 34:return 37;
+break;
+case 35:return 5;
+break;
+}
+},
+rules: [/^(?:\s+)/,/^(?:"(\\["]|[^"])*")/,/^(?:'(\\[']|[^'])*')/,/^(?:[A-Za-z]{1,}[A-Za-z_0-9]+(?=[(]))/,/^(?:([0]?[1-9]|1[0-2])[:][0-5][0-9]([:][0-5][0-9])?[ ]?(AM|am|aM|Am|PM|pm|pM|Pm))/,/^(?:([0]?[0-9]|1[0-9]|2[0-3])[:][0-5][0-9]([:][0-5][0-9])?)/,/^(?:SHEET[0-9]+)/,/^(?:\$[A-Za-z]+\$[0-9]+)/,/^(?:[A-Za-z]+[0-9]+)/,/^(?:[A-Za-z]+(?=[(]))/,/^(?:[A-Za-z]{1,}[A-Za-z_0-9]+)/,/^(?:[A-Za-z_]+)/,/^(?:[0-9]+)/,/^(?:\\s)/,/^(?:[.])/,/^(?::)/,/^(?:;)/,/^(?:,)/,/^(?:\*)/,/^(?:\/)/,/^(?:-)/,/^(?:\+)/,/^(?:\^)/,/^(?:\()/,/^(?:\))/,/^(?:>)/,/^(?:<)/,/^(?:NOT\b)/,/^(?:E\b)/,/^(?:")/,/^(?:')/,/^(?:!)/,/^(?:=)/,/^(?:%)/,/^(?:[#])/,/^(?:$)/],
+conditions: {"INITIAL":{"rules":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35],"inclusive":true}}
+};
+return lexer;
+})();
+parser.lexer = lexer;
+function Parser () {
+ this.yy = {};
+}
+Parser.prototype = parser;parser.Parser = Parser;
+return new Parser;
+})();
+
+
+if (typeof require !== 'undefined' && typeof exports !== 'undefined') {
+exports.parser = formula;
+exports.Parser = formula.Parser;
+exports.parse = function () { return formula.parse.apply(formula, arguments); };
+exports.main = function commonjsMain(args) {
+ if (!args[1]) {
+ console.log('Usage: '+args[0]+' FILE');
+ process.exit(1);
+ }
+ var source = require('fs').readFileSync(require('path').normalize(args[1]), "utf8");
+ return exports.parser.parse(source);
+};
+if (typeof module !== 'undefined' && require.main === module) {
+ exports.main(process.argv.slice(1));
+}
+}
\ No newline at end of file
diff --git a/ports/php/php.js b/ports/php/php.js
index 5e9f84254..d44ca6ebd 100644
--- a/ports/php/php.js
+++ b/ports/php/php.js
@@ -1,268 +1,267 @@
-var fs = require('fs'),
- util = require('util'),
- exec = require('child_process').exec,
- path = require('path');
-
-GLOBAL.convertToSyntax = function (types, body) {
- if (types['php'] || types['PHP']) {
- return body;
- }
- return '';
+GLOBAL.convertToSyntax = function (types, body) {
+ if (types['php'] || types['PHP']) {
+ return body;
+ }
+ return '';
};
-function puts(error, stdout, stderr) {
- util.puts(stdout);
-}
-
-console.log("Executing: " + "jison " + process.argv[2]);
-
-exec("jison " + process.argv[2], function (error) {
- if (error) {
- console.log(error);
- return;
- }
-
- String.prototype.trim=function(){return this.replace(/^\s+|\s+$/g, '');};
-
- var fileName = process.argv[2].replace('.jison', ''),
- comments = require(path.resolve(__dirname, '../comments.js')),
- requirePath = path.resolve(process.argv[2]).replace('.jison', '') + '.js';
-
- console.log("Opening newly created jison js file: " + fileName + '.js');
-
- var Parser = require(requirePath),
- symbols = Parser.parser.symbols_,
- terminals = Parser.parser.terminals_,
- productions = Parser.parser.productions_,
- table = Parser.parser.table,
- defaultActions = Parser.parser.defaultActions,
- //turn regex into string
- rules = [];
-
- for (var i = 0; i < Parser.parser.lexer.rules.length; i++) {
- rules.push(Parser.parser.lexer.rules[i].toString());
- }
-
- var conditions = Parser.parser.lexer.conditions,
- options = Parser.parser.lexer.options,
- parserPerformAction = Parser.parser.performAction.toString(),
- lexerPerformAction = Parser.parser.lexer.performAction.toString();
-
- function jsFnBody(str) {
- str = str.split('{');
- str.shift();
- str = str.join('{');
-
- str = str.split('}');
- str.pop();
- str = str.join('}');
-
- return str;
- }
-
- function jsPerformActionToPhp(str) {
- str = jsFnBody(str);
- str = str.replace("var $0 = $$.length - 1;", '');
- str = str.replace("var YYSTATE=YY_START", '');
- str = str.replace(new RegExp('[$]0', 'g'), '$o');
- str = str.replace(new RegExp('[$][$]', 'g'), '$s');
- str = str.replace(new RegExp('default[:][;]', 'g'), '');
- str = str.replace(new RegExp('this[.][$]', 'g'), '$thisS');
- str = str.replace(new RegExp('this[-][>]', 'g'), '$this->');
- str = str.replace(new RegExp('yystate', 'g'), '$yystate');
- //str = str.replace(new RegExp('yytext', 'g'), 'yy->text');
- str = str.replace(new RegExp('[$]yy[_][.]', 'g'), '$this->yy->');
- str = str.replace(new RegExp('[$]this[-][>]yy[-][>]yy', 'g'), '$this->yy->');
- str = str.replace(new RegExp('[.]yytext', 'g'), '->text');
- str = str.replace(new RegExp('yy[.]', 'g'), 'yy->');
- str = str.replace(new RegExp('yy_[.][$]', 'g'), '$this->yy->');
- str = str.replace(new RegExp('[$]accept', 'g'), 'accept');
- str = str.replace(new RegExp('[$]end', 'g'), 'end');
- str = str.replace(new RegExp('console[.]log'), '');
- str = str.replace(new RegExp('[$]avoiding_name_collisions'), '$avoidingNameCollisions');
-
- str = comments.parse(str);
-
- str = str.replace(/(\d)\n/g, function () {
- return arguments[1] + ';\n';
- });
-
- return str;
- }
-
-
- var option = {
- 'namespace': 'Jison',
- 'class': fileName,
- 'fileName': fileName + '.php',
- 'extends': '',
- 'use': '',
- 'parserValue': ''
- };
-
- var parserDefinition = fs.readFileSync(fileName + '.jison', "utf8");
- parserDefinition = parserDefinition.split(/\n/g);
- for(var i = 0; i < parserDefinition.length; i++) {
- if (parserDefinition[i].match('//option')) {
- parserDefinition[i] = parserDefinition[i].replace('//option ', '');
- parserDefinition[i] = parserDefinition[i].split(':');
- option[parserDefinition[i][0]] = parserDefinition[i][1];
- }
- }
-
- console.log(option);
-
- var parserRaw = fs.readFileSync(__dirname + "/template.php", "utf8");
-
- function parserInject() {
- var result = '\n';
- this.symbols = [];
- this.symbolsByIndex = [];
- this.tableInstantiation = [];
- this.tableDefinition = [];
- this.tableSetActions = [];
- this.table = [];
- this.terminals = [];
- this.defaultActions = [];
- this.productions = [];
-
- var actions = [
- 'none',
- 'shift',
- 'reduce',
- 'accept'
- ];
-
- for (var i in symbols) {
- this.symbolsByIndex[symbols[i] * 1] = {
- name: i.replace('$', ''),
- index: symbols[i]
- };
+var fs = require('fs'),
+ spawn = require('child_process').spawn,
+ path = require('path'),
+ createPHPFile = function (jisonFileName) {
+ String.prototype.trim=function(){return this.replace(/^\s+|\s+$/g, '');};
+
+ var fileName = jisonFileName.replace('.jison', ''),
+ comments = require(path.resolve(__dirname, '../comments.js')),
+ requirePath = path.resolve(jisonFileName).replace('.jison', '') + '.js';
+
+ console.log("\n\n\nOpening newly created jison js file: " + fileName + '.js');
+
+ var Parser = require(requirePath),
+ symbols = Parser.parser.symbols_,
+ terminals = Parser.parser.terminals_,
+ productions = Parser.parser.productions_,
+ table = Parser.parser.table,
+ defaultActions = Parser.parser.defaultActions,
+ //turn regex into string
+ rules = [];
+
+ for (var i = 0; i < Parser.parser.lexer.rules.length; i++) {
+ rules.push(Parser.parser.lexer.rules[i].toString());
}
- console.log(this.symbolsByIndex);
+ var conditions = Parser.parser.lexer.conditions,
+ options = Parser.parser.lexer.options,
+ parserPerformAction = Parser.parser.performAction.toString(),
+ lexerPerformAction = Parser.parser.lexer.performAction.toString();
+
+ function jsFnBody(str) {
+ str = str.split('{');
+ str.shift();
+ str = str.join('{');
- for (var i in this.symbolsByIndex) {
- var symbol = this.symbolsByIndex[i];
- result += '\t\t\t$symbol' + symbol.index + ' = new ParserSymbol("' + symbol.name + '", ' + symbol.index + ');\n';
- this.symbols.push('\t\t\t$this->symbols[' + symbol.index + '] = $symbol' + symbol.index + '');
- this.symbols.push('\t\t\t$this->symbols["' + symbol.name + '"] = $symbol' + symbol.index + '');
+ str = str.split('}');
+ str.pop();
+ str = str.join('}');
+ return str;
+ }
+
+ function jsPerformActionToPhp(str) {
+ str = jsFnBody(str);
+ str = str.replace("var $0 = $$.length - 1;", '');
+ str = str.replace("var YYSTATE=YY_START", '');
+ str = str.replace(new RegExp('[$]0', 'g'), '$o');
+ str = str.replace(new RegExp('[$][$]', 'g'), '$s');
+ str = str.replace(new RegExp('default[:][;]', 'g'), '');
+ str = str.replace(new RegExp('this[.][$]', 'g'), '$thisS');
+ str = str.replace(new RegExp('this[-][>]', 'g'), '$this->');
+ str = str.replace(new RegExp('yystate', 'g'), '$yystate');
+ //str = str.replace(new RegExp('yytext', 'g'), 'yy->text');
+ str = str.replace(new RegExp('[$]yy[_][.]', 'g'), '$this->yy->');
+ str = str.replace(new RegExp('[$]this[-][>]yy[-][>]yy', 'g'), '$this->yy->');
+ str = str.replace(new RegExp('[.]yytext', 'g'), '->text');
+ str = str.replace(new RegExp('yy[.]', 'g'), 'yy->');
+ str = str.replace(new RegExp('yy_[.][$]', 'g'), '$this->yy->');
+ str = str.replace(new RegExp('[$]accept', 'g'), 'accept');
+ str = str.replace(new RegExp('[$]end', 'g'), 'end');
+ str = str.replace(new RegExp('console[.]log'), '');
+ str = str.replace(new RegExp('[$]avoiding_name_collisions'), '$avoidingNameCollisions');
+
+ str = comments.parse(str);
+
+ str = str.replace(/(\d)\n/g, function () {
+ return arguments[1] + ';\n';
+ });
+
+ return str;
}
- result += this.symbols.join(';\n') + ';\n\n';
- for (var i in terminals) {
- this.terminals.push('\t\t\t\t\t' + i + '=>&$symbol' + i + '');
+ var option = {
+ 'namespace': 'Jison',
+ 'class': fileName,
+ 'fileName': fileName + '.php',
+ 'extends': '',
+ 'use': '',
+ 'parserValue': ''
+ };
+
+ var parserDefinition = fs.readFileSync(fileName + '.jison', "utf8");
+ parserDefinition = parserDefinition.split(/\n/g);
+ for(var i = 0; i < parserDefinition.length; i++) {
+ if (parserDefinition[i].match('//option')) {
+ parserDefinition[i] = parserDefinition[i].replace('//option ', '');
+ parserDefinition[i] = parserDefinition[i].split(':');
+ option[parserDefinition[i][0]] = parserDefinition[i][1];
+ }
}
- result += '\t\t\t$this->terminals = array(\n' + this.terminals.join(',\n') + '\n\t\t\t\t);\n\n';
-
- for (var i in table) {
- var items = [];
- for (var j in table[i]) {
- var item = table[i][j],
- action = 0,
- state = 0;
- if (item.join) { //is array
- if (item.length == 1) {
- action = item[0];
- items.push('\t\t\t\t\t' + j + '=>new ParserAction($this->' + actions[action] + ')');
+ var parserRaw = fs.readFileSync(__dirname + "/template.php", "utf8");
+
+ function parserInject() {
+ var result = '\n';
+ this.symbols = [];
+ this.symbolsByIndex = [];
+ this.tableInstantiation = [];
+ this.tableDefinition = [];
+ this.tableSetActions = [];
+ this.table = [];
+ this.terminals = [];
+ this.defaultActions = [];
+ this.productions = [];
+
+ var actions = [
+ 'none',
+ 'shift',
+ 'reduce',
+ 'accept'
+ ];
+
+ for (var i in symbols) {
+ this.symbolsByIndex[symbols[i] * 1] = {
+ name: i.replace('$', ''),
+ index: symbols[i]
+ };
+ }
+
+ for (var i in this.symbolsByIndex) {
+ var symbol = this.symbolsByIndex[i];
+ result += '\t\t\t$symbol' + symbol.index + ' = new ParserSymbol("' + symbol.name + '", ' + symbol.index + ');\n';
+ this.symbols.push('\t\t\t$this->symbols[' + symbol.index + '] = $symbol' + symbol.index + '');
+ this.symbols.push('\t\t\t$this->symbols["' + symbol.name + '"] = $symbol' + symbol.index + '');
+
+ }
+
+ result += this.symbols.join(';\n') + ';\n\n';
+
+ for (var i in terminals) {
+ this.terminals.push('\t\t\t\t\t' + i + '=>&$symbol' + i + '');
+ }
+
+ result += '\t\t\t$this->terminals = array(\n' + this.terminals.join(',\n') + '\n\t\t\t\t);\n\n';
+
+ for (var i in table) {
+ var items = [];
+ for (var j in table[i]) {
+ var item = table[i][j],
+ action = 0,
+ state = 0;
+ if (item.join) { //is array
+ if (item.length == 1) {
+ action = item[0];
+ items.push('\t\t\t\t\t' + j + '=>new ParserAction($this->' + actions[action] + ')');
+ } else {
+ action = item[0];
+ state = item[1];
+ items.push('\t\t\t\t\t' + j + '=>new ParserAction($this->' + actions[action] + ', $table' + state + ')');
+ }
} else {
- action = item[0];
- state = item[1];
+ state = item;
items.push('\t\t\t\t\t' + j + '=>new ParserAction($this->' + actions[action] + ', $table' + state + ')');
}
- } else {
- state = item;
- items.push('\t\t\t\t\t' + j + '=>new ParserAction($this->' + actions[action] + ', $table' + state + ')');
}
+
+ this.tableInstantiation.push('\t\t\t$table' + i + ' = new ParserState(' + i + ')');
+ this.tableDefinition.push('\t\t\t$tableDefinition' + i + ' = array(\n\t\t\t\t\n' + items.join(',\n') + '\n\t\t\t\t)');
+ this.tableSetActions.push('\t\t\t$table' + i + '->setActions($tableDefinition' + i + ')');
+ this.table.push('\t\t\t\t\t' + i + '=>$table' + i + '');
}
- this.tableInstantiation.push('\t\t\t$table' + i + ' = new ParserState(' + i + ')');
- this.tableDefinition.push('\t\t\t$tableDefinition' + i + ' = array(\n\t\t\t\t\n' + items.join(',\n') + '\n\t\t\t\t)');
- this.tableSetActions.push('\t\t\t$table' + i + '->setActions($tableDefinition' + i + ')');
- this.table.push('\t\t\t\t\t' + i + '=>$table' + i + '');
- }
+ result += this.tableInstantiation.join(';\n') + ';\n\n';
+ result += this.tableDefinition.join(';\n\n') + ';\n\n';
+ result += this.tableSetActions.join(';\n') + ';\n\n';
+ result += '\t\t\t$this->table = array(\n\t\t\t\t\n' + this.table.join(',\n') + '\n\t\t\t\t);\n\n';
- result += this.tableInstantiation.join(';\n') + ';\n\n';
- result += this.tableDefinition.join(';\n\n') + ';\n\n';
- result += this.tableSetActions.join(';\n') + ';\n\n';
- result += '\t\t\t$this->table = array(\n\t\t\t\t\n' + this.table.join(',\n') + '\n\t\t\t\t);\n\n';
+ for (var i in defaultActions) {
+ var action = defaultActions[i][0];
+ var state = defaultActions[i][1];
+ this.defaultActions.push('\t\t\t\t\t' + i + '=>new ParserAction($this->' + actions[action] +', $table' + state + ')');
+ }
+
+ result += '\t\t\t$this->defaultActions = array(\n\t\t\t\t\n' + this.defaultActions.join(',\n') + '\n\t\t\t\t);\n\n';
- for (var i in defaultActions) {
- var action = defaultActions[i][0];
- var state = defaultActions[i][1];
- this.defaultActions.push('\t\t\t\t\t' + i + '=>new ParserAction($this->' + actions[action] +', $table' + state + ')');
+ for (var i in productions) {
+ var production = productions[i];
+ if (production.join) {
+ var symbol = production[0],
+ len = production[1];
+ this.productions.push('\t\t\t\t\t' + i + '=>new ParserProduction($symbol' + this.symbolsByIndex[symbol].index + ',' + len + ')');
+ } else {
+ var symbol = production;
+ this.productions.push('\t\t\t\t\t' + i + '=>new ParserProduction($symbol' + this.symbolsByIndex[symbol].index + ')');
+ }
+ }
+
+ result += '\t\t\t$this->productions = array(\n\t\t\t\t\n' + this.productions.join(',\n') + '\n\t\t\t\t);\n\n\n';
+
+ return result;
}
- result += '\t\t\t$this->defaultActions = array(\n\t\t\t\t\n' + this.defaultActions.join(',\n') + '\n\t\t\t\t);\n\n';
+ function lexerInject() {
+ var result = '\n';
+ this.rules = [],
+ this.conditions = [];
- for (var i in productions) {
- var production = productions[i];
- if (production.join) {
- var symbol = production[0],
- len = production[1];
- this.productions.push('\t\t\t\t\t' + i + '=>new ParserProduction($symbol' + this.symbolsByIndex[symbol].index + ',' + len + ')');
- } else {
- var symbol = production;
- this.productions.push('\t\t\t\t\t' + i + '=>new ParserProduction($symbol' + this.symbolsByIndex[symbol].index + ')');
+ for (var i in rules) {
+ this.rules.push('\t\t\t\t\t' + i + '=>"/\\G' + rules[i].substring(2, rules[i].length - 1).replace(/"/g, '\\"') + '/"');
}
- }
- result += '\t\t\t$this->productions = array(\n\t\t\t\t\n' + this.productions.join(',\n') + '\n\t\t\t\t);\n\n\n';
+ result += '\t\t\t$this->rules = array(\n\t\t\t\t\n' + this.rules.join(',\n') + '\n\t\t\t\t);\n\n';
- return result;
- }
+ for (var i in conditions) {
+ this.conditions.push('\t\t\t\t\t"' + i + '"=>new LexerConditions(array( ' + conditions[i].rules.join(',') + '), ' + conditions[i].inclusive + ')');
+ }
- function lexerInject() {
- var result = '\n';
- this.rules = [],
- this.conditions = [];
+ result += '\t\t\t$this->conditions = array(\n\t\t\t\t\n' + this.conditions.join(',\n') + '\n\t\t\t\t);\n\n';
- for (var i in rules) {
- this.rules.push('\t\t\t\t\t' + i + '=>"/' + rules[i].substring(1, rules[i].length - 1).replace(/"/g, '\\"') + '/"');
+ return result;
}
- result += '\t\t\t$this->rules = array(\n\t\t\t\t\n' + this.rules.join(',\n') + '\n\t\t\t\t);\n\n';
+ parserRaw = parserRaw
+ .replace('/**/namespace Jison;/**/', (option.namespace ? 'namespace ' + option.namespace + ';\nuse Exception;\n' : ''))
+ .replace('/**/class Parser/**/', 'class ' + option.class + (option.extends ? ' extends ' + option.extends : ''))
+ .replace('/**use**/', (option.use ? 'use ' + option.use : ''))
+ .replace(/[/][*][*][/]ParserValue[/][*][*][/]/g, (option.parserValue ? option.parserValue : 'ParserValue'))
- for (var i in conditions) {
- this.conditions.push('\t\t\t\t\t"' + i + '"=>new LexerConditions(array( ' + conditions[i].rules.join(',') + '), ' + conditions[i].inclusive + ')');
- }
+ .replace('//@@PARSER_INJECT@@',
+ parserInject()
+ )
- result += '\t\t\t$this->conditions = array(\n\t\t\t\t\n' + this.conditions.join(',\n') + '\n\t\t\t\t);\n\n';
+ .replace('//@@LEXER_INJECT@@',
+ lexerInject()
+ )
- return result;
- }
+ .replace('//@@ParserPerformActionInjection@@',
+ jsPerformActionToPhp(parserPerformAction)
+ )
- parserRaw = parserRaw
- .replace('/**/namespace Jison;/**/', (option.namespace ? 'namespace ' + option.namespace + ';\nuse Exception;\n' : ''))
- .replace('/**/class Parser/**/', 'class ' + option.class + (option.extends ? ' extends ' + option.extends : ''))
- .replace('/**use**/', (option.use ? 'use ' + option.use : ''))
- .replace(/[/][*][*][/]ParserValue[/][*][*][/]/g, (option.parserValue ? option.parserValue : 'ParserValue'))
-
- .replace('//@@PARSER_INJECT@@',
- parserInject()
- )
-
- .replace('//@@LEXER_INJECT@@',
- lexerInject()
- )
-
- .replace('//@@ParserPerformActionInjection@@',
- jsPerformActionToPhp(parserPerformAction)
- )
-
- .replace('//@@LexerPerformActionInjection@@',
- jsPerformActionToPhp(lexerPerformAction, true)
- );
-
- fs.writeFile(option.fileName, parserRaw, function(err) {
- if (err) {
- console.log("Something went bad");
- } else {
- console.log("Success writing new parser files " + fileName + ".js" + " & " + option.fileName);
- console.log("Please Note: The php version of the jison parser is only an ATTEMPTED conversion");
- }
- });
+ .replace('//@@LexerPerformActionInjection@@',
+ jsPerformActionToPhp(lexerPerformAction, true)
+ );
+
+ fs.writeFile(option.fileName, parserRaw, function(err) {
+ if (err) {
+ console.log("Something went bad");
+ } else {
+ console.log("**************SUCCESS**************");
+ console.log("Success writing new parser files " + fileName + ".js" + " & " + option.fileName);
+ console.log("Please Note: The php version of the jison parser is only an ATTEMPTED conversion");
+ }
+ });
+ },
+ msg = (console.log("Executing: " + "jison " + process.argv[2])),
+ spawnedJison = spawn("jison", [process.argv[2]]);
+
+spawnedJison.stdout.on('data', function (data) {
+ console.log(data.toString());
+ console.log("**************Possible Issue**************");
+});
+
+spawnedJison.on('exit', function(code) {
+ if (code != 0) {
+ console.log('Failed: ' + code);
+ } else {
+ createPHPFile(process.argv[2]);
+ }
});
\ No newline at end of file
diff --git a/ports/php/readme b/ports/php/readme.md
similarity index 54%
rename from ports/php/readme
rename to ports/php/readme.md
index 4f7c84d34..c0d30766a 100644
--- a/ports/php/readme
+++ b/ports/php/readme.md
@@ -1,29 +1,31 @@
-Name: Jison Parser Php Port
-Written By: Robert Plummer, RobertLeePlummerJr@gmail.com
-Description: A jison wrapper that first processes a jison file and then injects a php template with the variables from a .js file.
+# Jison Parser Php Port #
+A jison wrapper that first processes a jison file and then injects a php template with the variables from a .js file. Written By: Robert Plummer, RobertLeePlummerJr@gmail.com
-DIRECTIONS:
+## DIRECTIONS ##
1. After you've downloaded jison & node.js, navigate in command line interface to the folder that contains the ".jison" file that you want to process
2. Process the ".jison" file like this "nodejs /location_of_jison/ports/php/php.js my_jison_file.jison"
-CONFIGURATION:
+## CONFIGURATION ##
Configuration takes advantage of the commenting in javascript so as not to conflict with.
-*In your ".jison" file
-**A that has a "//js" comment BEFORE the javascript line starts a javascript area of the parser section. Which will be removed from the php.
-**A line that simply has "//" ends whatever commenting is currently active.
-**A that has a "//php" comment ON the line of php it starts a php area of the parser section. In Javascript this is just a comment, in php though, the comment is removed so that it can be called.
-**A that has no comment, is left alone.
-*Comments in the ".jison" file that start with "//option" can be used to configure the output of the php file.
-**//option optionName:value
-**Current Options:
-*** "namespace" - default is "Jison"
-*** "class" - default is your ".jison" file without the file extension
-*** "fileName" - default is your ".jison" file without the file extension followed by ".php"
-EXAMPLE:
+### In your ".jison" file ###
+* A line that has a "//js" comment BEFORE the javascript line starts a javascript area of the parser section. Which will be removed from the php.
+* A line that simply has "//" ends whatever commenting is currently active.
+* A that has a "//php" comment ON the line of php it starts a php area of the parser section. In Javascript this is just a comment, in php though, the comment is removed so that it can be called.
+* A line that has no comment, is left alone.
+
+### Comments in the ".jison" file that start with "//option" can be used to configure the output of the php file. ###
+* //option optionName:value
+* Current Options:
+ * "namespace" - default is "Jison"
+ * "class" - default is your ".jison" file without the file extension
+ * "fileName" - default is your ".jison" file without the file extension followed by ".php"
+
+## EXAMPLE ##
+```
contents
: content
- {$$ = $1;} //<--this is left alone
+ {$$ = $1;} //<--this is left alone
| contents content
{
//js
@@ -41,3 +43,4 @@ contents
//
}
;
+```
diff --git a/ports/php/template.php b/ports/php/template.php
index 436b679f4..538e25969 100644
--- a/ports/php/template.php
+++ b/ports/php/template.php
@@ -17,6 +17,7 @@
public $shift = 1;
public $reduce = 2;
public $accept = 3;
+ public $unputStack = array();
function trace()
{
@@ -203,7 +204,6 @@ function parse($input)
public $eof;
public $yy = null;
public $match = "";
- public $matched = "";
public $conditionStack = array();
public $conditionStackCount = 0;
public $rules = array();
@@ -218,7 +218,7 @@ function parse($input)
function setInput($input)
{
- $this->input = $input;
+ $this->input = new InputReader($input);
$this->more = $this->less = $this->done = false;
$this->yy = new /**/ParserValue/**/();
$this->conditionStack = array('INITIAL');
@@ -235,12 +235,11 @@ function setInput($input)
function input()
{
- $ch = $this->input[0];
+ $ch = $this->input->ch();
$this->yy->text .= $ch;
$this->yy->leng++;
$this->offset++;
$this->match .= $ch;
- $this->matched .= $ch;
$lines = preg_match("/(?:\r\n?|\n).*/", $ch);
if (count($lines) > 0) {
$this->yy->lineNo++;
@@ -252,30 +251,32 @@ function input()
$this->yy->loc->range->y++;
}
- $this->input = array_slice($this->input, 1);
return $ch;
}
function unput($ch)
{
+ $yy = new /**/ParserValue/**/();
+
$len = strlen($ch);
$lines = explode("/(?:\r\n?|\n)/", $ch);
$linesCount = count($lines);
- $this->input = $ch . $this->input;
- $this->yy->text = substr($this->yy->text, 0, $len - 1);
+ $this->input->unCh($len);
+ $yy->text = substr($this->yy->text, 0, $len - 1);
//$this->yylen -= $len;
$this->offset -= $len;
$oldLines = explode("/(?:\r\n?|\n)/", $this->match);
$oldLinesCount = count($oldLines);
$this->match = substr($this->match, 0, strlen($this->match) - 1);
- $this->matched = substr($this->matched, 0, strlen($this->matched) - 1);
- if (($linesCount - 1) > 0) $this->yy->lineNo -= $linesCount - 1;
+ if (($linesCount - 1) > 0) {
+ $yy->lineNo = $this->yy->lineNo - $linesCount - 1;
+ }
$r = $this->yy->loc->range;
$oldLinesLength = (isset($oldLines[$oldLinesCount - $linesCount]) ? strlen($oldLines[$oldLinesCount - $linesCount]) : 0);
- $this->yy->loc = new ParserLocation(
+ $yy->loc = new ParserLocation(
$this->yy->loc->firstLine,
$this->yy->lineNo,
$this->yy->loc->firstColumn,
@@ -286,8 +287,10 @@ function unput($ch)
);
if (isset($this->ranges)) {
- $this->yy->loc->range = array($r[0], $r[0] + $this->yy->leng - $len);
+ $yy->loc->range = array($r->x, $r->y + $this->yy->leng - $len);
}
+
+ $this->unputStack[] = $yy;
}
function more()
@@ -297,17 +300,22 @@ function more()
function pastInput()
{
- $past = substr($this->matched, 0, strlen($this->matched) - strlen($this->match));
+ $matched = $this->input->toString();
+ $past = substr($matched, 0, strlen($matched) - strlen($this->match));
return (strlen($past) > 20 ? '...' : '') . preg_replace("/\n/", "", substr($past, -20));
}
function upcomingInput()
{
- $next = $this->match;
- if (strlen($next) < 20) {
- $next .= substr($this->input, 0, 20 - strlen($next));
+ if (!$this->done) {
+ $next = $this->match;
+ if (strlen($next) < 20) {
+ $next .= substr($this->input->toString(), 0, 20 - strlen($next));
+ }
+ return preg_replace("/\n/", "", substr($next, 0, 20) . (strlen($next) > 20 ? '...' : ''));
+ } else {
+ return "";
}
- return preg_replace("/\n/", "", substr($next, 0, 20) . (strlen($next) > 20 ? '...' : ''));
}
function showPosition()
@@ -324,11 +332,14 @@ function showPosition()
function next()
{
+ if ($yy = array_pop($this->unputStack)) {
+ $this->yy = $yy;
+ }
if ($this->done == true) {
return $this->eof;
}
- if (empty($this->input)) {
+ if ($this->input->done) {
$this->done = true;
}
@@ -339,7 +350,7 @@ function next()
$rules = $this->currentRules();
for ($i = 0, $j = count($rules); $i < $j; $i++) {
- preg_match($this->rules[$rules[$i]], $this->input, $tempMatch);
+ $tempMatch = $this->input->match($this->rules[$rules[$i]]);
if ($tempMatch && (empty($match) || count($tempMatch[0]) > count($match[0]))) {
$match = $tempMatch;
$index = $i;
@@ -368,33 +379,32 @@ function next()
$this->yy->text .= $match[0];
$this->match .= $match[0];
$this->matches = $match;
- $this->matched .= $match[0];
$this->yy->leng = strlen($this->yy->text);
if (isset($this->ranges)) {
$this->yy->loc->range = new ParserRange($this->offset, $this->offset += $this->yy->leng);
}
$this->more = false;
- $this->input = substr($this->input, $matchCount, strlen($this->input));
+ $this->input->addMatch($match[0]);
$ruleIndex = $rules[$index];
$nextCondition = $this->conditionStack[$this->conditionStackCount - 1];
$token = $this->lexerPerformAction($ruleIndex, $nextCondition);
- if ($this->done == true && empty($this->input) == false) {
+ if ($this->done == true && !$this->input->done) {
$this->done = false;
}
if (empty($token) == false) {
return $this->symbols[
- $token
+ $token
];
} else {
return null;
}
}
- if (empty($this->input)) {
+ if ($this->input->done) {
return $this->eof;
} else {
$this->lexerError("Lexical error on line " . ($this->yy->lineNo + 1) . ". Unrecognized text.\n" . $this->showPosition(), new LexerError("", -1, $this->yy->lineNo));
@@ -460,7 +470,9 @@ public function Range($range)
public function __clone()
{
- return new ParserLocation($this->firstLine, $this->lastLine, $this->firstColumn, $this->lastColumn);
+ if (isset($this->range)) {
+ $this->range = clone $this->range;
+ }
}
}
@@ -472,14 +484,9 @@ class ParserValue
public $text;
function __clone() {
- $clone = new ParserValue();
- $clone->leng = $this->leng;
if (isset($this->loc)) {
- $clone->loc = clone $this->loc;
+ $this->loc = clone $this->loc;
}
- $clone->lineNo = $this->lineNo;
- $clone->text = $this->text;
- return $clone;
}
}
@@ -612,4 +619,57 @@ function __construct($x, $y)
$this->x = $x;
$this->y = $y;
}
+}
+
+class InputReader
+{
+ public $done = false;
+ public $input;
+ public $length;
+ public $matches = array();
+ public $position = 0;
+
+ public function __construct($input)
+ {
+ $this->input = $input;
+ $this->length = strlen($input);
+ }
+
+ public function addMatch($match) {
+ $this->matches[] = $match;
+ $this->position += strlen($match);
+ $this->done = ($this->position >= $this->length);
+ }
+
+ public function ch()
+ {
+ $ch = $this->input{$this->position};
+ $this->addMatch($ch);
+ return $ch;
+ }
+
+ public function unCh($chLength)
+ {
+ $this->position -= $chLength;
+ $this->position = max(0, $this->position);
+ $this->done = ($this->position >= $this->length);
+ }
+
+ public function substring($start, $end) {
+ $start = ($start != 0 ? $this->position + $start : $this->position);
+ $end = ($end != 0 ? $start + $end : $this->length);
+ return substr($this->input, $start, $end);
+ }
+
+ public function match($rule) {
+ if (preg_match($rule, $this->input, $match, null, $this->position)) {
+ return $match;
+ }
+ return null;
+ }
+
+ public function toString()
+ {
+ return implode('', $this->matches);
+ }
}
\ No newline at end of file