Compare commits
3 Commits
c86334621d
...
e955ec672b
| Author | SHA1 | Date | |
|---|---|---|---|
| e955ec672b | |||
| add7307893 | |||
| cb19f33fef |
15
.crossnote/config.js
Normal file
15
.crossnote/config.js
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
({
|
||||||
|
katexConfig: {
|
||||||
|
"macros": {}
|
||||||
|
},
|
||||||
|
|
||||||
|
mathjaxConfig: {
|
||||||
|
"tex": {},
|
||||||
|
"options": {},
|
||||||
|
"loader": {}
|
||||||
|
},
|
||||||
|
|
||||||
|
mermaidConfig: {
|
||||||
|
"startOnLoad": false
|
||||||
|
},
|
||||||
|
})
|
||||||
6
.crossnote/head.html
Normal file
6
.crossnote/head.html
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
<!-- The content below will be included at the end of the <head> element. -->
|
||||||
|
<script type="text/javascript">
|
||||||
|
document.addEventListener("DOMContentLoaded", function () {
|
||||||
|
// your code here
|
||||||
|
});
|
||||||
|
</script>
|
||||||
12
.crossnote/parser.js
Normal file
12
.crossnote/parser.js
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
({
|
||||||
|
// Please visit the URL below for more information:
|
||||||
|
// https://shd101wyy.github.io/markdown-preview-enhanced/#/extend-parser
|
||||||
|
|
||||||
|
onWillParseMarkdown: async function(markdown) {
|
||||||
|
return markdown;
|
||||||
|
},
|
||||||
|
|
||||||
|
onDidParseMarkdown: async function(html) {
|
||||||
|
return html;
|
||||||
|
},
|
||||||
|
})
|
||||||
16
.crossnote/style.less
Normal file
16
.crossnote/style.less
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
|
||||||
|
/* Please visit the URL below for more information: */
|
||||||
|
/* https://shd101wyy.github.io/markdown-preview-enhanced/#/customize-css */
|
||||||
|
|
||||||
|
.markdown-preview.markdown-preview {
|
||||||
|
// modify your style here
|
||||||
|
.mermaid {
|
||||||
|
background-color: white;
|
||||||
|
font-family: NanumGothic;
|
||||||
|
}
|
||||||
|
font-size: 11pt;
|
||||||
|
font-family: NanumMyeongjo;
|
||||||
|
.language-scanres {
|
||||||
|
font-size: 6pt;
|
||||||
|
}
|
||||||
|
}
|
||||||
4
.gitignore
vendored
4
.gitignore
vendored
@@ -2,4 +2,6 @@
|
|||||||
.vscode
|
.vscode
|
||||||
|
|
||||||
*.o
|
*.o
|
||||||
*.yy.c
|
*.yy.c
|
||||||
|
|
||||||
|
node_modules
|
||||||
28
build.js
Normal file
28
build.js
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
const { Notebook } = require("crossnote");
|
||||||
|
const path = require("path");
|
||||||
|
const fs = require("fs");
|
||||||
|
|
||||||
|
async function main() {
|
||||||
|
const notebook = await Notebook.init(
|
||||||
|
{
|
||||||
|
notebookPath: path.resolve(''),
|
||||||
|
config: {
|
||||||
|
previewTheme: 'github-light.css',
|
||||||
|
mathRenderingOption: 'KaTeX',
|
||||||
|
codeBlockTheme: 'github.css',
|
||||||
|
printBackground: true,
|
||||||
|
enableScriptExecution: true,
|
||||||
|
|
||||||
|
chromePath: '/usr/bin/google-chrome-stable',
|
||||||
|
},
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
const file = "./src/2024062806.md";
|
||||||
|
|
||||||
|
const engine = notebook.getNoteMarkdownEngine(file);
|
||||||
|
|
||||||
|
await engine.chromeExport( {runAllCodeChunks: true});
|
||||||
|
}
|
||||||
|
|
||||||
|
main();
|
||||||
6933
package-lock.json
generated
Normal file
6933
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
5
package.json
Normal file
5
package.json
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
{
|
||||||
|
"dependencies": {
|
||||||
|
"crossnote": "^0.9.15"
|
||||||
|
}
|
||||||
|
}
|
||||||
379
src/2024062806.md
Normal file
379
src/2024062806.md
Normal file
@@ -0,0 +1,379 @@
|
|||||||
|
# Lexical Analysis(Scanner) Report
|
||||||
|
|
||||||
|
* 주하진, 2024062806
|
||||||
|
|
||||||
|
## Compilation Environment and Method
|
||||||
|
|
||||||
|
주어진 `Makefile`을 이용하여 C파일을 컴파일함.
|
||||||
|
C파일은 `gcc`를 이용해서 컴파일한다.
|
||||||
|
`Makefile`에서 산출되는 실행파일은 `cminus_cimpl`과 `cminus_lex`가 있으며 각각 `main.c util.c scan.c`, `main.c util.c lex.yy.c`를 컴파일한 오브젝트 파일을 필요로 한다.
|
||||||
|
|
||||||
|
`lex.yy.c`는 `flex -o lex.yy.c cminus.l`을 통해 생성된다.
|
||||||
|
|
||||||
|
## C-Minus Language
|
||||||
|
|
||||||
|
C-Minus에서 필요한 토큰타입변수와 그에 대한 설명은 다음과 같다.
|
||||||
|
|
||||||
|
**특수 토큰**
|
||||||
|
|
||||||
|
* `ENDFILE`: 파일끝
|
||||||
|
* `ERROR`: 에러
|
||||||
|
|
||||||
|
**키워드 토큰**
|
||||||
|
|
||||||
|
* `IF`: `if`
|
||||||
|
* `THEN`: `then`
|
||||||
|
* `ELSE`: `else`
|
||||||
|
* `WHILE`: `while`
|
||||||
|
* `RETURN`: `return`
|
||||||
|
* `INT`: `int`
|
||||||
|
* `VOID`: `void`
|
||||||
|
|
||||||
|
**가변길이 토큰**
|
||||||
|
|
||||||
|
* `ID`: 식별자
|
||||||
|
* `NUM`: 숫자
|
||||||
|
|
||||||
|
**기호 토큰**
|
||||||
|
|
||||||
|
* `ASSIGN`: `=`
|
||||||
|
* `EQ`: `==`
|
||||||
|
* `NE`: `!=`
|
||||||
|
* `LT`: `<`
|
||||||
|
* `LE`: `<=`
|
||||||
|
* `GT`: `>`
|
||||||
|
* `GE`: `>=`
|
||||||
|
* `PLUS`: `+`
|
||||||
|
* `MINUS`: `-`
|
||||||
|
* `TIMES`: `*`
|
||||||
|
* `OVER`: `/`
|
||||||
|
* `LPAREN`: `(`
|
||||||
|
* `RPAREN`: `)`
|
||||||
|
* `LBRACE`: `[`
|
||||||
|
* `RBRACE`: `]`
|
||||||
|
* `LCURLY`: `{`
|
||||||
|
* `RCURLY`: `}`
|
||||||
|
* `SEMI`: `;`
|
||||||
|
* `COMMA`: `,`
|
||||||
|
|
||||||
|
**토큰에 포함되지 않는 스펙**
|
||||||
|
|
||||||
|
* `/*` - `*/`: 주석 (토큰에 포함하지 않음)
|
||||||
|
|
||||||
|
위와 같은 토큰 타입을 기반으로 토크나이징하는 것이 목적이다.
|
||||||
|
|
||||||
|
### Using `scan.c`
|
||||||
|
|
||||||
|
`scan.c`에서는 올바른 `getToken`을 작성해야 한다.
|
||||||
|
|
||||||
|
`getToken`을 작성하기에 앞서 전이가능한 `STATE`를 작성한다. 특히 `<`, `>`, `!`, `=`, `/`의 경우에는 단 한 글자만 받는게 아니라 그 다음 문자에 따라 산출할 토큰이 달라질 수 있으므로 그에 따른 `STATE`를 만든다.
|
||||||
|
|
||||||
|
결과적으로 필요한 STATE는 다음과 같다.
|
||||||
|
|
||||||
|
```
|
||||||
|
START, INOVER, INCOMMENT, ASTERCOMMENT, INASSIGN, INLT, INGT, INNE, INNUM, INID, DONE
|
||||||
|
```
|
||||||
|
|
||||||
|
이를 이용해 `getToken`의 DFA를 작성할 수 있다.
|
||||||
|
|
||||||
|
```mermaid
|
||||||
|
stateDiagram-v2
|
||||||
|
START
|
||||||
|
state comment {
|
||||||
|
INOVER
|
||||||
|
INCOMMENT
|
||||||
|
ASTERCOMMENT
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
INASSIGN
|
||||||
|
INLT
|
||||||
|
INGT
|
||||||
|
INNE
|
||||||
|
state multichar {
|
||||||
|
INNUM
|
||||||
|
INID
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
state done {
|
||||||
|
DONE
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
START --> INNUM: isdigit
|
||||||
|
INNUM --> INNUM: isdigit
|
||||||
|
INNUM --> DONE: else with unget
|
||||||
|
|
||||||
|
START --> INID: isalpha
|
||||||
|
INID --> INID: isalnum
|
||||||
|
INID --> DONE: else with unget
|
||||||
|
|
||||||
|
START --> INASSIGN: =
|
||||||
|
INASSIGN --> DONE: =
|
||||||
|
INASSIGN --> DONE: else with unget
|
||||||
|
|
||||||
|
START --> INLT: \<
|
||||||
|
INLT --> DONE: =
|
||||||
|
INLT --> DONE: else with unget
|
||||||
|
|
||||||
|
START --> INGT: \>
|
||||||
|
INGT --> DONE: =
|
||||||
|
INGT --> DONE: else with unget
|
||||||
|
|
||||||
|
START --> INNE: !
|
||||||
|
INNE --> DONE: =
|
||||||
|
INNE --> DONE: else with unget and</br> return ERROR
|
||||||
|
|
||||||
|
|
||||||
|
START --> INOVER: /
|
||||||
|
INOVER --> INCOMMENT: \*
|
||||||
|
INCOMMENT --> ASTERCOMMENT: \*
|
||||||
|
ASTERCOMMENT --> INCOMMENT: else
|
||||||
|
ASTERCOMMENT --> START: /
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
이를 통해 `scan.c`를 작성하면 된다.
|
||||||
|
|
||||||
|
이때 `tokenString`은 항상 넣되 (하지만 NUM, ID 토큰에서만 필요함) comment때만 안 넣으면 된다. `unget`할때도 안넣어야 한다.
|
||||||
|
|
||||||
|
### Using Lex (cminus.l)
|
||||||
|
|
||||||
|
tiny의 lex파일처럼 간단하게 넣고 컴파일하면 된다.
|
||||||
|
|
||||||
|
하나 중요한 점은 comment를 구현할 때, `prev`와 `now`를 각 과정에서 계속 업데이트 해가면서 `now == '/' && prev == '*'` 일때까지 계속 `input()`을 받아주면 된다.
|
||||||
|
|
||||||
|
## Examples & Result
|
||||||
|
|
||||||
|
|
||||||
|
<table>
|
||||||
|
<tr>
|
||||||
|
<th>cminus file</th>
|
||||||
|
<th>result text file</th>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
|
||||||
|
```c { .line-numbers }
|
||||||
|
/* A program to perform Euclid's
|
||||||
|
Algorithm to computer gcd */
|
||||||
|
|
||||||
|
int gcd (int u, int v)
|
||||||
|
{
|
||||||
|
if (v == 0) return u;
|
||||||
|
else return gcd(v,u-u/v*v);
|
||||||
|
/* u-u/v*v == u mod v */
|
||||||
|
}
|
||||||
|
|
||||||
|
void main(void)
|
||||||
|
{
|
||||||
|
int x; int y;
|
||||||
|
x = input(); y = input();
|
||||||
|
output(gcd(x,y));
|
||||||
|
}
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
|
||||||
|
```scanres
|
||||||
|
|
||||||
|
C-MINUS COMPILATION: ./test1.cm
|
||||||
|
4: reserved word: int
|
||||||
|
4: ID, name= gcd
|
||||||
|
4: (
|
||||||
|
4: reserved word: int
|
||||||
|
4: ID, name= u
|
||||||
|
4: ,
|
||||||
|
4: reserved word: int
|
||||||
|
4: ID, name= v
|
||||||
|
4: )
|
||||||
|
5: {
|
||||||
|
6: reserved word: if
|
||||||
|
6: (
|
||||||
|
6: ID, name= v
|
||||||
|
6: ==
|
||||||
|
6: NUM, val= 0
|
||||||
|
6: )
|
||||||
|
6: reserved word: return
|
||||||
|
6: ID, name= u
|
||||||
|
6: ;
|
||||||
|
7: reserved word: else
|
||||||
|
7: reserved word: return
|
||||||
|
7: ID, name= gcd
|
||||||
|
7: (
|
||||||
|
7: ID, name= v
|
||||||
|
7: ,
|
||||||
|
7: ID, name= u
|
||||||
|
7: -
|
||||||
|
7: ID, name= u
|
||||||
|
7: /
|
||||||
|
7: ID, name= v
|
||||||
|
7: *
|
||||||
|
7: ID, name= v
|
||||||
|
7: )
|
||||||
|
7: ;
|
||||||
|
9: }
|
||||||
|
11: reserved word: void
|
||||||
|
11: ID, name= main
|
||||||
|
11: (
|
||||||
|
11: reserved word: void
|
||||||
|
11: )
|
||||||
|
12: {
|
||||||
|
13: reserved word: int
|
||||||
|
13: ID, name= x
|
||||||
|
13: ;
|
||||||
|
13: reserved word: int
|
||||||
|
13: ID, name= y
|
||||||
|
13: ;
|
||||||
|
14: ID, name= x
|
||||||
|
14: =
|
||||||
|
14: ID, name= input
|
||||||
|
14: (
|
||||||
|
14: )
|
||||||
|
14: ;
|
||||||
|
14: ID, name= y
|
||||||
|
14: =
|
||||||
|
14: ID, name= input
|
||||||
|
14: (
|
||||||
|
14: )
|
||||||
|
14: ;
|
||||||
|
15: ID, name= output
|
||||||
|
15: (
|
||||||
|
15: ID, name= gcd
|
||||||
|
15: (
|
||||||
|
15: ID, name= x
|
||||||
|
15: ,
|
||||||
|
15: ID, name= y
|
||||||
|
15: )
|
||||||
|
15: )
|
||||||
|
15: ;
|
||||||
|
16: }
|
||||||
|
17: EOF
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
|
||||||
|
```c {.line-numbers}
|
||||||
|
void main(void)
|
||||||
|
{
|
||||||
|
int i; int x[5];
|
||||||
|
|
||||||
|
i = 0;
|
||||||
|
while( i < 5 )
|
||||||
|
{
|
||||||
|
x[i] = input();
|
||||||
|
|
||||||
|
i = i + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
i = 0;
|
||||||
|
while( i <= 4 )
|
||||||
|
{
|
||||||
|
if( x[i] != 0 )
|
||||||
|
{
|
||||||
|
output(x[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
</td>
|
||||||
|
|
||||||
|
<td>
|
||||||
|
|
||||||
|
```scanres
|
||||||
|
|
||||||
|
C-MINUS COMPILATION: ./test2.cm
|
||||||
|
1: reserved word: void
|
||||||
|
1: ID, name= main
|
||||||
|
1: (
|
||||||
|
1: reserved word: void
|
||||||
|
1: )
|
||||||
|
2: {
|
||||||
|
3: reserved word: int
|
||||||
|
3: ID, name= i
|
||||||
|
3: ;
|
||||||
|
3: reserved word: int
|
||||||
|
3: ID, name= x
|
||||||
|
3: [
|
||||||
|
3: NUM, val= 5
|
||||||
|
3: ]
|
||||||
|
3: ;
|
||||||
|
5: ID, name= i
|
||||||
|
5: =
|
||||||
|
5: NUM, val= 0
|
||||||
|
5: ;
|
||||||
|
6: reserved word: while
|
||||||
|
6: (
|
||||||
|
6: ID, name= i
|
||||||
|
6: <
|
||||||
|
6: NUM, val= 5
|
||||||
|
6: )
|
||||||
|
7: {
|
||||||
|
8: ID, name= x
|
||||||
|
8: [
|
||||||
|
8: ID, name= i
|
||||||
|
8: ]
|
||||||
|
8: =
|
||||||
|
8: ID, name= input
|
||||||
|
8: (
|
||||||
|
8: )
|
||||||
|
8: ;
|
||||||
|
10: ID, name= i
|
||||||
|
10: =
|
||||||
|
10: ID, name= i
|
||||||
|
10: +
|
||||||
|
10: NUM, val= 1
|
||||||
|
10: ;
|
||||||
|
11: }
|
||||||
|
13: ID, name= i
|
||||||
|
13: =
|
||||||
|
13: NUM, val= 0
|
||||||
|
13: ;
|
||||||
|
14: reserved word: while
|
||||||
|
14: (
|
||||||
|
14: ID, name= i
|
||||||
|
14: <=
|
||||||
|
14: NUM, val= 4
|
||||||
|
14: )
|
||||||
|
15: {
|
||||||
|
16: reserved word: if
|
||||||
|
16: (
|
||||||
|
16: ID, name= x
|
||||||
|
16: [
|
||||||
|
16: ID, name= i
|
||||||
|
16: ]
|
||||||
|
16: !=
|
||||||
|
16: NUM, val= 0
|
||||||
|
16: )
|
||||||
|
17: {
|
||||||
|
18: ID, name= output
|
||||||
|
18: (
|
||||||
|
18: ID, name= x
|
||||||
|
18: [
|
||||||
|
18: ID, name= i
|
||||||
|
18: ]
|
||||||
|
18: )
|
||||||
|
18: ;
|
||||||
|
19: }
|
||||||
|
20: }
|
||||||
|
21: }
|
||||||
|
22: EOF
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
</table>
|
||||||
BIN
src/2024062806.pdf
Normal file
BIN
src/2024062806.pdf
Normal file
Binary file not shown.
@@ -55,7 +55,7 @@ whitespace [ \t]+
|
|||||||
"/*" { char now, prev;
|
"/*" { char now, prev;
|
||||||
do
|
do
|
||||||
{ now = input();
|
{ now = input();
|
||||||
if (now == EOF) break;
|
if (now == 0) break;
|
||||||
else if (now == '\n') lineno++;
|
else if (now == '\n') lineno++;
|
||||||
else if (now == '/' && prev == '*') break;
|
else if (now == '/' && prev == '*') break;
|
||||||
prev = now;
|
prev = now;
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ int TraceCode = FALSE;
|
|||||||
|
|
||||||
int Error = FALSE;
|
int Error = FALSE;
|
||||||
|
|
||||||
main(int argc, char *argv[]) {
|
int main(int argc, char *argv[]) {
|
||||||
TreeNode *syntaxTree;
|
TreeNode *syntaxTree;
|
||||||
char pgm[120]; /* source code file name */
|
char pgm[120]; /* source code file name */
|
||||||
if (argc != 2) {
|
if (argc != 2) {
|
||||||
|
|||||||
@@ -1,16 +0,0 @@
|
|||||||
/* A program to perform Euclid's
|
|
||||||
Algorithm to compute gcd */
|
|
||||||
|
|
||||||
int gcd(int u, int v)
|
|
||||||
{
|
|
||||||
if(v == 0) return u;
|
|
||||||
else return gcd(v, u- u/v * v);
|
|
||||||
/* hello u-u/v*v == u mod v */
|
|
||||||
}
|
|
||||||
|
|
||||||
void main()
|
|
||||||
{
|
|
||||||
int x; int y;
|
|
||||||
x = input(); y = input();
|
|
||||||
print(gcd(x, y));
|
|
||||||
}
|
|
||||||
@@ -219,7 +219,6 @@ TokenType getToken(void) { /* index for storing into tokenString */
|
|||||||
currentToken = ERROR;
|
currentToken = ERROR;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case INLT:
|
case INLT:
|
||||||
state = DONE;
|
state = DONE;
|
||||||
if (c == '=') {
|
if (c == '=') {
|
||||||
@@ -249,7 +248,7 @@ TokenType getToken(void) { /* index for storing into tokenString */
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case INID:
|
case INID:
|
||||||
if (!isalpha(c)) { /* backup in the input */
|
if (!isalnum(c)) { /* backup in the input */
|
||||||
ungetNextChar();
|
ungetNextChar();
|
||||||
save = FALSE;
|
save = FALSE;
|
||||||
state = DONE;
|
state = DONE;
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
|
|
||||||
C-MINUS COMPILATION: ./res/test.1.txt
|
C-MINUS COMPILATION: ./test1.cm
|
||||||
4: reserved word: int
|
4: reserved word: int
|
||||||
4: ID, name= gcd
|
4: ID, name= gcd
|
||||||
4: (
|
4: (
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
|
|
||||||
C-MINUS COMPILATION: ./res/test.2.txt
|
C-MINUS COMPILATION: ./test2.cm
|
||||||
1: reserved word: void
|
1: reserved word: void
|
||||||
1: ID, name= main
|
1: ID, name= main
|
||||||
1: (
|
1: (
|
||||||
5
src/test.cm
Normal file
5
src/test.cm
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
/*
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
dddd
|
||||||
@@ -156,7 +156,7 @@ char *copyString(char *s) {
|
|||||||
/* Variable indentno is used by printTree to
|
/* Variable indentno is used by printTree to
|
||||||
* store current number of spaces to indent
|
* store current number of spaces to indent
|
||||||
*/
|
*/
|
||||||
static indentno = 0;
|
static int indentno = 0;
|
||||||
|
|
||||||
/* macros to increase/decrease indentation */
|
/* macros to increase/decrease indentation */
|
||||||
#define INDENT indentno += 2
|
#define INDENT indentno += 2
|
||||||
|
|||||||
Reference in New Issue
Block a user