Skip to content

Commit

Permalink
構文木ASTを整理する #1742
Browse files Browse the repository at this point in the history
  • Loading branch information
kujirahand committed Aug 31, 2024
1 parent 229b2d3 commit 6b0feb5
Show file tree
Hide file tree
Showing 9 changed files with 159 additions and 35 deletions.
3 changes: 2 additions & 1 deletion core/src/nako_from_dncl.mts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
// import { NakoIndentError } from './nako_errors.mjs'
import { Token, NewEmptyToken } from './nako_types.mjs'
import { joinTokenLines, splitTokens } from './nako_indent_inline.mjs'
import { TokenType } from './nako_token.mjs'

// DNCLモードのキーワード
const DNCL_KEYWORDS = ['!DNCLモード', '💡DNCLモード']
Expand Down Expand Up @@ -183,7 +184,7 @@ export function convertDNCL (tokens: Token[]): Token[] {
const t = tokens[i]
const a = DNCL_SIMPLES[t.type + ':' + t.value]
if (a !== undefined) {
t.type = a[0]
t.type = a[0] as TokenType
t.value = a[1]
}
}
Expand Down
4 changes: 3 additions & 1 deletion core/src/nako_from_dncl2.mts
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
/**
* DNCL ver2 に対応する構文
*/
// import { NakoIndentError } from './nako_errors.mjs'
import { Token, NewEmptyToken } from './nako_types.mjs'
import { joinTokenLines, splitTokens } from './nako_indent_inline.mjs'
import { newToken, debugTokens } from './nako_tools.mjs'
import { TokenType } from './nako_token.mjs'

const IS_DEBUG = false
const DNCL_ARRAY_INIT_COUNT = 30
Expand Down Expand Up @@ -250,7 +252,7 @@ export function convertDNCL2 (tokens: Token[]): Token[] {
const t = tokens[i]
const a = DNCL_SIMPLES[t.type + ':' + t.value]
if (a !== undefined) {
t.type = a[0]
t.type = a[0] as TokenType
t.value = a[1]
}
}
Expand Down
4 changes: 3 additions & 1 deletion core/src/nako_lex_rules.mts
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
/**
* なでしこ3字句解析のためのルール
*/

import { josiRE, removeJosiMap } from './nako_josi_list.mjs'
import { TokenType } from './nako_token.mjs'

const kanakanji = /^[\u3005\u4E00-\u9FCF_a-zA-Z0-9ァ-ヶー\u2460-\u24FF\u2776-\u277F\u3251-\u32BF]+/
const hira = /^[ぁ-ん]/
Expand All @@ -23,7 +25,7 @@ export interface NakoLexParseResult {
}

