]> git.kianting.info Git - clo/blob - src/index.ts
rewrite parser
[clo] / src / index.ts
1 var fs = require('fs');
2 import jsTokens from "js-tokens";
3 import * as util from 'util';
4 import * as p from 'typescript-parsec';
5 import { Token } from 'typescript-parsec';
6 /**
7 *
8 * # REPRESENTATION
9 */
10 /**
11 * convert a `tkTree` AST to S-expr string
12 * @param t the `tkTree`
13 * @returns S-expr String
14 */
15 export function tkTreeToSExp(t: tkTree): string{
16 var str = "";
17
18 if (Array.isArray(t)){
19 let strArray = t.map((x)=>tkTreeToSExp(x));
20 str = "(" + strArray.join(" ") + ")";
21 }else{
22 if (t=== undefined){
23 str = "%undefined"
24 }else{
25 str = t;
26 }
27 }
28
29 return str;
30 }
31
32 /**inspect the inner of the representation. */
33 let repr = (x : any)=>{return util.inspect(x, {depth: null})};
34 /**
35 *
36 * # TYPES
37 */
38
39
40 type tkTree = string | tkTree[];
41
42 enum TokenKind {
43 Seperator,
44 Semicolon,
45 Number,
46 Op,
47 ExprMark,
48 Paren,
49 SpaceNL,
50 Id,
51 Str,
52 }
53
54 /**
55 * Parsing
56 */
57 const lexer = p.buildLexer([
58 [true, /^\d+(\.\d+)?/g, TokenKind.Number],
59 [true, /^\;/g, TokenKind.Semicolon],
60 [true, /^[-][-][-]/g, TokenKind.Seperator],
61 [true, /^[\+\-\*\/\&\|\!\^\<\>\~\=\?]+/g, TokenKind.Op],
62 [true, /^\@+/g, TokenKind.ExprMark],
63 [true, /^[()\[\]{}]/g, TokenKind.Paren],
64 [true, /^["]([\"]|[\\].)*["]/g, TokenKind.Str],
65 [true, /^[']([\']|[\\].)*[']/g, TokenKind.Str],
66 [true, /^[()\[\]{}]/g, TokenKind.Paren],
67 [true, /^[^\s\n\t\r;]+/g, TokenKind.Id],
68 [false, /^(\s|\n|\r|\t)+/g, TokenKind.SpaceNL]
69 ]);
70
71 /**
72 *
73 * # TEST
74 */
75 const inputTxt=
76 `import ast;
77 ---
78 122`;
79
80
81 const PROG = p.rule<TokenKind, tkTree>();
82 const UNIT = p.rule<TokenKind, tkTree>();
83 const IMPORTS = p.rule<TokenKind, tkTree>();
84 const SEMICOLON = p.rule<TokenKind, tkTree>();
85
86
87 let doubleMinus = { type: 'Punctuator', value: '--' };
88 let doubleMinus2 = p.str('--');
89 const TERM = p.rule<TokenKind, tkTree>();
90
91 function applyUnit(value: Token<TokenKind.Number>): tkTree{
92 return value.text;
93 }
94
95 function applySemiColon(value: Token<TokenKind.Semicolon>): tkTree{
96 return value.text;
97 }
98
99 function applyParts(first: tkTree,
100 second: [Token<TokenKind>, tkTree]):tkTree {
101 return ["%clo", first , second[1]];
102 }
103
104
105
106
107 function applyImports(input: [Token<TokenKind>,Token<TokenKind>[], tkTree]):tkTree{
108 let importTail = input[1].map(x=>x.text);
109 return ["import"].concat(importTail);
110 };
111
112 /**
113 * PROG : IMPORTS '---' UNIT;
114 */
115 PROG.setPattern(
116 p.lrec_sc(IMPORTS, p.seq(p.str('---'), UNIT), applyParts)
117
118 )
119
120 /**
121 * PROG : 'import' Id* SEMICOLON;
122 */
123 IMPORTS.setPattern(
124 p.apply(p.seq(p.str('import'), p.rep_sc(p.tok(TokenKind.Id)), SEMICOLON) , applyImports)
125 );
126
127 /**
128 * SEMICOLON : ';';
129 */
130 SEMICOLON.setPattern(
131 p.apply(p.tok(TokenKind.Semicolon), applySemiColon)
132 );
133
134 /**
135 * UNIT : Number;
136 */
137 UNIT.setPattern(
138 p.apply(p.tok(TokenKind.Number), applyUnit)
139 );
140
141 let tree = p.expectSingleResult(p.expectEOF(PROG.parse(lexer.parse(inputTxt))));
142
143
144
145 console.log("RESULT="+tkTreeToSExp(tree));