tscc-compiler
Version:
An LALR(1) compiler compiler written in Typescript
270 lines (257 loc) • 13.7 kB
HTML
<html>
<head>
<title>tscc-compiler demo</title>
<meta charset="UTF-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<link href="css/fontawesome-all.min.css" rel="stylesheet">
<!-- 咸鱼面筋 -->
<!-- 咸鱼免进 -->
<!-- 闲人免进 -->
<link href="css/main.css" rel="stylesheet" media="screen">
<link rel="stylesheet" href="css/codemirror.css">
</head>
<body>
<div class="mortal-overlay" id="help-container" style="display: none;">
<div class="help-panel">
<a href="javascript:void(0);" class="fa-btn close-btn help-close-btn" data-target="#help-container">
<span class="fa fa-times"></span>
</a>
<h1>Help</h1>
<p>
This site is a demo for tscc-compiler, an LALR(1) parser generator written in typescript. The project
is hosted on <a href="https://github.com/Hadron67/tscc-compiler">github</a>, documentation can be found
at <a href="https://github.com/Hadron67/tscc-compiler/wiki">wiki for tscc-compiler</a>. It has been
published on <a href="https://www.npmjs.com/package/tscc-compiler"></a>npm, you can install tscc-compiler
using the command
</p>
<div class="code-block source">npm install tscc-compiler -g</div>
<p>
You can input any grammar file you like, or select a demo file by clicking <span class="fa fa-file-code"></span>.
After you've done that, press <span class="fa fa-gavel"></span> to compile. The compilation includes generating tables and
the parser's source code, and "compile" the code using function constructor of Javascript, with two arguments:
<span class="source">console</span> and <span class="source">input</span>. The former is an object with the method
<span class="source">log</span>, which prints a specified string into the "Output" tab of the footer panel; The latter
is a string whose value is the value of the text area in the "Input" tab. You can access these two variables
in the inline code blocks or epilogue in the grammar file.
</p>
<p>
Errors and warnings will be printed in the "Messages" tab of the footer panel if they occur. When input is accepted, you can
either run the generated code by clicking <span class="fa fa-play"></span>, or print parse table and DFA tables by pressing
<span class="fa fa-desktop"></span> and select what you want to print. Tables will be printed in the "Output" tab.
</p>
<h2>Credits</h2>
<p>
This site is hosted on Github Pages, together with the following libraries:
<ul>
<li>jquery v3.1.1</li>
<li>Font Awesome Free 5.0.8</li>
<li>RequireJS 2.3.5</li>
</ul>
</p>
<h2>License</h2>
<p>
The same as tscc-compiler, this site is licensed under MIT.
</p>
</div>
</div>
<div class="top-container">
<div class="titlebar">
<div class="titlebar-header">
<a class="titlebar-title titlebar-item" href="#">TSCC Demo</a>
<div class="cbtn-container">
<button class="collapse-btn" data-collapse="#titlebar-collapse">
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
</div>
</div>
<div class="titlebar-collapse collapsed" id="titlebar-collapse">
<ul class="titlebar-list">
<li>
<div class="titlebar-item titlebar-list-item titlebar-button" id="btn-compile" title="Compile">
<span class="fa fa-gavel"></span>
</div>
</li>
<li>
<div class="titlebar-item titlebar-list-item titlebar-button" id="btn-run" title="Run">
<span class="fa fa-play"></span>
</div>
</li>
<li class="dropdown" data-dropdown="#show-list">
<div class="titlebar-item titlebar-list-item titlebar-button" title="Show...">
<span class="fa fa-desktop"></span>
</div>
<ul class="dropdown-menu hidden" id="show-list">
<li><a href="javascript:void(0);" class="menu-btn" id="btn-parse-table">Parse table</a></li>
<li><a href="javascript:void(0);" class="menu-btn" id="btn-full-table">Full parse table</a></li>
<li><a href="javascript:void(0);" class="menu-btn" id="btn-dfa-tables">DFA tables</a></li>
</ul>
</li>
<li class="dropdown" data-dropdown="#demo-files">
<div class="titlebar-item titlebar-list-item titlebar-button" title="Open demo file...">
<span class="fa fa-file-code"></span>
</div>
<ul class="dropdown-menu hidden" id="demo-files"></ul>
</li>
<li>
<div class="titlebar-item titlebar-list-item titlebar-button toggle-btn" title="Help" data-target="#help-container">
<span class="fa fa-question-circle"></span>
</div>
</li>
</ul>
</div>
</div>
<div class="editor-container" id="editor-container" style="flex-grow: 1;"></div>
<div class="footer-panel" id="footer-panel" style="display: none; flex-grow: 0.5;">
<div class="resizer-col" id="footer-resizer">
<span class="icon-resizer-bar"></span>
<span class="icon-resizer-bar"></span>
<span class="icon-resizer-bar"></span>
</div>
<div class="footer-head">
<a class="fa-btn btn-left btn-clear-msg" href="javascript:void(0);" title="Clear messages">
<span class="fa fa-trash-alt"></span>
</a>
<a class="fa-btn btn-left btn-clear-output" href="javascript:void(0);" title="Clear output">
<span class="fa fa-trash-alt"></span>
</a>
<a class="fa-btn btn-right btn-close" href="javascript:void(0);" title="Hide footer panel">
<span class="fa fa-times"></span>
</a>
</div>
<div class="content-container" id="message-panel">
<div class="footer-content" id="message-content"></div>
</div>
<div class="content-container" id="output-panel">
<div class="footer-content" id="output-content"></div>
</div>
<div class="content-container" id="input-panel">
<div class="input-panel-container">
<div class="input-panel-head">
<span class="input-panel-title">The following input can be accessed through variable 'input':</span>
</div>
<textarea class="parse-input" id="parse-input" spellcheck="false"></textarea>
</div>
</div>
</div>
<div class="footer-buttons">
<a class="footer-button fbtn-messages" href="javascript:void(0);" data-show="messages">Messages</a>
<a class="footer-button fbtn-output" href="javascript:void(0);" data-show="output">Output</a>
<a class="footer-button fbtn-input" href="javascript:void(0);" data-show="input">Input</a>
</div>
</div>
<!-- Github ribbon -->
<a class="github-ribbon" href="https://github.com/Hadron67/tscc-compiler">
<img style="position: fixed; top: 0; right: 0; border: 0; z-index: 1001;" src="https://s3.amazonaws.com/github/ribbons/forkme_right_orange_ff7600.png" alt="Fork me on GitHub">
</a>
</body>
<script type="text/tscc" id="tscc-hint" data-indent="2">
// Input your code here.
// or, you can open a demo file by clicking the 4th button on the title bar.
// When your input is done, press compile button, which looks like a gavel.
// If no error occurs, you can then either run the code by clicking the 2th button,
// or print the parse table or DFA tables through the 3th button.
// For more information, press help.
</script>
<script type="text/tscc" class="tscc-demo-script" data-fname="calculator.y" data-indent="2">
// This grammar implements a simple calculator
%lex {
DIGIT = < ['0'-'9'] >
EXP_TRAILER = < ['e', 'E']['+', '-']? <DIGIT>+ >
// white space
< ([' ', '\t', '\r', '\n'] | '\r\n')+ >: [='']
// numbers. Decimals and exponentials are allowed
< NUM: ( <DIGIT>+ ('.' <DIGIT>*)? | '.' <DIGIT>+ ) <EXP_TRAILER>? >: { $$ = Number($token.val); }
// operators
< PLUS: '+' >
< MINUS: '-' >
< TIMES: '*' >
< EXP: '**' >
< DIVIDE: '/' >
// brackets
< OPEN_BRACE: '(' >
< CLOSE_BRACE: ')' >
}
// define operators' associativity and priority
%left '+' '-'
%left '*' '/'
%right '**'
// should be javascript, or test run will fail
%output 'javascript'
%%
start: expr { console.log('result: ' + $$); };
expr:
a = expr '+' b = expr { $$ = a + b; }
| a = expr '-' b = expr { $$ = a - b; }
| a = expr '*' b = expr { $$ = a * b; }
| a = expr '/' b = expr { $$ = a / b; }
| a = expr '**' b = expr { $$ = Math.exp(a, b); }
| '(' a = expr ')' { $$ = a; }
| <NUM>
;
%%
var parser = createParser();
parser.init();
// error handling
parser.on('syntaxerror', function(token, state){
// token may be an ERROR token, which indicates a lexical error.
if(token.id === TokenKind.ERROR){
console.log('unexpected illegal token ' + token.toString());
}
else {
console.log('unexpected token ' + token.toString() + ', expecting:\n');
for(var i = 0, _a = getExpectedTokens(state); i < _a.length; i++){
console.log(' ' + tokenToString(_a[i]) + '...');
}
}
// stop the parser
parser.halt();
});
parser.parse(input);
</script>
<script type="text/tscc" class="tscc-demo-script" data-fname="json.y" data-indent="2">
%lex {
LETTER = < ['a'-'z', 'A'-'Z', '$', '_'] >
DIGIT = < ['0'-'9'] >
EXP_TRAILER = < ['e', 'E']['+', '-']? <DIGIT>+ >
HEX = < ['0'-'9', 'a'-'f', 'A'-'F'] >
ESCAPE_CHAR = < "\\" (['n', 't', 'b', 'r', 'f', '"', "'", "\\"] | <UNICODE>) >
UNICODE = < ['x', 'u', 'X', 'U'] <HEX>+ >
< ( ['\r', '\n', ' ', '\t'] | '\r\n')+ >: [='']
< STRING:
'"' ( [^'"', '\n', '\\'] | <ESCAPE_CHAR> )* '"'
| "'" ( [^"'", '\n', '\\'] | <ESCAPE_CHAR> )* "'"
>: { $$ = $token.val; $$ = $$.substr(1, $$.length - 2); }
< NAME: <LETTER> (<DIGIT>|<LETTER>)* >: { $$ = $token.val; }
< NUM: ( <DIGIT>+ ('.' <DIGIT>*)? | '.' <DIGIT>+ ) <EXP_TRAILER>? >: { $$ = Number($token.val); }
< TRUE: 'true' >
< FALSE: 'false' >
< NULL: 'null' >
< OPEN_CUBIC_B: '[' >
< CLOSE_CUBIC_B: ']' >
< OPEN_CURLY_B: '{' >
< CLOSE_CURLY_B: '}' >
< COMMA: ',' >
< COLLON: ':' >
}
%output "javascript"
%%
json: primitives | '[' array ']' | '{' obj '}';
primitives: <NAME> | <STRING> | <NUM> | 'true' | 'false' | 'null';
array: nearray comma | /* empty */;
nearray: nearray ',' json | json;
obj: neobj comma | /* empty */;
neobj: neobj ','oitem | oitem;
oitem: key ':' json;
key: <NAME> | <STRING>;
comma: ',' | /* empty */;
%%
var jsonParser = createParser();
jsonParser.init();
jsonParser.parse(input);
</script>
<script data-main="requirejs.config.js" src="lib/require.js"></script>
</html>