export interface NakoLexRule {
name: string;
name: TokenType;
pattern: RegExp;
readJosi?: boolean;
cb?: (v: string) => any;
Expand Down
5 changes: 3 additions & 2 deletions core/src/nako_lexer.mts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
// なでしこの字句解析を行う
// 既に全角半角を揃えたコードに対して字句解析を行う
import { opPriority } from './nako_parser_const.mjs'
Expand Down Expand Up @@ -214,7 +215,7 @@ export class NakoLexer {
t.value = t.value.substring(0, t.value.length - 1)
// N回を挿入
if (!t.endOffset) { t.endOffset = 1 }
const kai = { type: '回', value: '回', indent: t.indent, line: t.line, column: t.column, file: t.file, josi: '', startOffset: t.endOffset - 1, endOffset: t.endOffset, rawJosi: '' }
const kai: Token = { type: '回', value: '回', indent: t.indent, line: t.line, column: t.column, file: t.file, josi: '', startOffset: t.endOffset - 1, endOffset: t.endOffset, rawJosi: '' }
tokens.splice(i + 1, 0, kai)
t.endOffset--
i++
Expand Down Expand Up @@ -458,7 +459,7 @@ export class NakoLexer {
if (!t.rawJosi) { t.rawJosi = t.josi }
const startOffset = t.endOffset === undefined ? undefined : t.endOffset - t.rawJosi.length
tokens.splice(i + 1, 0, {
type: t.josi,
type: 'とは',
indent: t.indent,
line: t.line,
column: t.column,
Expand Down
9 changes: 8 additions & 1 deletion core/src/nako_parser3.mts
Original file line number Diff line number Diff line change
Expand Up @@ -897,7 +897,14 @@ export class NakoParser extends NakoParserBase {
if (incdec) {
if (incdec.type === 'word' && (incdec.value === '増' || incdec.value === '減')) {
if (incdec.value === '増') { flagDown = false }
kurikaesu.type = incdec.value + kurikaesu.type // typeを増繰返 | 減繰返 に変換
const w = incdec.value + kurikaesu.type
if (w == '増繰返') {
kurikaesu.type = '増繰返'
} else if (w == '減繰返') {
kurikaesu.type = '減繰返'
} else {
throw Error('[System Error] 増繰り返し | 減繰り返しのエラー。')
}
} else {
// 普通の繰り返しの場合
this.stack.push(incdec) // 違ったので改めて追加
Expand Down
6 changes: 5 additions & 1 deletion core/src/nako_reserved_words.mts
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
import { TokenType } from './nako_token.mjs'

/** 予約語 */
const reserved: Map<string, string> = new Map([
const reserved: Map<string, TokenType> = new Map([
['もし', 'もし'],
['回', '回'],
['回繰返', '回'], // (#924)
['間', '間'],
Expand Down Expand Up @@ -32,6 +35,7 @@ const reserved: Map<string, string> = new Map([
['インデント構文', 'インデント構文'], // https://nadesi.com/v3/doc/go.php?949
['非同期モード', '非同期モード'], // (#637)
['DNCLモード', 'DNCLモード'], // (#1140)
['DNCL2モード', 'DNCL2モード'],
['モード設定', 'モード設定'], // (#1020)
['取込', '取込'],
['モジュール公開既定値', 'モジュール公開既定値'],
Expand Down
128 changes: 128 additions & 0 deletions core/src/nako_token.mts
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
/* eslint-disable @typescript-eslint/no-explicit-any */

import { FuncListItem, Ast } from './nako_types.mjs'

export type TokenType = '?'
| 'eol'
| '_eol'
| 'eof'
| 'dec_lineno'
| 'require'
| 'line_comment' | 'range_comment'
| 'とは' // ?
| 'string' | 'string_ex'
| 'number'
| 'word'
| 'ならば'
| '増繰返' | '減繰返'
| '違えば'
| '定数'
| 'ここまで' | 'ここから'
| 'comma'
| 'func'
| 'func_pointer'
| 'not'
| 'code'
| 'space'
| 'def_test'
| 'def_func'
| 'bigint'
| '&'
| '('
| ')'
| 'eq'
| 'noteq'
| 'gt'
| 'gteq'
| 'lt'
| 'lteq'
| '==='
| '!=='
| '←'
| 'and'
| 'or'
| '@'
| '+'
| '-'
| '*'
| '**'
| '÷'
| '÷÷'
| '^'
| '%'
| '['
| ']'
| '{'
| '}'
| '|'
| 'shift_r0'
| 'shift_r'
| 'shift_l'
| ':'
| '…'
| 'もし'
| '回' // 回
| '回' // 回繰返 // (#924)
| '間' // 間
| '間' // 間繰返 // (#927)
| '繰返' // 繰返
| '増繰返' // 増繰返 // (#1140)
| '減繰返' // 減繰返
| '後判定' // 後判定 // (#1147)
| '反復' // 反復
| '抜ける' // 抜
| '続ける' // 続
| '戻る' // 戻
| '先に' // 先
| '次に' // 次
| '代入' // 代入
| '実行速度優先' // 実行速度優先
| 'パフォーマンスモニタ適用' // パフォーマンスモニタ適用 // (#986)
| '定める' // 定
| '逐次実行' // 逐次実行 // 廃止 #1611 ただし念のため残しておく
| '条件分岐' // 条件分岐
| '増' // 増
| '減' // 減
| '変数' // 変数
| '定数' // 定数
| 'エラー監視' // エラー監視 // 例外処理:エラーならばと対
| 'エラー' // エラー
| 'word' // それ
| 'word' // そう // 「それ」のエイリアス
| 'def_func' // 関数 // 無名関数の定義用
| 'インデント構文' // インデント構文 // https://nadesi.com/v3/doc/go.php?949
| '非同期モード' // 非同期モード // (#637)
| 'DNCLモード' // DNCLモード // (#1140)
| 'DNCL2モード'
| 'モード設定' // モード設定 // (#1020)
| '取込' // 取込
| 'モジュール公開既定値' // モジュール公開既定値
| '厳チェック' // 厳しくチェック (#1698)
| '」' // error - エラーチェックのため
| '』' // error - エラーチェックのため

// トークン
export interface Token {
type: TokenType;
value: any;
line: number;
column: number;
file: string;
josi: string;
indent: number;
meta?: FuncListItem;
rawJosi?: string;
startOffset?: number | undefined;
endOffset?: number | undefined;
isDefinition?: boolean;
funcPointer?: boolean;
tag?: string;
preprocessedCodeOffset?: number | undefined;
preprocessedCodeLength?: number | undefined;
// eslint-disable-next-line no-use-before-define
name?: Token | Ast; // NakoPaserBase.nodeToStrの問題を回避するため
start?: number;
end?: number;
firstToken?: Token;
lastToken?: Token;
}
4 changes: 3 additions & 1 deletion core/src/nako_tools.mts
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
/**
* よく使う処理をまとめたもの
*/
import { Token, NewEmptyToken } from './nako_types.mjs'
import { TokenType } from './nako_token.mjs'

/**
* トークンの内容をデバッグ出力する関数
Expand Down Expand Up @@ -37,7 +39,7 @@ export function makeIndent (n: number): string {
}

let lastTokenInfo = NewEmptyToken()
export function newToken (type: string, value: any, templateToken: Token|undefined = undefined): Token {
export function newToken (type: TokenType, value: any, templateToken: Token|undefined = undefined): Token {
if (templateToken) {
lastTokenInfo = templateToken
}
Expand Down
31 changes: 4 additions & 27 deletions core/src/nako_types.mts
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,16 @@

import { NakoGlobal } from './nako_global.mjs'
import { Ast as AstRaw } from './nako_ast.mjs'
import { Token as TokenRaw, TokenType } from './nako_token.mjs'

export type Ast = AstRaw;
export type Token = TokenRaw;

// 関数に関する定義
export type FuncArgs = string[][]

export type FuncListItemType = 'func' | 'var' | 'const' | 'test_func'

// FuncListの定義
export interface FuncListItem {
type: FuncListItemType;
Expand Down Expand Up @@ -43,33 +46,7 @@ export interface TokenMeta {
funcPointers: any[] | undefined;
}

// トークン
export interface Token {
type: string;
value: any;
line: number;
column: number;
file: string;
josi: string;
indent: number;
meta?: FuncListItem;
rawJosi?: string;
startOffset?: number | undefined;
endOffset?: number | undefined;
isDefinition?: boolean;
funcPointer?: boolean;
tag?: string;
preprocessedCodeOffset?: number | undefined;
preprocessedCodeLength?: number | undefined;
// eslint-disable-next-line no-use-before-define
name?: Token | Ast; // NakoPaserBase.nodeToStrの問題を回避するため
start?: number;
end?: number;
firstToken?: Token;
lastToken?: Token;
}

export function NewEmptyToken (type = '?', value: any = '', indent = -1, line = 0, file = 'main.nako3'): Token {
export function NewEmptyToken(type: TokenType = '?', value: any = '', indent = -1, line = 0, file = 'main.nako3'): Token {
return {
type,
value,
Expand Down

0 comments on commit 6b0feb5

Please sign in to comment.