1 var fs
= require('fs');
2 import { argv
, resourceUsage
} from
'node:process';
3 import * as tk from
'./tokenize.js';
4 import * as util from
'util';
5 import { reduceRotation
} from
'pdf-lib';
10 type tkTree
= tkTree
[] | tk
.Token
12 export interface TokenMatcheePair
{
17 export interface MaybeTokensAST
{
18 maybeTokens
: tk
.Maybe
<TokenMatcheePair
>;
24 * match one token type.
26 * it returns a function which test if the type of first token of the `remained` part of
27 * the argument of the function is `typ` , if it's true, update the `TokenMatcheePair` wrapped
28 * in `Some`. Otherwise, it returns `None`.
29 * * @param typ : the type to be test.
30 * @returns the updated `TokenMatcheePair` wrapped in `Some(x)` or `None`.
32 export function m1TType(typ
: tk
.TokenType
):
33 (m
: TokenMatcheePair
) => tk
.Maybe
<TokenMatcheePair
> {
34 return (m
: TokenMatcheePair
) => {
35 if (m
.remained
.length
== 0) {
36 return { _tag
: "None" };
41 const ttbm
= m
.remained
[0];
43 if (ttbm
.type == typ
) {
44 let new_matched
= m
.matched
.concat(ttbm
);
45 let result
: tk
.Some
<TokenMatcheePair
> = {
46 _tag
: "Some", value
: {
48 remained
: m
.remained
.slice(1)
54 return { _tag
: "None" };
59 let toSome
= tk
.toSome
;
60 let thenDo
= tk
.thenDo
;
61 let zeroOrOnceDo
= tk
.zeroOrOnceDo
;
63 let zeroOrMoreDo
= tk
.zeroOrMoreDo
;
66 argv
.forEach((val
, index
) => {
67 console
.log(`${index}=${val}`);
70 let commandInput
= "int a str b"//argv[2];
71 let commandInputTokenized
= tk
.tokenize(commandInput
);
72 let commandInputTokenizedFiltered
= commandInputTokenized
.filter(
73 (x
: tk
.Token
)=>{return x
.type != tk
.TokenType
.SP
&&
74 x
.type != tk
.TokenType
.NL
});
75 console
.log("aaa: "+util
.inspect(commandInputTokenizedFiltered
, { showHidden
: true, depth
: null }));
78 * matchee pair of commandInputTokenized
80 let commandTPair
: TokenMatcheePair
= {matched
:[],
81 remained
: commandInputTokenizedFiltered
};
84 let tInt
= m1TType(tk
.TokenType
.INT
);
85 let tFlo
= m1TType(tk
.TokenType
.FLO
);
86 let tStr
= m1TType(tk
.TokenType
.STR
);
87 let tId
= m1TType(tk
.TokenType
.ID
);
88 let tApos
= m1TType(tk
.TokenType
.APOS
);
91 function tBool (x
: TokenMatcheePair
) :tk
.Maybe
<TokenMatcheePair
> {
92 let text
= x
.remained
[0].text
93 if (text
== "true" || text
== "false"){
94 return thenDo(toSome(x
), m1TType(tk
.TokenType
.ID
));
96 return {_tag
: "None"};
101 * define the right hand side of a grammar
102 * eg. `LHS ::= a + b`
103 * @param process the right hand side processing : eg. `a + b` in `LHS`
104 * @param arrange define the order (0 starting) of the elements of the result.
105 * ast. : eg. `a + c` is `1 0 2` `(+ a c)`
106 * @returns the processed ast.
108 function gramRHS (process
: Function, arrange
: number[]){
109 return (m
: TokenMatcheePair
)=>{
111 let middle
: tk
.Maybe
<TokenMatcheePair
> = process(m
);
113 console
.log("Middle"+util
.inspect(middle
, { showHidden
: true, depth
: null }));
115 if (middle
._tag
== "None"){
119 let matched
= middle
.value
.matched
;
120 let arrLength
= arrange
.length
;
121 let returnRrray
: tkTree
[] = Array(arrange
.length
);
123 arrange
.forEach((val
, index
) => {
124 returnRrray
[arrange
[index
]] = matched
[index
];
127 let matchedTmp1Length
= matched
.length
-arrLength
;
128 console
.log(matchedTmp1Length
);
129 var matchedTmp1
: tkTree
[] = matched
130 .slice(0,matchedTmp1Length
);
132 console
.log("matchedTmp1"+util
.inspect(matchedTmp1
, { showHidden
: true, depth
: null }));
133 console
.log("returnRrray"+util
.inspect(returnRrray
, { showHidden
: true, depth
: null }));
134 matchedTmp1
.push(returnRrray
);
137 let result
: tk
.Some
<TokenMatcheePair
> = {_tag
:"Some",
138 value
: {matched
: matchedTmp1
,
139 remained
: middle
.value
.remained
}};
148 var typeABS
= (x
: TokenMatcheePair
)=>
150 var result
= thenDo(thenDo(toSome(x
),tApos
),tId
);
151 if (result
._tag
== "Some" && "text" in result
.value
.matched
[1]){
152 var realToken
: tk
.Token
= result
.value
.matched
[1];
153 realToken
.text
= "'"+realToken
.text
;
154 result
.value
.matched
= [realToken
];
160 * TypeId ::= typeABS | ID
162 var typeName
= (x
: TokenMatcheePair
)=>
164 return thenDo(toSome(x
), orDo(typeABS
, tId
));
168 * CONST ::= INT | STR | FLO | BOOL
172 * TODO: 要用 debugger 檢查分析問題
174 var constParser
= gramRHS((x
: TokenMatcheePair
)=>
175 {return thenDo(toSome(x
),orDo(orDo(orDo(tInt
,tFlo
),tStr
),tBool
))}, [0]);
180 var astTree
: tkTree
= [];
183 * TYPE_PAIR ::= TYP_ID ID
185 var typePair
= (x
: MaybeTokensAST
)=>
189 let a
= thenDo(thenDo(x
.maybeTokens
, typeName
), tId
);
190 if (a
._tag
== "Some"){
191 let matched
= a
.value
.matched
;
192 let slice
= matched
.slice(matched
.length
-2);
193 console
.log("slice"+slice
);
195 let b
: MaybeTokensAST
= {maybeTokens
: a
, ast
: slice
};
199 let b
: MaybeTokensAST
= {maybeTokens
: a
, ast
: []};
205 * function's arguments
206 * FN_ARGS = TYPE_PAIR ("," TYPE_PAIR)+
209 var fnArgs
= (x
: TokenMatcheePair
)=>
211 let wrapper
: MaybeTokensAST
= {maybeTokens
: toSome(x
), ast
: []};
212 let a
= typePair(wrapper
);
213 console
.log("AAAAA"+util
.inspect(a
, { showHidden
: true, depth
: null }));
214 let abanibi
= typePair(a
);
215 console
.log("ABNB"+util
.inspect(abanibi
, { showHidden
: true, depth
: null }));
218 return {maybeTokens
: abanibi
.maybeTokens
, ast
: [a
.ast
, abanibi
.ast
]};
222 let tree
= fnArgs(commandTPair
);
223 console
.log("CHRANN"+util
.inspect(tree
, { showHidden
: true, depth
: null }));