<html>
	<head>
		<meta charset="utf-8">
		<title>LR(1) parser by netcan</title>
		<script src="../node_modules/jquery/dist/jquery.min.js"></script>
		<link href="../node_modules/semantic-ui-css/semantic.min.css" rel="stylesheet">

		<style>
			.node-name {
				font-weight: bolder;
			}
			.underline {
				text-decoration: underline;
			}
			thead, tbody tr {
				display:table;
				width:100%;
				table-layout:fixed;/* even columns width , fix width of table too*/
			}
			tbody {
				display:block;
				max-height:550px;
				overflow-y:scroll;
			}
			thead {
				width: calc( 100% - 1em )/* scrollbar is average 1em/16px width, remove it from thead width */
			}
		</style>
	</head>
	<body>

		<a href="https://github.com/netcan/compilingTheory" target="_blank">
			<img style="position: fixed; top: 0; right: 0; border: 0; z-index: 901" src="../fork.png" alt="Fork me on GitHub" data-canonical-src="https://s3.amazonaws.com/github/ribbons/forkme_right_gray_6d6d6d.png">
		</a>

		<div class="ui container">
			<h1 class="header">LR(1) parser by netcan</h1>

			<!-- DFA图 -->
			<div class="ui stacked segment" id="DFA">
				<h4 class="ui horizontal divider header">
					DFA Graph
				</h4>
				<div class="ui inverted dimmer">
					<div class="ui text loader errorMsg"></div>
				</div>
				<div class="huge ui buttons fluid">
					<button class="ui button" id="graphButton">
						Open DFA Graph on new window
					</button>
					<div class="or"></div>
					<button class="ui positive button" id="graphDownload">
						Download DFA Graph
					</button>
				</div>
				<div id="GraphAll" style="display:none">
				</div>
				<div id="Graph">
				</div>
			</div>

			<div class="ui two column doubling stackable grid">
				<!-- 输入串，文法 -->
				<div class="four wide column">
					<div class="ui stacked segment">
						<div class="ui form">
							<div class="field">
								<label for="selectGrammar">测试文法</label>
								<select class="ui dropdown fluid" id="selectGrammar">
								</select>
							</div>
							<div class="field">
								<label for="indata">输入串</label>
								<input type="text" id="indata">
							</div>
							<div class="field">
								<label for="grammar">输入文法</label>
								<textarea id="grammar"></textarea>
							</div>
						</div>
					</div>

					<!-- 文法列表 -->
					<div class="row">
						<div class="ui piled segment">
							<h4 class="ui horizontal divider header">
								Grammar List
							</h4>
							<div class="ui inverted dimmer">
								<div class="ui text loader errorMsg"></div>
							</div>
							<table class="ui selectable striped celled structured table">
								<thead>
									<tr class="center aligned">
										<th class="three wide">ID</th>
										<th>Production</th>
									</tr>
								</thead>
								<tbody id="gmrb">
								</tbody>
							</table>
						</div>
					</div>
				</div>

				<div class="twelve wide column">
					<!-- LR分析表 -->
					<div class="twelve wide column" id="parseTable">
						<div class="ui piled segment">
							<h4 class="ui horizontal divider header">
								Parse Table
							</h4>
							<div class="ui inverted dimmer">
								<div class="ui text loader errorMsg"></div>
							</div>
							<table class="ui selectable striped celled structured table">
								<thead>
									<tr id="pth1" class="center aligned">
									</tr>
									<tr id="pth2" class="center aligned">
									</tr>
								</thead>
								<tbody id="ptb">
								</tbody>
							</table>
						</div>
					</div>

					<div class="row">
						<!-- 分析过程 -->
						<div class="twelve wide column">
							<div class="ui piled segment">
								<h4 class="ui horizontal divider header">
									Parser
								</h4>
								<div class="ui inverted dimmer">
									<div class="ui text loader errorMsg"></div>
								</div>
								<table class="ui stackable striped selectable celled table">
									<thead>
										<tr class="center aligned">
											<th class="one wide">Step</th>
											<th>statusStack</th>
											<th>parseStack</th>
											<th>inStrStack</th>
											<th>action</th>
										</tr>
									</thead>
									<tbody id="parser">
									</tbody>
								</table>
							</div>
						</div>

					</div>
				</div>
			</div>
		</div>
		<script src="../node_modules/semantic-ui-css/semantic.min.js"></script>
		<script src="../node_modules/file-saver/FileSaver.min.js"></script>
		<script src="../node_modules/viz.js/viz.js"></script>
		<script>

			function update(local) {
				var data = $('#grammar').val() + '\n#\n' + $('#indata').val();
				$.ajax({
					url: "LR.php",
					datatype: "json",
					method: "POST",
					data: {"data": data},
					success: function(res, status, jqxhr) {
						$('.ui.dimmer').dimmer('hide');
						console.log(res);
						if(!local) {
							// Gammar list
							var gmrb = '';
							for(var i=0, len=res["Grammar"].length; i<len; ++i)
								gmrb += '<tr class="center aligned">' +
									'<td class="three wide">' + i + '</td>' +
									'<td>' + res["Grammar"][i] + '</td>';
							$('#gmrb').html(gmrb);

							// parse Table
							var pth1 = '<th rowspan="2">Status</th>'+
								'<th colspan='+ res["parseTable"]["Vt"].length +'>ACTION</th>' +
								'<th colspan='+ res["parseTable"]["Vn"].length +'>GOTO</th>';
							var pth2 = '';
							var ptb = '';
							for(var i=0, len=res["parseTable"]["Vt"].length; i<len; ++i)
								pth2 += '<th>' + res["parseTable"]["Vt"][i] + '</th>'
									for(var i=0, len=res["parseTable"]["Vn"].length; i<len; ++i)
										pth2 += '<th>' + res["parseTable"]["Vn"][i] + '</th>';

							for(var i=0, len=res["parseTable"]["Body"].length; i<len; ++i) {
								ptb += '<tr class="center aligned"><td>' + i + '</td>'
									var row = res["parseTable"]["Body"][i];
								for(var j=0, jlen=row.length; j<jlen; ++j)
									ptb += '<td>' + row[j] + '</td>'
										ptb += '</tr>';
							}

							$('#pth1').html(pth1);
							$('#pth2').html(pth2);
							$('#ptb').html(ptb);
						}

						// parser
						var parser = '';
						for(var i=0, len=res["parser"].length; i<len; ++i) {
							var row = res["parser"][i];
							parser += '<tr class="center aligned '+ (row["action"] == "ERROR"?"negative":"") +'">' +
								'<td class="one wide">'+ i +'</td>' +
								'<td>'+ row["statusStack"] +'</td>' +
								'<td>'+ row["parseStack"] +'</td>' +
								'<td>'+ row["inStrStack"] +'</td>' +
								'<td>'+ row["action"] +'</td>' +
								'</tr>';
						}
						$('#parser').html(parser);

						if(!local) {
							// DFA Graph
							var GraphAll = Viz(res['Graph']['All'], {format: "svg"});
							var GraphSimple = Viz(res['Graph']['Simple'], {format: "svg"});
							$('#GraphAll').html(GraphAll);
							$('#Graph').html(GraphSimple);
							window.scrollTo(0, $('#DFA').height() + 35);
						}
					},
					error: function() {
						$('.errorMsg').html('请检查文法是否合法，否则请联系我！谢谢合作。');
						$('.ui.dimmer').dimmer('show');
					}
				});
			}

			$("#indata").on("keyup paste", function() {
				update(true);
			});
			$("#grammar").on("keyup paste", function() {
				update(false);
			});
			$('#graphButton').click(function() {
				var gw = window.open("", "DFA Graph", "width=800,height=600,scrollbars=1");
				gw.document.write($('#GraphAll').html());
				// console.log($('#graphButton').val());
			});
			$('#graphDownload').click(function() {
				var blob = new Blob([$('#GraphAll').html()], {type: "text/plain;charset=utf-8"});
				saveAs(blob, "LR1_DFA_Graph.svg");
			});

			$(document).ready(function() {
				var inStr = ["i*i+i*(i+i)*i-i+i/(i*i)*i",
				"i+i*i",
				"a*(a+a*a)",
				"aaaabbbbaaaabbbb"
				];
				var grammar = ["E->TG\n" +
					"G->+TG|-TG\n" +
					"G->@\n" +
					"T->FS\n" +
					"S->*FS|/FS\n" +
					"S->@\n" +
					"F->(E)\n" +
					"F->i",

					"E->E+T\n" +
					"E->T\n" +
					"T->T*F\n" +
					"T->F\n"+
					"F->(E)\n" +
					"F->i",

					"E->E+E|E*E|(E)|a",

					"S->aBS|bAS|@\n" +
					"A->bAA|a\n" +
					"B->aBB|b\n"
				];

				var opt = '';
				for(var i=0, len=grammar.length; i<len; ++i)
					opt += "<option value="+i+">" + "文法" + i + "</option>";
				$('#selectGrammar').html(opt);
				{ // 初始化文法
					 $('#selectGrammar').val(0);
					 $('#indata').val(inStr[$('#selectGrammar').val()]);
					 $('#grammar').val(grammar[$('#selectGrammar').val()]);
					 update(false);
				}

				$('#selectGrammar').dropdown({allowReselection: true});
				$('#selectGrammar').on('change', function() {
					$('#indata').val(inStr[$('#selectGrammar').val()]);
					$('#grammar').val(grammar[$('#selectGrammar').val()]);
					update(false);
				});
			});
		</script>
	</body>
</html>
