Compiler Compiler based on CSharp
Supports RE to NFA, e-NFA, NFA to DFA, DFA Minimization, Lexical Analyzer Generator, SLR, LALR, LR(1) Parser Generator.
A tool for analyzing regular expressions using (
,)
,+
,*
,?
,|
,[
,]
as tokens and generating Scanner tables.
var sg = new ScannerGenerator();
sg.PushRule("", "[\\r\\n ]");
sg.PushRule("if", "if");
sg.PushRule("for", "for");
sg.PushRule("else", "else");
sg.PushRule("id", "[a-z][a-z0-9]*");
sg.PushRule("num", "[0-9]+");
sg.Generate();
sg.PrintDiagram();
var scanner = sg.CreateScannerInstance();
scanner.AllocateTarget("+/a1321 if else 0415abse+9999");
while (scanner.Valid())
{
var ss = scanner.Next();
Console.WriteLine($"{ss.Item1}, {ss.Item2}");
}
plus, +
id, a1321 // Ignore '/'
if, if
else, else
num, 0415
id, abse
plus, +
num, 9999
This source code includes the SLR, LR(1), and LALR parser generators.
var gen = new ParserGenerator();
// Non-Terminals
var exp = gen.CreateNewProduction("exp", false);
var term = gen.CreateNewProduction("term", false);
var factor = gen.CreateNewProduction("factor", false);
// Terminals
var plus = gen.CreateNewProduction("plus");
var minus = gen.CreateNewProduction("minus");
var multiple = gen.CreateNewProduction("multiple");
var divide = gen.CreateNewProduction("divide");
var id = gen.CreateNewProduction("id");
var op_open = gen.CreateNewProduction("op_open");
var op_close = gen.CreateNewProduction("op_close");
exp |= exp + plus + term;
exp |= term;
term |= term + multiple + factor;
term |= factor;
factor |= op_open + exp + op_close;
factor |= id;
gen.PushStarts(exp);
gen.Generate();
gen.PrintStates();
I0 => SHIFT{(exp,I1),(term,I2),(factor,I3),(op_open,I4),(id,I5)}
I1 => SHIFT{(plus,I6)}
REDUCE{($,accept,0)}
I2 => SHIFT{(multiple,I7)}
REDUCE{(plus,exp,1),(op_close,exp,1),($,exp,1)}
I3 => REDUCE{(multiple,term,1),(plus,term,1),(op_close,term,1),($,term,1)}
I4 => SHIFT{(exp,I8),(term,I2),(factor,I3),(op_open,I4),(id,I5)}
I5 => REDUCE{(multiple,factor,1),(plus,factor,1),(op_close,factor,1),($,factor,1)}
I6 => SHIFT{(term,I9),(factor,I3),(op_open,I4),(id,I5)}
I7 => SHIFT{(factor,I10),(op_open,I4),(id,I5)}
I8 => SHIFT{(op_close,I11),(plus,I6)}
I9 => SHIFT{(multiple,I7)}
REDUCE{(plus,exp,0),(op_close,exp,0),($,exp,0)}
I10 => REDUCE{(multiple,term,0),(plus,term,0),(op_close,term,0),($,term,0)}
I11 => REDUCE{(multiple,factor,0),(plus,factor,0),(op_close,factor,0),($,factor,0)}
var gen = new ParserGenerator();
// Non-Terminals
var exp = gen.CreateNewProduction("exp", false);
var term = gen.CreateNewProduction("term", false);
var factor = gen.CreateNewProduction("factor", false);
var func = gen.CreateNewProduction("func", false);
var arguments = gen.CreateNewProduction("args", false);
var args_left = gen.CreateNewProduction("args_left", false);
// Terminals
var plus = gen.CreateNewProduction("plus"); // +
var minus = gen.CreateNewProduction("minus"); // -
var multiple = gen.CreateNewProduction("multiple"); // *
var divide = gen.CreateNewProduction("divide"); // /
var id = gen.CreateNewProduction("id"); // [_$a-zA-Z][_$a-zA-Z0-9]*
var op_open = gen.CreateNewProduction("op_open"); // (
var op_close = gen.CreateNewProduction("op_close"); // )
var num = gen.CreateNewProduction("num"); // [0-9]+
var split = gen.CreateNewProduction("split"); // ,
exp |= exp + plus + term;
exp |= exp + minus + term;
exp |= term;
term |= term + multiple + factor;
term |= term + divide + factor;
term |= factor;
factor |= op_open + exp + op_close;
factor |= num;
factor |= id;
factor |= func;
func |= id + op_open + arguments + op_close;
arguments |= args_left + id;
arguments |= ParserGenerator.EmptyString;
args_left |= args_left + id + split;
args_left |= ParserGenerator.EmptyString;
gen.PushStarts(exp);
gen.GenerateLR1();
gen.PrintStates();
var slr = gen.CreateShiftReduceParserInstance();
// 2*4+5$
Action<string, string> insert = (string x, string y) =>
{
slr.Insert(x, y);
while (slr.Reduce())
{
var l = slr.LatestReduce();
Console.Instance.Write(l.Produnction.PadLeft(8) + " => ");
Console.Instance.WriteLine(string.Join(" ", l.Childs.Select(z => z.Produnction)));
Console.Instance.Write(l.Produnction.PadLeft(8) + " => ");
Console.Instance.WriteLine(string.Join(" ", l.Childs.Select(z => z.Contents)));
slr.Insert(x, y);
}
};
var sg2 = new ScannerGenerator();
sg2.PushRule("", "[\\r\\n ]");
sg2.PushRule("plus", "\\+");
sg2.PushRule("minus", "-");
sg2.PushRule("multiple", "\\*");
sg2.PushRule("divide", "\\/");
sg2.PushRule("op_open", "\\(");
sg2.PushRule("op_close", "\\)");
sg2.PushRule("split", ",");
sg2.PushRule("id", "[a-z][a-z0-9]*");
sg2.PushRule("num", "[0-9]+");
sg2.Generate();
sg2.CreateScannerInstance();
var scanner2 = sg2.CreateScannerInstance();
//scanner2.AllocateTarget("2+6*(6+4*7-2)+sin(a,b,c,d)+cos()*pi");
scanner2.AllocateTarget("2+6*(6+4*7-2)+sin(a,b,c,d)+cos()*pi");
while (scanner2.Valid())
{
var ss = scanner2.Next();
insert(ss.Item1,ss.Item2);
}
insert("$", "$");
-----I0-----
S' -> ·exp $
exp -> ·exp plus term $/plus/minus
exp -> ·exp minus term $/plus/minus
exp -> ·term $/plus/minus
term -> ·term multiple factor $/multiple/divide
term -> ·term divide factor $/multiple/divide
term -> ·factor $/multiple/divide
factor -> ·op_open exp op_close $
factor -> ·num $
factor -> ·id $
factor -> ·func $
func -> ·id op_open args op_close $
func -> ·id op_open op_close $
-----I1-----
S' -> exp · $
exp -> exp ·plus term $/plus/minus
exp -> exp ·minus term $/plus/minus
-----I2-----
exp -> term · $/plus/minus
term -> term ·multiple factor $/multiple/divide
term -> term ·divide factor $/multiple/divide
-----I3-----
term -> factor · $/multiple/divide
-----I4-----
factor -> op_open ·exp op_close $
exp -> ·exp plus term op_close/plus/minus
exp -> ·exp minus term op_close/plus/minus
exp -> ·term op_close/plus/minus
term -> ·term multiple factor op_close/multiple/divide
term -> ·term divide factor op_close/multiple/divide
term -> ·factor op_close/multiple/divide
factor -> ·op_open exp op_close op_close
factor -> ·num op_close
factor -> ·id op_close
factor -> ·func op_close
func -> ·id op_open args op_close op_close
func -> ·id op_open op_close op_close
-----I5-----
factor -> num · $
-----I6-----
factor -> id · $
func -> id ·op_open args op_close $
func -> id ·op_open op_close $
-----I7-----
factor -> func · $
-----I8-----
exp -> exp plus ·term $/plus/minus
term -> ·term multiple factor $/plus/minus/multiple/divide
term -> ·term divide factor $/plus/minus/multiple/divide
term -> ·factor $/plus/minus/multiple/divide
factor -> ·op_open exp op_close $/plus/minus
factor -> ·num $/plus/minus
factor -> ·id $/plus/minus
factor -> ·func $/plus/minus
func -> ·id op_open args op_close $/plus/minus
func -> ·id op_open op_close $/plus/minus
-----I9-----
exp -> exp minus ·term $/plus/minus
term -> ·term multiple factor $/plus/minus/multiple/divide
term -> ·term divide factor $/plus/minus/multiple/divide
term -> ·factor $/plus/minus/multiple/divide
factor -> ·op_open exp op_close $/plus/minus
factor -> ·num $/plus/minus
factor -> ·id $/plus/minus
factor -> ·func $/plus/minus
func -> ·id op_open args op_close $/plus/minus
func -> ·id op_open op_close $/plus/minus
-----I10-----
term -> term multiple ·factor $/multiple/divide
factor -> ·op_open exp op_close $/multiple/divide
factor -> ·num $/multiple/divide
factor -> ·id $/multiple/divide
factor -> ·func $/multiple/divide
func -> ·id op_open args op_close $/multiple/divide
func -> ·id op_open op_close $/multiple/divide
-----I11-----
term -> term divide ·factor $/multiple/divide
factor -> ·op_open exp op_close $/multiple/divide
factor -> ·num $/multiple/divide
factor -> ·id $/multiple/divide
factor -> ·func $/multiple/divide
func -> ·id op_open args op_close $/multiple/divide
func -> ·id op_open op_close $/multiple/divide
-----I12-----
factor -> op_open exp ·op_close $
exp -> exp ·plus term op_close/plus/minus
exp -> exp ·minus term op_close/plus/minus
-----I13-----
exp -> term · op_close/plus/minus
term -> term ·multiple factor op_close/multiple/divide
term -> term ·divide factor op_close/multiple/divide
-----I14-----
term -> factor · op_close/multiple/divide
-----I15-----
factor -> op_open ·exp op_close op_close
exp -> ·exp plus term op_close/plus/minus
exp -> ·exp minus term op_close/plus/minus
exp -> ·term op_close/plus/minus
term -> ·term multiple factor op_close/multiple/divide
term -> ·term divide factor op_close/multiple/divide
term -> ·factor op_close/multiple/divide
factor -> ·op_open exp op_close op_close
factor -> ·num op_close
factor -> ·id op_close
factor -> ·func op_close
func -> ·id op_open args op_close op_close
func -> ·id op_open op_close op_close
-----I16-----
factor -> num · op_close
-----I17-----
factor -> id · op_close
func -> id ·op_open args op_close op_close
func -> id ·op_open op_close op_close
-----I18-----
factor -> func · op_close
-----I19-----
func -> id op_open ·args op_close $
func -> id op_open ·op_close $
args -> ·args_left id op_close
args -> ·id op_close
args_left -> ·args_left id split id
args_left -> ·id split id
-----I20-----
exp -> exp plus term · $/plus/minus
term -> term ·multiple factor $/plus/minus/multiple/divide
term -> term ·divide factor $/plus/minus/multiple/divide
-----I21-----
term -> factor · $/plus/minus/multiple/divide
-----I22-----
factor -> op_open ·exp op_close $/plus/minus
exp -> ·exp plus term op_close/plus/minus
exp -> ·exp minus term op_close/plus/minus
exp -> ·term op_close/plus/minus
term -> ·term multiple factor op_close/multiple/divide
term -> ·term divide factor op_close/multiple/divide
term -> ·factor op_close/multiple/divide
factor -> ·op_open exp op_close op_close
factor -> ·num op_close
factor -> ·id op_close
factor -> ·func op_close
func -> ·id op_open args op_close op_close
func -> ·id op_open op_close op_close
-----I23-----
factor -> num · $/plus/minus
-----I24-----
factor -> id · $/plus/minus
func -> id ·op_open args op_close $/plus/minus
func -> id ·op_open op_close $/plus/minus
-----I25-----
factor -> func · $/plus/minus
-----I26-----
exp -> exp minus term · $/plus/minus
term -> term ·multiple factor $/plus/minus/multiple/divide
term -> term ·divide factor $/plus/minus/multiple/divide
-----I27-----
term -> term multiple factor · $/multiple/divide
-----I28-----
factor -> op_open ·exp op_close $/multiple/divide
exp -> ·exp plus term op_close/plus/minus
exp -> ·exp minus term op_close/plus/minus
exp -> ·term op_close/plus/minus
term -> ·term multiple factor op_close/multiple/divide
term -> ·term divide factor op_close/multiple/divide
term -> ·factor op_close/multiple/divide
factor -> ·op_open exp op_close op_close
factor -> ·num op_close
factor -> ·id op_close
factor -> ·func op_close
func -> ·id op_open args op_close op_close
func -> ·id op_open op_close op_close
-----I29-----
factor -> num · $/multiple/divide
-----I30-----
factor -> id · $/multiple/divide
func -> id ·op_open args op_close $/multiple/divide
func -> id ·op_open op_close $/multiple/divide
-----I31-----
factor -> func · $/multiple/divide
-----I32-----
term -> term divide factor · $/multiple/divide
-----I33-----
factor -> op_open exp op_close · $
-----I34-----
exp -> exp plus ·term op_close/plus/minus
term -> ·term multiple factor op_close/plus/minus/multiple/divide
term -> ·term divide factor op_close/plus/minus/multiple/divide
term -> ·factor op_close/plus/minus/multiple/divide
factor -> ·op_open exp op_close op_close/plus/minus
factor -> ·num op_close/plus/minus
factor -> ·id op_close/plus/minus
factor -> ·func op_close/plus/minus
func -> ·id op_open args op_close op_close/plus/minus
func -> ·id op_open op_close op_close/plus/minus
-----I35-----
exp -> exp minus ·term op_close/plus/minus
term -> ·term multiple factor op_close/plus/minus/multiple/divide
term -> ·term divide factor op_close/plus/minus/multiple/divide
term -> ·factor op_close/plus/minus/multiple/divide
factor -> ·op_open exp op_close op_close/plus/minus
factor -> ·num op_close/plus/minus
factor -> ·id op_close/plus/minus
factor -> ·func op_close/plus/minus
func -> ·id op_open args op_close op_close/plus/minus
func -> ·id op_open op_close op_close/plus/minus
-----I36-----
term -> term multiple ·factor op_close/multiple/divide
factor -> ·op_open exp op_close op_close/multiple/divide
factor -> ·num op_close/multiple/divide
factor -> ·id op_close/multiple/divide
factor -> ·func op_close/multiple/divide
func -> ·id op_open args op_close op_close/multiple/divide
func -> ·id op_open op_close op_close/multiple/divide
-----I37-----
term -> term divide ·factor op_close/multiple/divide
factor -> ·op_open exp op_close op_close/multiple/divide
factor -> ·num op_close/multiple/divide
factor -> ·id op_close/multiple/divide
factor -> ·func op_close/multiple/divide
func -> ·id op_open args op_close op_close/multiple/divide
func -> ·id op_open op_close op_close/multiple/divide
-----I38-----
factor -> op_open exp ·op_close op_close
exp -> exp ·plus term op_close/plus/minus
exp -> exp ·minus term op_close/plus/minus
-----I39-----
func -> id op_open ·args op_close op_close
func -> id op_open ·op_close op_close
args -> ·args_left id op_close
args -> ·id op_close
args_left -> ·args_left id split id
args_left -> ·id split id
-----I40-----
func -> id op_open args ·op_close $
-----I41-----
func -> id op_open op_close · $
-----I42-----
args -> args_left ·id op_close
args_left -> args_left ·id split id
-----I43-----
args -> id · op_close
args_left -> id ·split id
-----I44-----
term -> term multiple ·factor $/plus/minus/multiple/divide
factor -> ·op_open exp op_close $/plus/minus/multiple/divide
factor -> ·num $/plus/minus/multiple/divide
factor -> ·id $/plus/minus/multiple/divide
factor -> ·func $/plus/minus/multiple/divide
func -> ·id op_open args op_close $/plus/minus/multiple/divide
func -> ·id op_open op_close $/plus/minus/multiple/divide
-----I45-----
term -> term divide ·factor $/plus/minus/multiple/divide
factor -> ·op_open exp op_close $/plus/minus/multiple/divide
factor -> ·num $/plus/minus/multiple/divide
factor -> ·id $/plus/minus/multiple/divide
factor -> ·func $/plus/minus/multiple/divide
func -> ·id op_open args op_close $/plus/minus/multiple/divide
func -> ·id op_open op_close $/plus/minus/multiple/divide
-----I46-----
factor -> op_open exp ·op_close $/plus/minus
exp -> exp ·plus term op_close/plus/minus
exp -> exp ·minus term op_close/plus/minus
-----I47-----
func -> id op_open ·args op_close $/plus/minus
func -> id op_open ·op_close $/plus/minus
args -> ·args_left id op_close
args -> ·id op_close
args_left -> ·args_left id split id
args_left -> ·id split id
-----I48-----
factor -> op_open exp ·op_close $/multiple/divide
exp -> exp ·plus term op_close/plus/minus
exp -> exp ·minus term op_close/plus/minus
-----I49-----
func -> id op_open ·args op_close $/multiple/divide
func -> id op_open ·op_close $/multiple/divide
args -> ·args_left id op_close
args -> ·id op_close
args_left -> ·args_left id split id
args_left -> ·id split id
-----I50-----
exp -> exp plus term · op_close/plus/minus
term -> term ·multiple factor op_close/plus/minus/multiple/divide
term -> term ·divide factor op_close/plus/minus/multiple/divide
-----I51-----
term -> factor · op_close/plus/minus/multiple/divide
-----I52-----
factor -> op_open ·exp op_close op_close/plus/minus
exp -> ·exp plus term op_close/plus/minus
exp -> ·exp minus term op_close/plus/minus
exp -> ·term op_close/plus/minus
term -> ·term multiple factor op_close/multiple/divide
term -> ·term divide factor op_close/multiple/divide
term -> ·factor op_close/multiple/divide
factor -> ·op_open exp op_close op_close
factor -> ·num op_close
factor -> ·id op_close
factor -> ·func op_close
func -> ·id op_open args op_close op_close
func -> ·id op_open op_close op_close
-----I53-----
factor -> num · op_close/plus/minus
-----I54-----
factor -> id · op_close/plus/minus
func -> id ·op_open args op_close op_close/plus/minus
func -> id ·op_open op_close op_close/plus/minus
-----I55-----
factor -> func · op_close/plus/minus
-----I56-----
exp -> exp minus term · op_close/plus/minus
term -> term ·multiple factor op_close/plus/minus/multiple/divide
term -> term ·divide factor op_close/plus/minus/multiple/divide
-----I57-----
term -> term multiple factor · op_close/multiple/divide
-----I58-----
factor -> op_open ·exp op_close op_close/multiple/divide
exp -> ·exp plus term op_close/plus/minus
exp -> ·exp minus term op_close/plus/minus
exp -> ·term op_close/plus/minus
term -> ·term multiple factor op_close/multiple/divide
term -> ·term divide factor op_close/multiple/divide
term -> ·factor op_close/multiple/divide
factor -> ·op_open exp op_close op_close
factor -> ·num op_close
factor -> ·id op_close
factor -> ·func op_close
func -> ·id op_open args op_close op_close
func -> ·id op_open op_close op_close
-----I59-----
factor -> num · op_close/multiple/divide
-----I60-----
factor -> id · op_close/multiple/divide
func -> id ·op_open args op_close op_close/multiple/divide
func -> id ·op_open op_close op_close/multiple/divide
-----I61-----
factor -> func · op_close/multiple/divide
-----I62-----
term -> term divide factor · op_close/multiple/divide
-----I63-----
factor -> op_open exp op_close · op_close
-----I64-----
func -> id op_open args ·op_close op_close
-----I65-----
func -> id op_open op_close · op_close
-----I66-----
func -> id op_open args op_close · $
-----I67-----
args -> args_left id · op_close
args_left -> args_left id ·split id
-----I68-----
args_left -> id split · id
-----I69-----
term -> term multiple factor · $/plus/minus/multiple/divide
-----I70-----
factor -> op_open ·exp op_close $/plus/minus/multiple/divide
exp -> ·exp plus term op_close/plus/minus
exp -> ·exp minus term op_close/plus/minus
exp -> ·term op_close/plus/minus
term -> ·term multiple factor op_close/multiple/divide
term -> ·term divide factor op_close/multiple/divide
term -> ·factor op_close/multiple/divide
factor -> ·op_open exp op_close op_close
factor -> ·num op_close
factor -> ·id op_close
factor -> ·func op_close
func -> ·id op_open args op_close op_close
func -> ·id op_open op_close op_close
-----I71-----
factor -> num · $/plus/minus/multiple/divide
-----I72-----
factor -> id · $/plus/minus/multiple/divide
func -> id ·op_open args op_close $/plus/minus/multiple/divide
func -> id ·op_open op_close $/plus/minus/multiple/divide
-----I73-----
factor -> func · $/plus/minus/multiple/divide
-----I74-----
term -> term divide factor · $/plus/minus/multiple/divide
-----I75-----
factor -> op_open exp op_close · $/plus/minus
-----I76-----
func -> id op_open args ·op_close $/plus/minus
-----I77-----
func -> id op_open op_close · $/plus/minus
-----I78-----
factor -> op_open exp op_close · $/multiple/divide
-----I79-----
func -> id op_open args ·op_close $/multiple/divide
-----I80-----
func -> id op_open op_close · $/multiple/divide
-----I81-----
term -> term multiple ·factor op_close/plus/minus/multiple/divide
factor -> ·op_open exp op_close op_close/plus/minus/multiple/divide
factor -> ·num op_close/plus/minus/multiple/divide
factor -> ·id op_close/plus/minus/multiple/divide
factor -> ·func op_close/plus/minus/multiple/divide
func -> ·id op_open args op_close op_close/plus/minus/multiple/divide
func -> ·id op_open op_close op_close/plus/minus/multiple/divide
-----I82-----
term -> term divide ·factor op_close/plus/minus/multiple/divide
factor -> ·op_open exp op_close op_close/plus/minus/multiple/divide
factor -> ·num op_close/plus/minus/multiple/divide
factor -> ·id op_close/plus/minus/multiple/divide
factor -> ·func op_close/plus/minus/multiple/divide
func -> ·id op_open args op_close op_close/plus/minus/multiple/divide
func -> ·id op_open op_close op_close/plus/minus/multiple/divide
-----I83-----
factor -> op_open exp ·op_close op_close/plus/minus
exp -> exp ·plus term op_close/plus/minus
exp -> exp ·minus term op_close/plus/minus
-----I84-----
func -> id op_open ·args op_close op_close/plus/minus
func -> id op_open ·op_close op_close/plus/minus
args -> ·args_left id op_close
args -> ·id op_close
args_left -> ·args_left id split id
args_left -> ·id split id
-----I85-----
factor -> op_open exp ·op_close op_close/multiple/divide
exp -> exp ·plus term op_close/plus/minus
exp -> exp ·minus term op_close/plus/minus
-----I86-----
func -> id op_open ·args op_close op_close/multiple/divide
func -> id op_open ·op_close op_close/multiple/divide
args -> ·args_left id op_close
args -> ·id op_close
args_left -> ·args_left id split id
args_left -> ·id split id
-----I87-----
func -> id op_open args op_close · op_close
-----I88-----
args_left -> args_left id split · id
-----I89-----
factor -> op_open exp ·op_close $/plus/minus/multiple/divide
exp -> exp ·plus term op_close/plus/minus
exp -> exp ·minus term op_close/plus/minus
-----I90-----
func -> id op_open ·args op_close $/plus/minus/multiple/divide
func -> id op_open ·op_close $/plus/minus/multiple/divide
args -> ·args_left id op_close
args -> ·id op_close
args_left -> ·args_left id split id
args_left -> ·id split id
-----I91-----
func -> id op_open args op_close · $/plus/minus
-----I92-----
func -> id op_open args op_close · $/multiple/divide
-----I93-----
term -> term multiple factor · op_close/plus/minus/multiple/divide
-----I94-----
factor -> op_open ·exp op_close op_close/plus/minus/multiple/divide
exp -> ·exp plus term op_close/plus/minus
exp -> ·exp minus term op_close/plus/minus
exp -> ·term op_close/plus/minus
term -> ·term multiple factor op_close/multiple/divide
term -> ·term divide factor op_close/multiple/divide
term -> ·factor op_close/multiple/divide
factor -> ·op_open exp op_close op_close
factor -> ·num op_close
factor -> ·id op_close
factor -> ·func op_close
func -> ·id op_open args op_close op_close
func -> ·id op_open op_close op_close
-----I95-----
factor -> num · op_close/plus/minus/multiple/divide
-----I96-----
factor -> id · op_close/plus/minus/multiple/divide
func -> id ·op_open args op_close op_close/plus/minus/multiple/divide
func -> id ·op_open op_close op_close/plus/minus/multiple/divide
-----I97-----
factor -> func · op_close/plus/minus/multiple/divide
-----I98-----
term -> term divide factor · op_close/plus/minus/multiple/divide
-----I99-----
factor -> op_open exp op_close · op_close/plus/minus
-----I100-----
func -> id op_open args ·op_close op_close/plus/minus
-----I101-----
func -> id op_open op_close · op_close/plus/minus
-----I102-----
factor -> op_open exp op_close · op_close/multiple/divide
-----I103-----
func -> id op_open args ·op_close op_close/multiple/divide
-----I104-----
func -> id op_open op_close · op_close/multiple/divide
-----I105-----
factor -> op_open exp op_close · $/plus/minus/multiple/divide
-----I106-----
func -> id op_open args ·op_close $/plus/minus/multiple/divide
-----I107-----
func -> id op_open op_close · $/plus/minus/multiple/divide
-----I108-----
factor -> op_open exp ·op_close op_close/plus/minus/multiple/divide
exp -> exp ·plus term op_close/plus/minus
exp -> exp ·minus term op_close/plus/minus
-----I109-----
func -> id op_open ·args op_close op_close/plus/minus/multiple/divide
func -> id op_open ·op_close op_close/plus/minus/multiple/divide
args -> ·args_left id op_close
args -> ·id op_close
args_left -> ·args_left id split id
args_left -> ·id split id
-----I110-----
func -> id op_open args op_close · op_close/plus/minus
-----I111-----
func -> id op_open args op_close · op_close/multiple/divide
-----I112-----
func -> id op_open args op_close · $/plus/minus/multiple/divide
-----I113-----
factor -> op_open exp op_close · op_close/plus/minus/multiple/divide
-----I114-----
func -> id op_open args ·op_close op_close/plus/minus/multiple/divide
-----I115-----
func -> id op_open op_close · op_close/plus/minus/multiple/divide
-----I116-----
func -> id op_open args op_close · op_close/plus/minus/multiple/divide
I0 => SHIFT{(exp,I1),(term,I2),(factor,I3),(op_open,I4),(num,I5),(id,I6),(func,I7)}
I1 => SHIFT{(plus,I8),(minus,I9)}
REDUCE{($,accept,0)}
I2 => SHIFT{(multiple,I10),(divide,I11)}
REDUCE{(plus,exp,2),(minus,exp,2),(op_close,exp,2),($,exp,2)}
I3 => REDUCE{(multiple,term,2),(divide,term,2),(plus,term,2),(minus,term,2),(op_close,term,2),($,term,2)}
I4 => SHIFT{(exp,I12),(term,I13),(factor,I14),(op_open,I15),(num,I16),(id,I17),(func,I18)}
I5 => REDUCE{(multiple,factor,1),(divide,factor,1),(plus,factor,1),(minus,factor,1),(op_close,factor,1),($,factor,1)}
I6 => SHIFT{(op_open,I19)}
REDUCE{(multiple,factor,2),(divide,factor,2),(plus,factor,2),(minus,factor,2),(op_close,factor,2),($,factor,2)}
I7 => REDUCE{(multiple,factor,3),(divide,factor,3),(plus,factor,3),(minus,factor,3),(op_close,factor,3),($,factor,3)}
I8 => SHIFT{(term,I20),(factor,I21),(op_open,I22),(num,I23),(id,I24),(func,I25)}
I9 => SHIFT{(term,I26),(factor,I21),(op_open,I22),(num,I23),(id,I24),(func,I25)}
I10 => SHIFT{(factor,I27),(op_open,I28),(num,I29),(id,I30),(func,I31)}
I11 => SHIFT{(factor,I32),(op_open,I28),(num,I29),(id,I30),(func,I31)}
I12 => SHIFT{(op_close,I33),(plus,I34),(minus,I35)}
I13 => SHIFT{(multiple,I36),(divide,I37)}
REDUCE{(plus,exp,2),(minus,exp,2),(op_close,exp,2),($,exp,2)}
I14 => REDUCE{(multiple,term,2),(divide,term,2),(plus,term,2),(minus,term,2),(op_close,term,2),($,term,2)}
I15 => SHIFT{(exp,I38),(term,I13),(factor,I14),(op_open,I15),(num,I16),(id,I17),(func,I18)}
I16 => REDUCE{(multiple,factor,1),(divide,factor,1),(plus,factor,1),(minus,factor,1),(op_close,factor,1),($,factor,1)}
I17 => SHIFT{(op_open,I39)}
REDUCE{(multiple,factor,2),(divide,factor,2),(plus,factor,2),(minus,factor,2),(op_close,factor,2),($,factor,2)}
I18 => REDUCE{(multiple,factor,3),(divide,factor,3),(plus,factor,3),(minus,factor,3),(op_close,factor,3),($,factor,3)}
I19 => SHIFT{(args,I40),(op_close,I41),(args_left,I42),(id,I43)}
I20 => SHIFT{(multiple,I44),(divide,I45)}
REDUCE{(plus,exp,0),(minus,exp,0),(op_close,exp,0),($,exp,0)}
I21 => REDUCE{(multiple,term,2),(divide,term,2),(plus,term,2),(minus,term,2),(op_close,term,2),($,term,2)}
I22 => SHIFT{(exp,I46),(term,I13),(factor,I14),(op_open,I15),(num,I16),(id,I17),(func,I18)}
I23 => REDUCE{(multiple,factor,1),(divide,factor,1),(plus,factor,1),(minus,factor,1),(op_close,factor,1),($,factor,1)}
I24 => SHIFT{(op_open,I47)}
REDUCE{(multiple,factor,2),(divide,factor,2),(plus,factor,2),(minus,factor,2),(op_close,factor,2),($,factor,2)}
I25 => REDUCE{(multiple,factor,3),(divide,factor,3),(plus,factor,3),(minus,factor,3),(op_close,factor,3),($,factor,3)}
I26 => SHIFT{(multiple,I44),(divide,I45)}
REDUCE{(plus,exp,1),(minus,exp,1),(op_close,exp,1),($,exp,1)}
I27 => REDUCE{(multiple,term,0),(divide,term,0),(plus,term,0),(minus,term,0),(op_close,term,0),($,term,0)}
I28 => SHIFT{(exp,I48),(term,I13),(factor,I14),(op_open,I15),(num,I16),(id,I17),(func,I18)}
I29 => REDUCE{(multiple,factor,1),(divide,factor,1),(plus,factor,1),(minus,factor,1),(op_close,factor,1),($,factor,1)}
I30 => SHIFT{(op_open,I49)}
REDUCE{(multiple,factor,2),(divide,factor,2),(plus,factor,2),(minus,factor,2),(op_close,factor,2),($,factor,2)}
I31 => REDUCE{(multiple,factor,3),(divide,factor,3),(plus,factor,3),(minus,factor,3),(op_close,factor,3),($,factor,3)}
I32 => REDUCE{(multiple,term,1),(divide,term,1),(plus,term,1),(minus,term,1),(op_close,term,1),($,term,1)}
I33 => REDUCE{(multiple,factor,0),(divide,factor,0),(plus,factor,0),(minus,factor,0),(op_close,factor,0),($,factor,0)}
I34 => SHIFT{(term,I50),(factor,I51),(op_open,I52),(num,I53),(id,I54),(func,I55)}
I35 => SHIFT{(term,I56),(factor,I51),(op_open,I52),(num,I53),(id,I54),(func,I55)}
I36 => SHIFT{(factor,I57),(op_open,I58),(num,I59),(id,I60),(func,I61)}
I37 => SHIFT{(factor,I62),(op_open,I58),(num,I59),(id,I60),(func,I61)}
I38 => SHIFT{(op_close,I63),(plus,I34),(minus,I35)}
I39 => SHIFT{(args,I64),(op_close,I65),(args_left,I42),(id,I43)}
I40 => SHIFT{(op_close,I66)}
I41 => REDUCE{(multiple,func,1),(divide,func,1),(plus,func,1),(minus,func,1),(op_close,func,1),($,func,1)}
I42 => SHIFT{(id,I67)}
I43 => SHIFT{(split,I68)}
REDUCE{(op_close,args,1)}
I44 => SHIFT{(factor,I69),(op_open,I70),(num,I71),(id,I72),(func,I73)}
I45 => SHIFT{(factor,I74),(op_open,I70),(num,I71),(id,I72),(func,I73)}
I46 => SHIFT{(op_close,I75),(plus,I34),(minus,I35)}
I47 => SHIFT{(args,I76),(op_close,I77),(args_left,I42),(id,I43)}
I48 => SHIFT{(op_close,I78),(plus,I34),(minus,I35)}
I49 => SHIFT{(args,I79),(op_close,I80),(args_left,I42),(id,I43)}
I50 => SHIFT{(multiple,I81),(divide,I82)}
REDUCE{(plus,exp,0),(minus,exp,0),(op_close,exp,0),($,exp,0)}
I51 => REDUCE{(multiple,term,2),(divide,term,2),(plus,term,2),(minus,term,2),(op_close,term,2),($,term,2)}
I52 => SHIFT{(exp,I83),(term,I13),(factor,I14),(op_open,I15),(num,I16),(id,I17),(func,I18)}
I53 => REDUCE{(multiple,factor,1),(divide,factor,1),(plus,factor,1),(minus,factor,1),(op_close,factor,1),($,factor,1)}
I54 => SHIFT{(op_open,I84)}
REDUCE{(multiple,factor,2),(divide,factor,2),(plus,factor,2),(minus,factor,2),(op_close,factor,2),($,factor,2)}
I55 => REDUCE{(multiple,factor,3),(divide,factor,3),(plus,factor,3),(minus,factor,3),(op_close,factor,3),($,factor,3)}
I56 => SHIFT{(multiple,I81),(divide,I82)}
REDUCE{(plus,exp,1),(minus,exp,1),(op_close,exp,1),($,exp,1)}
I57 => REDUCE{(multiple,term,0),(divide,term,0),(plus,term,0),(minus,term,0),(op_close,term,0),($,term,0)}
I58 => SHIFT{(exp,I85),(term,I13),(factor,I14),(op_open,I15),(num,I16),(id,I17),(func,I18)}
I59 => REDUCE{(multiple,factor,1),(divide,factor,1),(plus,factor,1),(minus,factor,1),(op_close,factor,1),($,factor,1)}
I60 => SHIFT{(op_open,I86)}
REDUCE{(multiple,factor,2),(divide,factor,2),(plus,factor,2),(minus,factor,2),(op_close,factor,2),($,factor,2)}
I61 => REDUCE{(multiple,factor,3),(divide,factor,3),(plus,factor,3),(minus,factor,3),(op_close,factor,3),($,factor,3)}
I62 => REDUCE{(multiple,term,1),(divide,term,1),(plus,term,1),(minus,term,1),(op_close,term,1),($,term,1)}
I63 => REDUCE{(multiple,factor,0),(divide,factor,0),(plus,factor,0),(minus,factor,0),(op_close,factor,0),($,factor,0)}
I64 => SHIFT{(op_close,I87)}
I65 => REDUCE{(multiple,func,1),(divide,func,1),(plus,func,1),(minus,func,1),(op_close,func,1),($,func,1)}
I66 => REDUCE{(multiple,func,0),(divide,func,0),(plus,func,0),(minus,func,0),(op_close,func,0),($,func,0)}
I67 => SHIFT{(split,I88)}
REDUCE{(op_close,args,0)}
I68 => REDUCE{(id,args_left,1)}
I69 => REDUCE{(multiple,term,0),(divide,term,0),(plus,term,0),(minus,term,0),(op_close,term,0),($,term,0)}
I70 => SHIFT{(exp,I89),(term,I13),(factor,I14),(op_open,I15),(num,I16),(id,I17),(func,I18)}
I71 => REDUCE{(multiple,factor,1),(divide,factor,1),(plus,factor,1),(minus,factor,1),(op_close,factor,1),($,factor,1)}
I72 => SHIFT{(op_open,I90)}
REDUCE{(multiple,factor,2),(divide,factor,2),(plus,factor,2),(minus,factor,2),(op_close,factor,2),($,factor,2)}
I73 => REDUCE{(multiple,factor,3),(divide,factor,3),(plus,factor,3),(minus,factor,3),(op_close,factor,3),($,factor,3)}
I74 => REDUCE{(multiple,term,1),(divide,term,1),(plus,term,1),(minus,term,1),(op_close,term,1),($,term,1)}
I75 => REDUCE{(multiple,factor,0),(divide,factor,0),(plus,factor,0),(minus,factor,0),(op_close,factor,0),($,factor,0)}
I76 => SHIFT{(op_close,I91)}
I77 => REDUCE{(multiple,func,1),(divide,func,1),(plus,func,1),(minus,func,1),(op_close,func,1),($,func,1)}
I78 => REDUCE{(multiple,factor,0),(divide,factor,0),(plus,factor,0),(minus,factor,0),(op_close,factor,0),($,factor,0)}
I79 => SHIFT{(op_close,I92)}
I80 => REDUCE{(multiple,func,1),(divide,func,1),(plus,func,1),(minus,func,1),(op_close,func,1),($,func,1)}
I81 => SHIFT{(factor,I93),(op_open,I94),(num,I95),(id,I96),(func,I97)}
I82 => SHIFT{(factor,I98),(op_open,I94),(num,I95),(id,I96),(func,I97)}
I83 => SHIFT{(op_close,I99),(plus,I34),(minus,I35)}
I84 => SHIFT{(args,I100),(op_close,I101),(args_left,I42),(id,I43)}
I85 => SHIFT{(op_close,I102),(plus,I34),(minus,I35)}
I86 => SHIFT{(args,I103),(op_close,I104),(args_left,I42),(id,I43)}
I87 => REDUCE{(multiple,func,0),(divide,func,0),(plus,func,0),(minus,func,0),(op_close,func,0),($,func,0)}
I88 => REDUCE{(id,args_left,0)}
I89 => SHIFT{(op_close,I105),(plus,I34),(minus,I35)}
I90 => SHIFT{(args,I106),(op_close,I107),(args_left,I42),(id,I43)}
I91 => REDUCE{(multiple,func,0),(divide,func,0),(plus,func,0),(minus,func,0),(op_close,func,0),($,func,0)}
I92 => REDUCE{(multiple,func,0),(divide,func,0),(plus,func,0),(minus,func,0),(op_close,func,0),($,func,0)}
I93 => REDUCE{(multiple,term,0),(divide,term,0),(plus,term,0),(minus,term,0),(op_close,term,0),($,term,0)}
I94 => SHIFT{(exp,I108),(term,I13),(factor,I14),(op_open,I15),(num,I16),(id,I17),(func,I18)}
I95 => REDUCE{(multiple,factor,1),(divide,factor,1),(plus,factor,1),(minus,factor,1),(op_close,factor,1),($,factor,1)}
I96 => SHIFT{(op_open,I109)}
REDUCE{(multiple,factor,2),(divide,factor,2),(plus,factor,2),(minus,factor,2),(op_close,factor,2),($,factor,2)}
I97 => REDUCE{(multiple,factor,3),(divide,factor,3),(plus,factor,3),(minus,factor,3),(op_close,factor,3),($,factor,3)}
I98 => REDUCE{(multiple,term,1),(divide,term,1),(plus,term,1),(minus,term,1),(op_close,term,1),($,term,1)}
I99 => REDUCE{(multiple,factor,0),(divide,factor,0),(plus,factor,0),(minus,factor,0),(op_close,factor,0),($,factor,0)}
I100 => SHIFT{(op_close,I110)}
I101 => REDUCE{(multiple,func,1),(divide,func,1),(plus,func,1),(minus,func,1),(op_close,func,1),($,func,1)}
I102 => REDUCE{(multiple,factor,0),(divide,factor,0),(plus,factor,0),(minus,factor,0),(op_close,factor,0),($,factor,0)}
I103 => SHIFT{(op_close,I111)}
I104 => REDUCE{(multiple,func,1),(divide,func,1),(plus,func,1),(minus,func,1),(op_close,func,1),($,func,1)}
I105 => REDUCE{(multiple,factor,0),(divide,factor,0),(plus,factor,0),(minus,factor,0),(op_close,factor,0),($,factor,0)}
I106 => SHIFT{(op_close,I112)}
I107 => REDUCE{(multiple,func,1),(divide,func,1),(plus,func,1),(minus,func,1),(op_close,func,1),($,func,1)}
I108 => SHIFT{(op_close,I113),(plus,I34),(minus,I35)}
I109 => SHIFT{(args,I114),(op_close,I115),(args_left,I42),(id,I43)}
I110 => REDUCE{(multiple,func,0),(divide,func,0),(plus,func,0),(minus,func,0),(op_close,func,0),($,func,0)}
I111 => REDUCE{(multiple,func,0),(divide,func,0),(plus,func,0),(minus,func,0),(op_close,func,0),($,func,0)}
I112 => REDUCE{(multiple,func,0),(divide,func,0),(plus,func,0),(minus,func,0),(op_close,func,0),($,func,0)}
I113 => REDUCE{(multiple,factor,0),(divide,factor,0),(plus,factor,0),(minus,factor,0),(op_close,factor,0),($,factor,0)}
I114 => SHIFT{(op_close,I116)}
I115 => REDUCE{(multiple,func,1),(divide,func,1),(plus,func,1),(minus,func,1),(op_close,func,1),($,func,1)}
I116 => REDUCE{(multiple,func,0),(divide,func,0),(plus,func,0),(minus,func,0),(op_close,func,0),($,func,0)}
var gen2 = new ParserGenerator();
// Non-Terminals
var S = gen2.CreateNewProduction("S", false);
var L = gen2.CreateNewProduction("L", false);
var R = gen2.CreateNewProduction("R", false);
// Terminals
var equal = gen2.CreateNewProduction("=");
var mult = gen2.CreateNewProduction("*");
var div = gen2.CreateNewProduction("/");
var pp = gen2.CreateNewProduction("+");
var mi = gen2.CreateNewProduction("-");
var num = gen2.CreateNewProduction("num");
// right associativity, -
gen2.PushConflictSolver(false, new Tuple<ParserProduction, int>(S, 4));
// left associativity, *, /
gen2.PushConflictSolver(true, mult, div);
// left associativity, +, -
gen2.PushConflictSolver(true, pp, mi);
S |= S + pp + S;
S |= S + mi + S;
S |= S + mult + S;
S |= S + div + S;
S |= mi + S;
S |= num;
gen2.PushStarts(S);
gen2.Generate();
gen2.PrintStates();
gen2.GenerateLALR();
gen2.PrintStates();
var slr = gen2.CreateShiftReduceParserInstance();
// 2*4+5$
Action<string, string> insert = (string x, string y) =>
{
slr.Insert(x, y);
while (slr.Reduce())
{
Console.Instance.WriteLine(slr.Stack());
var l = slr.LatestReduce();
Console.Instance.Write(l.Produnction.PadLeft(8) + " => ");
Console.Instance.WriteLine(string.Join(" ", l.Childs.Select(z => z.Produnction)));
Console.Instance.Write(l.Produnction.PadLeft(8) + " => ");
Console.Instance.WriteLine(string.Join(" ", l.Childs.Select(z => z.Contents)));
slr.Insert(x, y);
}
Console.Instance.WriteLine(slr.Stack());
};
var sg2 = new ScannerGenerator();
sg2.PushRule("", "[\\r\\n ]");
sg2.PushRule("+", "\\+");
sg2.PushRule("-", "-");
sg2.PushRule("*", "\\*");
sg2.PushRule("/", "\\/");
sg2.PushRule("(", "\\(");
sg2.PushRule(")", "\\)");
sg2.PushRule(",", ",");
sg2.PushRule("id", "[a-z][a-z0-9]*");
sg2.PushRule("num", "[0-9]+");
sg2.Generate();
sg2.CreateScannerInstance();
var scanner2 = sg2.CreateScannerInstance();
//scanner2.AllocateTarget("2+6*(6+4*7-2)+sin(a,b,c,d)+cos()*pi");
scanner2.AllocateTarget("2+--6*4");
while (scanner2.Valid())
{
var ss = scanner2.Next();
insert(ss.Item1, ss.Item2);
}
insert("$", "$");
Shift-Reduce Conflict! +
States: 8 1
-----I8-----
S -> - S · $/+/-/*//
S -> S ·+ S $/+/-/*//
S -> S ·- S $/+/-/*//
S -> S ·* S $/+/-/*//
S -> S ·/ S $/+/-/*//
-----I0-----
S' -> ·S $
S -> ·S + S $/+/-/*//
S -> ·S - S $/+/-/*//
S -> ·S * S $/+/-/*//
S -> ·S / S $/+/-/*//
S -> ·- S $/+/-/*//
S -> ·num $/+/-/*//
Shift-Reduce Conflict! -
States: 8 1
-----I8-----
S -> - S · $/+/-/*//
S -> S ·+ S $/+/-/*//
S -> S ·- S $/+/-/*//
S -> S ·* S $/+/-/*//
S -> S ·/ S $/+/-/*//
-----I1-----
S' -> S · $
S -> S ·+ S $/+/-/*//
S -> S ·- S $/+/-/*//
S -> S ·* S $/+/-/*//
S -> S ·/ S $/+/-/*//
Shift-Reduce Conflict! *
States: 8 1
-----I8-----
S -> - S · $/+/-/*//
S -> S ·+ S $/+/-/*//
S -> S ·- S $/+/-/*//
S -> S ·* S $/+/-/*//
S -> S ·/ S $/+/-/*//
-----I2-----
S -> - ·S $/+/-/*//
S -> ·S + S $/+/-/*//
S -> ·S - S $/+/-/*//
S -> ·S * S $/+/-/*//
S -> ·S / S $/+/-/*//
S -> ·- S $/+/-/*//
S -> ·num $/+/-/*//
Shift-Reduce Conflict! /
States: 8 1
-----I8-----
S -> - S · $/+/-/*//
S -> S ·+ S $/+/-/*//
S -> S ·- S $/+/-/*//
S -> S ·* S $/+/-/*//
S -> S ·/ S $/+/-/*//
-----I3-----
S -> num · $/+/-/*//
Shift-Reduce Conflict! +
States: 9 1
-----I9-----
S -> S + S · $/+/-/*//
S -> S ·+ S $/+/-/*//
S -> S ·- S $/+/-/*//
S -> S ·* S $/+/-/*//
S -> S ·/ S $/+/-/*//
-----I0-----
S' -> ·S $
S -> ·S + S $/+/-/*//
S -> ·S - S $/+/-/*//
S -> ·S * S $/+/-/*//
S -> ·S / S $/+/-/*//
S -> ·- S $/+/-/*//
S -> ·num $/+/-/*//
Shift-Reduce Conflict! -
States: 9 1
-----I9-----
S -> S + S · $/+/-/*//
S -> S ·+ S $/+/-/*//
S -> S ·- S $/+/-/*//
S -> S ·* S $/+/-/*//
S -> S ·/ S $/+/-/*//
-----I1-----
S' -> S · $
S -> S ·+ S $/+/-/*//
S -> S ·- S $/+/-/*//
S -> S ·* S $/+/-/*//
S -> S ·/ S $/+/-/*//
Shift-Reduce Conflict! *
States: 9 1
-----I9-----
S -> S + S · $/+/-/*//
S -> S ·+ S $/+/-/*//
S -> S ·- S $/+/-/*//
S -> S ·* S $/+/-/*//
S -> S ·/ S $/+/-/*//
-----I2-----
S -> - ·S $/+/-/*//
S -> ·S + S $/+/-/*//
S -> ·S - S $/+/-/*//
S -> ·S * S $/+/-/*//
S -> ·S / S $/+/-/*//
S -> ·- S $/+/-/*//
S -> ·num $/+/-/*//
Shift-Reduce Conflict! /
States: 9 1
-----I9-----
S -> S + S · $/+/-/*//
S -> S ·+ S $/+/-/*//
S -> S ·- S $/+/-/*//
S -> S ·* S $/+/-/*//
S -> S ·/ S $/+/-/*//
-----I3-----
S -> num · $/+/-/*//
Shift-Reduce Conflict! +
States: 10 1
-----I10-----
S -> S - S · $/+/-/*//
S -> S ·+ S $/+/-/*//
S -> S ·- S $/+/-/*//
S -> S ·* S $/+/-/*//
S -> S ·/ S $/+/-/*//
-----I0-----
S' -> ·S $
S -> ·S + S $/+/-/*//
S -> ·S - S $/+/-/*//
S -> ·S * S $/+/-/*//
S -> ·S / S $/+/-/*//
S -> ·- S $/+/-/*//
S -> ·num $/+/-/*//
Shift-Reduce Conflict! -
States: 10 1
-----I10-----
S -> S - S · $/+/-/*//
S -> S ·+ S $/+/-/*//
S -> S ·- S $/+/-/*//
S -> S ·* S $/+/-/*//
S -> S ·/ S $/+/-/*//
-----I1-----
S' -> S · $
S -> S ·+ S $/+/-/*//
S -> S ·- S $/+/-/*//
S -> S ·* S $/+/-/*//
S -> S ·/ S $/+/-/*//
Shift-Reduce Conflict! *
States: 10 1
-----I10-----
S -> S - S · $/+/-/*//
S -> S ·+ S $/+/-/*//
S -> S ·- S $/+/-/*//
S -> S ·* S $/+/-/*//
S -> S ·/ S $/+/-/*//
-----I2-----
S -> - ·S $/+/-/*//
S -> ·S + S $/+/-/*//
S -> ·S - S $/+/-/*//
S -> ·S * S $/+/-/*//
S -> ·S / S $/+/-/*//
S -> ·- S $/+/-/*//
S -> ·num $/+/-/*//
Shift-Reduce Conflict! /
States: 10 1
-----I10-----
S -> S - S · $/+/-/*//
S -> S ·+ S $/+/-/*//
S -> S ·- S $/+/-/*//
S -> S ·* S $/+/-/*//
S -> S ·/ S $/+/-/*//
-----I3-----
S -> num · $/+/-/*//
Shift-Reduce Conflict! +
States: 11 1
-----I11-----
S -> S * S · $/+/-/*//
S -> S ·+ S $/+/-/*//
S -> S ·- S $/+/-/*//
S -> S ·* S $/+/-/*//
S -> S ·/ S $/+/-/*//
-----I0-----
S' -> ·S $
S -> ·S + S $/+/-/*//
S -> ·S - S $/+/-/*//
S -> ·S * S $/+/-/*//
S -> ·S / S $/+/-/*//
S -> ·- S $/+/-/*//
S -> ·num $/+/-/*//
Shift-Reduce Conflict! -
States: 11 1
-----I11-----
S -> S * S · $/+/-/*//
S -> S ·+ S $/+/-/*//
S -> S ·- S $/+/-/*//
S -> S ·* S $/+/-/*//
S -> S ·/ S $/+/-/*//
-----I1-----
S' -> S · $
S -> S ·+ S $/+/-/*//
S -> S ·- S $/+/-/*//
S -> S ·* S $/+/-/*//
S -> S ·/ S $/+/-/*//
Shift-Reduce Conflict! *
States: 11 1
-----I11-----
S -> S * S · $/+/-/*//
S -> S ·+ S $/+/-/*//
S -> S ·- S $/+/-/*//
S -> S ·* S $/+/-/*//
S -> S ·/ S $/+/-/*//
-----I2-----
S -> - ·S $/+/-/*//
S -> ·S + S $/+/-/*//
S -> ·S - S $/+/-/*//
S -> ·S * S $/+/-/*//
S -> ·S / S $/+/-/*//
S -> ·- S $/+/-/*//
S -> ·num $/+/-/*//
Shift-Reduce Conflict! /
States: 11 1
-----I11-----
S -> S * S · $/+/-/*//
S -> S ·+ S $/+/-/*//
S -> S ·- S $/+/-/*//
S -> S ·* S $/+/-/*//
S -> S ·/ S $/+/-/*//
-----I3-----
S -> num · $/+/-/*//
Shift-Reduce Conflict! +
States: 12 1
-----I12-----
S -> S / S · $/+/-/*//
S -> S ·+ S $/+/-/*//
S -> S ·- S $/+/-/*//
S -> S ·* S $/+/-/*//
S -> S ·/ S $/+/-/*//
-----I0-----
S' -> ·S $
S -> ·S + S $/+/-/*//
S -> ·S - S $/+/-/*//
S -> ·S * S $/+/-/*//
S -> ·S / S $/+/-/*//
S -> ·- S $/+/-/*//
S -> ·num $/+/-/*//
Shift-Reduce Conflict! -
States: 12 1
-----I12-----
S -> S / S · $/+/-/*//
S -> S ·+ S $/+/-/*//
S -> S ·- S $/+/-/*//
S -> S ·* S $/+/-/*//
S -> S ·/ S $/+/-/*//
-----I1-----
S' -> S · $
S -> S ·+ S $/+/-/*//
S -> S ·- S $/+/-/*//
S -> S ·* S $/+/-/*//
S -> S ·/ S $/+/-/*//
Shift-Reduce Conflict! *
States: 12 1
-----I12-----
S -> S / S · $/+/-/*//
S -> S ·+ S $/+/-/*//
S -> S ·- S $/+/-/*//
S -> S ·* S $/+/-/*//
S -> S ·/ S $/+/-/*//
-----I2-----
S -> - ·S $/+/-/*//
S -> ·S + S $/+/-/*//
S -> ·S - S $/+/-/*//
S -> ·S * S $/+/-/*//
S -> ·S / S $/+/-/*//
S -> ·- S $/+/-/*//
S -> ·num $/+/-/*//
Shift-Reduce Conflict! /
States: 12 1
-----I12-----
S -> S / S · $/+/-/*//
S -> S ·+ S $/+/-/*//
S -> S ·- S $/+/-/*//
S -> S ·* S $/+/-/*//
S -> S ·/ S $/+/-/*//
-----I3-----
S -> num · $/+/-/*//
--------------------------------------------------------
0 3
0 1
S => num
S => 2
0 1 4
0 1 4 2
0 1 4 2 2
0 1 4 2 2 3
0 1 4 2 2 8
S => num
S => 6
0 1 4 2 8
S => - S
S => - 6
0 1 4 9
S => - S
S => - -6
0 1 4 9 6
0 1 4 9 6 3
0 1 4 9 6 11
S => num
S => 4
0 1 4 9
S => S * S
S => --6 * 4
0 1
S => S + S
S => 2 + --6*4
0 1
var gen = new ParserGenerator();
// Non-Terminals
var exp = gen.CreateNewProduction("exp", false);
var term = gen.CreateNewProduction("term", false);
var factor = gen.CreateNewProduction("factor", false);
var func = gen.CreateNewProduction("func", false);
var arguments = gen.CreateNewProduction("args", false);
var args_left = gen.CreateNewProduction("args_left", false);
// Terminals
var plus = gen.CreateNewProduction("plus"); // +
var minus = gen.CreateNewProduction("minus"); // -
var multiple = gen.CreateNewProduction("multiple"); // *
var divide = gen.CreateNewProduction("divide"); // /
var id = gen.CreateNewProduction("id"); // [_$a-zA-Z][_$a-zA-Z0-9]*
var op_open = gen.CreateNewProduction("op_open"); // (
var op_close = gen.CreateNewProduction("op_close"); // )
var num = gen.CreateNewProduction("num"); // [0-9]+
var split = gen.CreateNewProduction("split"); // ,
exp |= exp + plus + term;
exp |= exp + minus + term;
exp |= term;
term |= term + multiple + factor;
term |= term + divide + factor;
term |= factor;
factor |= op_open + exp + op_close;
factor |= num;
factor |= id;
factor |= func;
func |= id + op_open + arguments + op_close;
arguments |= id;
arguments |= arguments + split + id;
arguments |= ParserGenerator.EmptyString;
gen.PushStarts(exp);
gen.Generate();
gen.PrintStates();
var slr = gen.CreateShiftReduceParserInstance();
// 2*4+5$
Action<string, string> insert = (string x, string y) =>
{
slr.Insert(x, y);
while (slr.Reduce())
{
var l = slr.LatestReduce();
Console.Instance.Write(l.Produnction.PadLeft(8) + " => ");
Console.Instance.WriteLine(string.Join(" ", l.Childs.Select(z => z.Produnction)));
Console.Instance.Write(l.Produnction.PadLeft(8) + " => ");
Console.Instance.WriteLine(string.Join(" ", l.Childs.Select(z => z.Contents)));
slr.Insert(x, y);
}
};
var sg2 = new ScannerGenerator();
sg2.PushRule("", "[\\r\\n ]");
sg2.PushRule("plus", "\\+");
sg2.PushRule("minus", "-");
sg2.PushRule("multiple", "\\*");
sg2.PushRule("divide", "\\/");
sg2.PushRule("op_open", "\\(");
sg2.PushRule("op_close", "\\)");
sg2.PushRule("split", ",");
sg2.PushRule("id", "[a-z][a-z0-9]*");
sg2.PushRule("num", "[0-9]+");
sg2.Generate();
sg2.CreateScannerInstance();
var scanner2 = sg2.CreateScannerInstance();
scanner2.AllocateTarget("2+6*(6+4*7-2)+sin(a,b)+cos()*pi");
while (scanner2.Valid())
{
var ss = scanner2.Next();
insert(ss.Item1,ss.Item2);
}
insert("$", "$");
factor => num
factor => 2
term => factor
term => 2
exp => term
exp => 2
factor => num
factor => 6
term => factor
term => 6
factor => num
factor => 6
term => factor
term => 6
exp => term
exp => 6
factor => num
factor => 4
term => factor
term => 4
factor => num
factor => 7
term => term multiple factor
term => 4 * 7
exp => exp plus term
exp => 6 + 4*7
factor => num
factor => 2
term => factor
term => 2
exp => exp minus term
exp => 6+4*7 - 2
factor => op_open exp op_close
factor => ( 6+4*7-2 )
term => term multiple factor
term => 6 * (6+4*7-2)
exp => exp plus term
exp => 2 + 6*(6+4*7-2)
args => id
args => a
args => args split id
args => a , b
args => args split id
args => a,b , c
args => args split id
args => a,b,c , d
func => id op_open args op_close
func => sin ( a,b,c,d )
factor => func
factor => sin(a,b,c,d)
term => factor
term => sin(a,b,c,d)
exp => exp plus term
exp => 2+6*(6+4*7-2) + sin(a,b,c,d)
func => id op_open op_close
func => cos ( )
factor => func
factor => cos()
term => factor
term => cos()
factor => id
factor => pi
term => term multiple factor
term => cos() * pi
exp => exp plus term
exp => 2+6*(6+4*7-2)+sin(a,b,c,d) + cos()*pi