Browse Source

feat: 添加词法分析模块

添加从str读取信息的模块
添加词法分析模块及其测试程序
添加词法分析模块错误信息输出程序
SongZihuan 3 năm trước cách đây
mục cha
commit
a456b65d4e

+ 3 - 0
include/aFun.h

@@ -14,6 +14,9 @@
 #include "gc.h"
 #include "magic_func.h"
 
+#include "reader.h"
+#include "parser.h"
+
 // Init系列函数
 void aFunInit(void);
 

+ 17 - 0
include/lexical_warning_error.h

@@ -0,0 +1,17 @@
+/*
+ * 文件名: lexical_warning_error.h
+ * 目标: 记录lexical的警告和错误信息
+ */
+#ifndef AFUN_LEXICAL_WARNING_ERROR_H
+#define AFUN_LEXICAL_WARNING_ERROR_H
+
+#define LEXICAL_ERROR(status, info) ("status: " #status " " #info)
+
+#define SYS_ILLEGAL_CHAR(status) LEXICAL_ERROR(status, "System error to obtain illegal characters") /* switch分支获得了不可能的字符 */
+#define ILLEGAL_CHAR(status) LEXICAL_ERROR(status, "Illegal characters") /* 输入了非法字符 */
+
+#define SYS_ERROR_STATUS(status) LEXICAL_ERROR(status, "System error to jump status") /* 状态跳转错误 */
+#define INCOMPLETE_FILE(status) LEXICAL_ERROR(status, "Incomplete file") /* 文件不完整 */
+#define INCULDE_CONTROL(status) LEXICAL_ERROR(status, "Include control characters in the text (not recommended)") /* 文本中包含控制符 */
+
+#endif //AFUN_LEXICAL_WARNING_ERROR_H

+ 20 - 0
include/parser.h

@@ -0,0 +1,20 @@
+#ifndef AFUN_PARSER_H
+#define AFUN_PARSER_H
+#include "macro.h"
+#include "token.h"
+#include "reader.h"
+
+typedef struct af_Parser af_Parser;
+
+/* Parser 创建与释放 */
+af_Parser *makeParser(DLC_SYMBOL(readerFunc) read_func, DLC_SYMBOL(destructReaderFunc) destruct_func, size_t data_size,
+                      FILE *error);
+void freeParser(af_Parser *parser);
+af_Parser *makeParserByString(char *str, bool free_str, FILE *error);
+
+/* Parser 操作函数 */
+af_TokenType getTokenFromLexical(char **text, af_Parser *parser);
+void *getParserData(af_Parser *parser);
+void initParser(af_Parser *parser);
+
+#endif //AFUN_PARSER_H

+ 6 - 5
include/prefix_macro.h

@@ -5,14 +5,15 @@
 #ifndef AFUN__PREFIX_MACRO_H
 #define AFUN__PREFIX_MACRO_H
 
-#define LV_PREFIX ",`'"  /* 字面量和变量前缀 */
-#define B_PREFIX "%^&'`,<?>"  /* 括号前缀 */
+#define E_PREFIX ",`'"  /* element前缀 */
+#define B_PREFIX ",`'%^&<?>"  /* block前缀 */
+#define ALL_PREFIX B_PREFIX
 
 // 作为顶层代码,以及'()运行时
-#define V_QUOTE           (0)  /* 变量前缀: 引用 */
+#define E_QUOTE           (0)  /* element前缀: 引用 */
 
-#define B_EXEC            (1)  /* 括号前缀: 顺序执行 */
-#define B_EXEC_FIRST      (2)  /* 括号前缀: 顺序执行, 返回第一个 */
+#define B_EXEC            (1)  /* block前缀: 顺序执行 */
+#define B_EXEC_FIRST      (2)  /* block前缀: 顺序执行, 返回第一个 */
 
 #define PREFIX_SIZE       (3)  /* 前缀总数 */
 

+ 11 - 0
include/reader.h

@@ -0,0 +1,11 @@
+#ifndef AFUN_READER_H
+#define AFUN_READER_H
+#include "macro.h"
+
+typedef size_t readerFunc(void *data, char *dest, size_t len);
+DEFINE_DLC_SYMBOL(readerFunc);
+
+typedef void destructReaderFunc(void *data);
+DEFINE_DLC_SYMBOL(destructReaderFunc);
+
+#endif //AFUN_READER_H

+ 23 - 0
include/token.h

@@ -0,0 +1,23 @@
+#ifndef AFUN_TOKEN_H
+#define AFUN_TOKEN_H
+#include "macro.h"
+
+enum af_TokenType {
+    TK_ERROR = -1,
+    TK_PREFIX = 0,  // 前缀
+    TK_LP = 1,
+    TK_LB = 2,
+    TK_LC = 3,
+    TK_RP = 4,
+    TK_RB = 5,
+    TK_RC = 6,
+    TK_ELEMENT_SHORT = 7,
+    TK_ELEMENT_LONG = 8,
+    TK_COMMENT = 9,
+    TK_SPACE = 10,
+    TK_EOF = 11,
+};
+
+typedef enum af_TokenType af_TokenType;
+
+#endif //AFUN_TOKEN_H

+ 52 - 0
src/core/__parser.h

@@ -0,0 +1,52 @@
+#ifndef AFUN__PARSER_H
+#define AFUN__PARSER_H
+#include <stdio.h>
+#include "__reader.h"
+#include "token.h"
+#include "parser.h"
+
+enum af_LexicalStatus {
+    lex_begin = 0,  // 起始类型
+    lex_prefix_block_p = 1,  // 前缀括号 !
+    lex_prefix_block_b = 2,  // 前缀括号 @
+    lex_prefix_block_c = 3,  // 前缀括号 #
+    lex_comment_before = 4,  // 注释
+    lex_element_long = 5,
+    lex_mutli_comment = 6,  // 多行注释
+    lex_uni_comment = 7,  // 当行注释
+    lex_mutli_comment_end_before = 8,  // 多行注释遇到;
+
+    lex_prefix = -1,  // prefix类型
+    lex_lp = -2,
+    lex_lb = -3,
+    lex_lc = -4,
+    lex_rp = -5,
+    lex_rb = -6,
+    lex_rc = -7,
+    lex_space = -8,
+    lex_uni_comment_end = -9,
+    lex_mutli_comment_end = -10,
+    lex_nul = -11,
+    lex_element_short = -12,
+    lex_element_long_end = -13,
+};
+
+typedef enum af_LexicalStatus af_LexicalStatus;
+typedef struct af_Lexical af_Lexical;
+
+struct af_Parser {
+    struct af_Reader *reader;
+    struct af_Lexical *lexical;
+    FILE *error;
+};
+
+struct af_Lexical {  // 词法匹配器的状态机
+    enum af_LexicalStatus status;
+    size_t last;  // 最后一次词法匹配的有效长度
+    enum af_TokenType token;  // token类型\
+
+    size_t mutli_comment;  // 多行注释嵌套等级
+    bool is_end;
+};
+
+#endif //AFUN__PARSER_H

+ 7 - 4
src/core/__reader.h

@@ -3,6 +3,7 @@
 #include <stdio.h>
 #include "macro.h"
 #include "tool.h"
+#include "reader.h"
 
 #define DEFAULT_BUF_SIZE (1024)
 #define NEW_BUF_SIZE (512)
@@ -12,12 +13,12 @@ typedef struct af_Reader af_Reader;
 typedef size_t readerFunc(void *data, char *dest, size_t len);
 NEW_DLC_SYMBOL(readerFunc, readerFunc);
 
-typedef void destructReaderDataFunc(void *data);
-NEW_DLC_SYMBOL(destructReaderDataFunc, destructReaderDataFunc);
+typedef void destructReaderFunc(void *data);
+NEW_DLC_SYMBOL(destructReaderFunc, destructReaderFunc);
 
 struct af_Reader {
     DLC_SYMBOL(readerFunc) read_func;
-    DLC_SYMBOL(destructReaderDataFunc) destruct;
+    DLC_SYMBOL(destructReaderFunc) destruct;
     void *data;
     size_t data_size;
 
@@ -26,10 +27,12 @@ struct af_Reader {
     size_t buf_size;  // buf的长度-1
     char *read;
     bool read_end;
+
+    bool init;  // 是否初始化
 };
 
 /* Reader 创建与释放 */
-af_Reader *makeReader(DLC_SYMBOL(readerFunc) read_func, DLC_SYMBOL(destructReaderDataFunc) destruct_func, size_t data_size);
+af_Reader *makeReader(DLC_SYMBOL(readerFunc) read_func, DLC_SYMBOL(destructReaderFunc) destruct_func, size_t data_size);
 void freeReader(af_Reader *reader);
 
 /* Reader 初始化函数 */

+ 1 - 1
src/core/code.c

@@ -39,7 +39,7 @@ static af_Code *makeCode(char prefix, FileLine line, FilePath path) {
 }
 
 af_Code *makeElementCode(char *var, char prefix, FileLine line, FilePath path) {
-    if (prefix != NUL && strchr(LV_PREFIX, prefix) == NULL)
+    if (prefix != NUL && strchr(E_PREFIX, prefix) == NULL)
         prefix = NUL;
 
     af_Code *bt = makeCode(prefix, line, path);

+ 4 - 4
src/core/env.c

@@ -84,8 +84,8 @@ char setPrefix(size_t name, char prefix, af_Environment *env) {
     if (prefix_ == NULL || strlen(prefix_) < PREFIX_SIZE)
         return '-';
     switch (name) {
-        case V_QUOTE:
-            if (prefix == NUL && strchr(LV_PREFIX, prefix) == NULL)
+        case E_QUOTE:
+            if (prefix == NUL && strchr(E_PREFIX, prefix) == NULL)
                 prefix = '-';
             break;
         case B_EXEC:
@@ -538,7 +538,7 @@ af_Environment *makeEnvironment(enum GcRunTime grt) {
 
     /* 设置默认prefix */
     char prefix[PREFIX_SIZE + 1] = "";
-    prefix[V_QUOTE] = '\'';
+    prefix[E_QUOTE] = '\'';
     prefix[B_EXEC] = '\'';
     prefix[B_EXEC_FIRST] = ',';
     setEnvVar(ev_sys_prefix, prefix, env);
@@ -673,7 +673,7 @@ bool pushExecutionActivity(af_Code *bt, bool return_first, af_Environment *env)
 }
 
 static bool isInfixFunc(af_Code *code, af_Environment *env) {
-    if (code == NULL || code->type != code_element || code->prefix == getPrefix(V_QUOTE, env))
+    if (code == NULL || code->type != code_element || code->prefix == getPrefix(E_QUOTE, env))
         return false;
 
     af_Var *var = findVarFromVarList(code->element.data, env->activity->belong, env->activity->var_list);

+ 401 - 0
src/core/lexical.c

@@ -0,0 +1,401 @@
+/*
+ * 文件名: lexical
+ * 目标: aFunlang词法分析
+ */
+#include <ctype.h>
+#include "aFun.h"
+#include "__parser.h"
+#include "lexical_warning_error.h"
+
+static void printLexicalError(char *info, af_Parser *parser) {
+    if (parser->error == NULL)
+        return;
+    fprintf(parser->error, "[Lexical-Error] %s\n", info);
+}
+
+static void printLexicalWarning(char *info, af_Parser *parser) {
+    if (parser->error == NULL)
+        return;
+    fprintf(parser->error, "[Lexical-Warning] %s\n", info);
+}
+
+static void setLexicalLast(af_LexicalStatus status, af_TokenType token, af_Parser *parser) {
+    parser->lexical->status = status;
+    parser->lexical->last = parser->reader->read - parser->reader->buf;
+    parser->lexical->token = token;
+}
+
+/*
+ * 函数族: done系列 (doneXXX)
+ * 目标: 用于把转台xxx转换为其他状态
+ * 返回值: 1 正常
+ * 返回值: 0 遇到错误, 仍可继续
+ * 返回值: -1 正常, 不可继续 -> 必须设置 setLexicalLast
+ * 返回值: -2 遇到错误, 不可继续
+ * 注意: 函数使用前不在检查`status`是否正确
+ */
+
+/*
+ * 状态机图:
+ * [lex_begin]
+ *     -> NUL -> (lex_nul)
+ *     -> ALL_PREFIX -> [lex_prefix] # return -1
+ *     -> ! -> (lex_prefix_block_p)
+ *     -> @ -> (lex_prefix_block_b)
+ *     -> # -> (lex_prefix_block_c)
+ *     -> ( -> [lex_lp] # return -1
+ *     -> [ -> [lex_lb] # return -1
+ *     -> { -> [lex_lc] # return -1
+ *     -> ) -> [lex_rp] # return -1
+ *     -> ] -> [lex_rb] # return -1
+ *     -> } -> [lex_rc] # return -1
+ *     -> ; -> (lex_comment_before)
+ *     -> iscntrl(ch) || isspace(ch) -> [lex_space]
+ *     -> | -> (lex_element_long)
+ *     -> isgraph(ch) -> [lex_element]
+ */
+
+static int doneBegin(char ch, af_Parser *parser) {
+    if (ch == NUL) {
+        setLexicalLast(lex_nul, TK_EOF, parser);
+        return -1;
+    } else if (strchr(ALL_PREFIX, ch)) {  /* 属于前缀 */
+        setLexicalLast(lex_prefix, TK_PREFIX, parser);
+        return -1;
+    } else if (strchr("!@#", ch)) {
+        switch (ch) {
+            case '!':
+                parser->lexical->status = lex_prefix_block_p;
+                return 1;
+            case '@':
+                parser->lexical->status = lex_prefix_block_b;
+                return 1;
+            case '#':
+                parser->lexical->status = lex_prefix_block_c;
+                return 1;
+            default:
+                printLexicalError(SYS_ILLEGAL_CHAR(lex_beging), parser);
+                return -2;
+        }
+    } else if (strchr("([{)]}", ch)) { /* 括号 */
+        switch (ch) {
+            case '(':
+                setLexicalLast(lex_lp, TK_LP, parser);
+                return -1;
+            case '[':
+                setLexicalLast(lex_lb, TK_LB, parser);
+                return -1;
+            case '{':
+                setLexicalLast(lex_lc, TK_LC, parser);
+                return -1;
+            case ')':
+                setLexicalLast(lex_rp, TK_RP, parser);
+                return -1;
+            case ']':
+                setLexicalLast(lex_rb, TK_RB, parser);
+                return -1;
+            case '}':
+                setLexicalLast(lex_rc, TK_RC, parser);
+                return -1;
+            default:
+                printLexicalError(SYS_ILLEGAL_CHAR(lex_beging), parser);
+                return -2;
+        }
+    } else if (ch == ';') {
+        parser->lexical->status = lex_comment_before;
+        return 1;
+    } else if (iscntrl(ch) || isspace(ch)) {  // 空白符或控制字符被忽略
+        setLexicalLast(lex_space, TK_SPACE, parser);
+        return 1;
+    } else if (ch == '|') {
+        parser->lexical->status = lex_element_long;
+        return 1;
+    } else if (isgraph(ch)) {  // 除空格外的可见字符
+        setLexicalLast(lex_element_short, TK_ELEMENT_SHORT, parser);
+        return 1;
+    }
+    printLexicalError(ILLEGAL_CHAR(lex_beging), parser);
+    return -2;
+}
+
+/*
+ * 状态机图:
+ * [lex_prefix_block_p] -> ( -> [lex_lp] # return -1
+ * [lex_prefix_block_b] -> ( -> [lex_lb] # return -1
+ * [lex_prefix_block_c] -> ( -> [lex_lc] # return -1
+ * [lex_prefix_block_p] -> ) -> [lex_rp] # return -1
+ * [lex_prefix_block_b] -> ) -> [lex_rb] # return -1
+ * [lex_prefix_block_c] -> ) -> [lex_rc] # return -1
+ */
+static int donePrefixBlock(char ch, af_Parser *parser) {
+    if (ch == '(') {
+        switch (parser->lexical->status) {
+            case lex_prefix_block_p:
+                setLexicalLast(lex_lp, TK_LP, parser);
+                return -1;
+            case lex_prefix_block_b:
+                setLexicalLast(lex_lb, TK_LB, parser);
+                return -1;
+            case lex_prefix_block_c:
+                setLexicalLast(lex_lc, TK_LC, parser);
+                return -1;
+            default:
+                printLexicalError(SYS_ERROR_STATUS(lex_prefix_block), parser);
+                return -2;
+        }
+    } else if (ch == ')') {
+        switch (parser->lexical->status) {
+            case lex_prefix_block_p:
+                setLexicalLast(lex_rp, TK_RP, parser);
+                return -1;
+            case lex_prefix_block_b:
+                setLexicalLast(lex_rb, TK_RB, parser);
+                return -1;
+            case lex_prefix_block_c:
+                setLexicalLast(lex_rc, TK_RC, parser);
+                return -1;
+            default:
+                printLexicalError(SYS_ERROR_STATUS(lex_prefix_block), parser);
+                return -2;
+        }
+    }
+    printLexicalError(ILLEGAL_CHAR(lex_prefix_block), parser);
+    return -2;
+}
+
+/*
+ * 状态机图:
+ * [lex_comment_before]
+ *      -> '\n' || NUL -> [lex_uni_comment_end] # return -1
+ *      -> ; -> (lex_mutli_comment) # mutli_comment = 0
+ *      -> other -> (lex_uni_comment)
+ */
+static int doneCommentBefore(char ch, af_Parser *parser) {
+    if (ch == '\n' || ch == NUL) {
+        setLexicalLast(lex_uni_comment_end, TK_COMMENT, parser);
+        return -1;
+    } else if (ch == ';') {  // 多行注释
+        parser->lexical->status = lex_mutli_comment;
+        parser->lexical->mutli_comment = 0;
+        return 1;
+    }
+    parser->lexical->status = lex_uni_comment;
+    return 1;
+}
+
+/*
+ * 状态机图:
+ * [lex_uni_comment]
+ *      -> '\n' || NUL -> [lex_uni_comment_end] # return -1
+ *      -> other -> (lex_uni_comment)
+ */
+static int doneUniComment(char ch, af_Parser *parser) {
+    if (ch == '\n' || ch == NUL) {
+        setLexicalLast(lex_uni_comment_end, TK_COMMENT, parser);
+        return -1;
+    }
+    parser->lexical->status = lex_uni_comment;
+    return 1;
+}
+
+/*
+ * 状态机图:
+ * [lex_mutli_comment]
+ *      -> NUL -> [lex_mutli_comment_end] # return -1; [warning]
+ *      -> ; -> (lex_mutli_comment_end_before)
+ *      -> other -> (lex_mutli_comment)
+ */
+static int doneMutliComment(char ch, af_Parser *parser) {
+    if (ch == NUL) {
+        parser->lexical->status = lex_mutli_comment_end;
+        printLexicalWarning(INCOMPLETE_FILE(lex_mutli_comment), parser);
+        return -1;
+    } else if (ch == ';')
+        parser->lexical->status = lex_mutli_comment_end_before;
+    else
+        parser->lexical->status = lex_mutli_comment;
+    return 1;
+}
+
+/*
+ * 状态机图:
+ * [lex_mutli_comment_end_before]
+ *      -> NUL -> [lex_mutli_comment_end] # return -1; [warning]
+ *      -> ; -> (lex_mutli_comment) # mutli_comment++;
+ *      -> = ->
+ *              mutli_comment == 0 -> [lex_mutli_comment_end] # return -1
+ *              else -> (lex_mutli_comment)# mutli_comment--;
+ */
+static int doneMutliCommentBeforeEnd(char ch, af_Parser *parser) {
+    if (ch == NUL) {
+        printLexicalWarning(INCOMPLETE_FILE(lex_mutli_comment_end_before), parser);
+        setLexicalLast(lex_mutli_comment_end, TK_COMMENT, parser);
+        return -1;
+    } else if (ch == ';') {
+        /* 嵌套注释 */
+        parser->lexical->mutli_comment++;
+        parser->lexical->status = lex_mutli_comment;
+    } else if (ch == '=') {
+        if (parser->lexical->mutli_comment == 0) {
+            /* 注释结束 */
+            setLexicalLast(lex_mutli_comment_end, TK_COMMENT, parser);
+            return -1;
+        } else {
+            /* 嵌套注释 */
+            parser->lexical->mutli_comment--;
+            parser->lexical->status = lex_mutli_comment;
+        }
+    }
+    parser->lexical->status = lex_mutli_comment;
+    return 1;
+}
+
+/*
+ * 状态机图:
+ * [lex_element_long]
+ *      -> NUL -> error
+ *      -> | -> [lex_element_long_end]
+ *      -> other -> (lex_element_long)
+ */
+static int doneElementLong(char ch, af_Parser *parser) {
+    if (ch == '|') {  // 结束符
+        setLexicalLast(lex_element_long_end, TK_ELEMENT_LONG, parser);
+        return 1;
+    } else if (ch == NUL) {
+        printLexicalError(INCOMPLETE_FILE(lex_element_long), parser);
+        return -2;
+    }
+    parser->lexical->status = lex_element_long;
+    return 1;
+}
+
+/*
+ * 状态机图:
+ * [lex_element_long]
+ *      -> | -> (lex_element_long)
+ *      -> other -> [lex_element_long_end] # return -1
+ */
+static int doneElementLongEnd(char ch, af_Parser *parser) {
+    if (ch == '|') {  // ||表示非结束
+        parser->lexical->status = lex_element_long;
+        return 1;
+    }
+    parser->lexical->status = lex_element_long_end;
+    return -1;
+}
+
+/*
+ * 状态机图:
+ * [lex_element_short]
+ *      -> !strchr("!@#([{}]);", ch) && isgraph(ch) -> (lex_element_short)
+ *      -> other -> (lex_element_short) # return -1
+ */
+static int doneElementShort(char ch, af_Parser *parser) {
+    if (!strchr("!@#([{}]);", ch) && isgraph(ch)) {  // 除空格外的可见字符 (不包括NUL)
+        setLexicalLast(lex_element_short, TK_ELEMENT_SHORT, parser);
+        return 1;
+    }
+    parser->lexical->status = lex_element_short;
+    return -1;
+}
+
+/*
+ * 状态机图:
+ * [lex_space]
+ *      -> ch != NUL && (iscntrl(ch) || isspace(ch)) -> (lex_space)
+ *      -> other -> (lex_space) # return -1
+ */
+static int doneSpace(char ch, af_Parser *parser) {
+    if (ch != NUL && (iscntrl(ch) || isspace(ch))) {
+        setLexicalLast(lex_space, TK_SPACE, parser);
+        return 1;
+    }
+    parser->lexical->status = lex_space;
+    return -1;
+}
+
+/*
+ * 函数名: getTokenFromLexical
+ * 目标: 获取Lexical的TokenType以及相关值
+ */
+af_TokenType getTokenFromLexical(char **text, af_Parser *parser) {
+    af_TokenType tt;
+    int re;
+    parser->lexical->status = lex_begin;
+    parser->lexical->last = 0;
+
+    if (parser->lexical->is_end) {
+        *text = NULL;
+        return TK_EOF;
+    }
+
+    while (1) {
+        char ch = getChar(parser->reader);
+        if (iscntrl(ch) && !isspace(ch))
+            printLexicalWarning(INCULDE_CONTROL(base), parser);
+
+        switch (parser->lexical->status) {
+            case lex_begin:
+                re = doneBegin(ch, parser);
+                break;
+            case lex_prefix_block_p:
+            case lex_prefix_block_b:
+            case lex_prefix_block_c:
+                re = donePrefixBlock(ch, parser);
+                break;
+            case lex_comment_before:
+                re = doneCommentBefore(ch, parser);
+                break;
+            case lex_element_long:
+                re = doneElementLong(ch, parser);
+                break;
+            case lex_mutli_comment:
+                re = doneMutliComment(ch, parser);
+                break;
+            case lex_uni_comment:
+                re = doneUniComment(ch, parser);
+                break;
+            case lex_mutli_comment_end_before:
+                re = doneMutliCommentBeforeEnd(ch, parser);
+                break;
+            case lex_space:
+                re = doneSpace(ch, parser);
+                break;
+            case lex_element_short:
+                re = doneElementShort(ch, parser);
+                break;
+            case lex_element_long_end:
+                re = doneElementLongEnd(ch, parser);
+                break;
+            default:
+                printLexicalError(SYS_ERROR_STATUS(base), parser);
+                re = -3;
+                break;
+        }
+
+        if (re == -1) {
+            char *word = readWord(parser->lexical->last, parser->reader);
+            tt = parser->lexical->token;
+
+            if (tt == TK_ELEMENT_SHORT || tt == TK_ELEMENT_LONG)
+                *text = word;
+            else
+                free(word);
+
+            if (tt == TK_SPACE || tt == TK_COMMENT) {
+                parser->lexical->status = lex_begin;
+                parser->lexical->last = 0;
+                continue;
+            } else if (tt == TK_EOF)
+                parser->lexical->is_end = true;
+
+            break;
+        } else if (re == -2 || re == -3) {
+            tt = TK_ERROR;
+            *text = NULL;
+            break;
+        }
+    }
+
+    return tt;
+}

+ 80 - 0
src/core/parser.c

@@ -0,0 +1,80 @@
+/*
+ * 文件名: parser.c
+ * 目标: __parser.h中结构体的相关函数
+ */
+
+#include "aFun.h"
+#include "__parser.h"
+
+static af_Lexical *makeLexical(void);
+static void freeLexical(af_Lexical *lex);
+
+af_Parser *makeParser(DLC_SYMBOL(readerFunc) read_func, DLC_SYMBOL(destructReaderFunc) destruct_func, size_t data_size,
+                      FILE *error) {
+    af_Parser *parser = calloc(1, sizeof(af_Parser));
+    parser->reader = makeReader(read_func, destruct_func, data_size);
+    parser->lexical = makeLexical();
+    parser->error = error;
+    return parser;
+}
+
+void freeParser(af_Parser *parser) {
+    freeReader(parser->reader);
+    freeLexical(parser->lexical);
+    free(parser);
+}
+
+void *getParserData(af_Parser *parser) {
+    return getReaderData(parser->reader);
+}
+
+void initParser(af_Parser *parser) {
+    initReader(parser->reader);
+}
+
+static af_Lexical *makeLexical(void) {
+    af_Lexical *lex = calloc(1, sizeof(af_Lexical));
+    lex->status = lex_begin;
+    return lex;
+}
+
+static void freeLexical(af_Lexical *lex) {
+    free(lex);
+}
+
+
+struct readerDataString {
+    char *str;
+    bool free_str;
+    size_t index;
+    size_t len;
+};
+
+static size_t readFuncString(struct readerDataString *data, char *dest, size_t len) {
+    if (data->index == data->len)  // 读取到末尾
+        return 0;
+
+    if (data->index + len > data->len)  // 超出长度范围
+        len = data->len - data->index;
+    memcpy(dest, data->str + data->index, len);
+    data->index += len;
+    return len;
+}
+
+static void destructFunc(struct readerDataString *data) {
+    if (data->free_str)
+        free(data->str);
+}
+
+af_Parser *makeParserByString(char *str, bool free_str, FILE *error) {
+    DLC_SYMBOL(readerFunc) read_func = MAKE_SYMBOL(readFuncString, readerFunc);
+    DLC_SYMBOL(destructReaderFunc) destruct = MAKE_SYMBOL(destructFunc, destructReaderFunc);
+    af_Parser *parser = makeParser(read_func, destruct, sizeof(struct readerDataString), error);
+    ((struct readerDataString *)parser->reader->data)->str = str;
+    ((struct readerDataString *)parser->reader->data)->free_str = free_str;
+    ((struct readerDataString *)parser->reader->data)->len = strlen(str);
+    initParser(parser);
+    FREE_SYMBOL(read_func);
+    FREE_SYMBOL(destruct);
+    return parser;
+}

+ 5 - 2
src/core/reader.c

@@ -1,9 +1,9 @@
 #include "__reader.h"
 
-af_Reader *makeReader(DLC_SYMBOL(readerFunc) read_func, DLC_SYMBOL(destructReaderDataFunc) destruct_func, size_t data_size) {
+af_Reader *makeReader(DLC_SYMBOL(readerFunc) read_func, DLC_SYMBOL(destructReaderFunc) destruct_func, size_t data_size) {
     af_Reader *reader = calloc(1, sizeof(af_Reader));
     reader->read_func = COPY_SYMBOL(read_func, readerFunc);
-    reader->destruct = COPY_SYMBOL(destruct_func, destructReaderDataFunc);
+    reader->destruct = COPY_SYMBOL(destruct_func, destructReaderFunc);
 
     reader->data = calloc(1, data_size);
     reader->data_size = data_size;
@@ -16,8 +16,11 @@ af_Reader *makeReader(DLC_SYMBOL(readerFunc) read_func, DLC_SYMBOL(destructReade
 }
 
 af_Reader *initReader(af_Reader *reader) {
+    if (reader->init)
+        return reader;
     char *new = readWord(reader->buf_size, reader);  // 写入数据
     free(new);
+    reader->init = true;
     return reader;
 }
 

+ 1 - 1
src/core/run.c

@@ -160,7 +160,7 @@ static bool codeElement(af_Code *code, af_Environment *env) {
     obj_isObjFunc *is_obj;
     obj_isInfixFunc *is_infix;
 
-    if (code->prefix != getPrefix(V_QUOTE, env)) {
+    if (code->prefix != getPrefix(E_QUOTE, env)) {
         if ((is_obj = findAPI("obj_isObjFunc", obj->data->api)) != NULL && is_obj(obj))
             return pushVariableActivity(code, var->vn->obj, env);  // 对象函数
         else if (env->activity->status != act_func_get && // 在act_func模式时关闭保护

+ 2 - 0
test/CMakeLists.txt

@@ -31,11 +31,13 @@ ADD_aFunTest(env test_env.c)
 ADD_aFunTest(regex test_regex.c)
 ADD_aFunTest(run test_run.c)
 ADD_aFunTest(reader test_reader.c)
+ADD_aFunTest(lexical test_lexcial.c)
 
 SET_LINK(lib lib_Test1)  # 链接测试程序需要的动态库
 
 SET_PASS(lib "num = 100 test = 110")
 SET_PASS(dlc "a = 100, test = 110")
+
 SET_PASS(byte_code
 "out:
 code_element: data prefix: 44

+ 33 - 0
test/test_lexcial.c

@@ -0,0 +1,33 @@
+#include <stdio.h>
+#include "aFun.h"
+
+char *str = "Hello_var\n"
+            "10 20.32 100var\n"
+            "|10 20.32|int->num\n"
+            "|10||20.32|int->num\n"
+            "{if true 10}\n"
+            "of(HelloWorld)\n"
+            "!(!) @(@) #(#)\n"
+            "() [] {}\n"
+            "Hello ;comment\n"
+            "Hello ;;comment\n"
+            "commment2;=\n"
+            "var-200 ;; comment\n"
+            ";; comment\n"
+            ";= comment\n"
+            ";= var-300\n";
+
+int main() {
+    af_Parser *parser = makeParserByString(str, false, stderr);
+    af_TokenType tt;
+    char *text = NULL;
+
+    do {
+        tt = getTokenFromLexical(&text, parser);
+        printf("tt = %d, text = %s\n", tt, text);
+        free(text);
+    } while (tt != TK_EOF && tt != TK_ERROR);
+
+    freeParser(parser);
+    return 0;
+}

+ 5 - 5
test/test_reader.c

@@ -7,10 +7,10 @@ typedef struct af_Reader af_Reader;
 typedef size_t readerFunc(void *data, char *dest, size_t len);
 DEFINE_DLC_SYMBOL(readerFunc);
 
-typedef void destructReaderDataFunc(void *data);
-DEFINE_DLC_SYMBOL(destructReaderDataFunc);
+typedef void destructReaderFunc(void *data);
+DEFINE_DLC_SYMBOL(destructReaderFunc);
 
-af_Reader *makeReader(DLC_SYMBOL(readerFunc) read_func, DLC_SYMBOL(destructReaderDataFunc) destruct_func, size_t data_size);
+af_Reader *makeReader(DLC_SYMBOL(readerFunc) read_func, DLC_SYMBOL(destructReaderFunc) destruct_func, size_t data_size);
 void freeReader(af_Reader *reader);
 af_Reader *initReader(af_Reader *reader);
 void *getReaderData(af_Reader *reader);
@@ -38,7 +38,7 @@ int main() {
 
     {
         DLC_SYMBOL(readerFunc) read_func = MAKE_SYMBOL(readTest, readerFunc);
-        DLC_SYMBOL(destructReaderDataFunc) destruct_func = MAKE_SYMBOL(destructTest, destructReaderDataFunc);
+        DLC_SYMBOL(destructReaderFunc) destruct_func = MAKE_SYMBOL(destructTest, destructReaderFunc);
         af_Reader *reader = makeReader(read_func, destruct_func, sizeof(int));
         *(int *) getReaderData(reader) = 0;
         initReader(reader);
@@ -58,7 +58,7 @@ int main() {
 
     {
         DLC_SYMBOL(readerFunc) read_func = MAKE_SYMBOL(readTest, readerFunc);
-        DLC_SYMBOL(destructReaderDataFunc) destruct_func = MAKE_SYMBOL(destructTest, destructReaderDataFunc);
+        DLC_SYMBOL(destructReaderFunc) destruct_func = MAKE_SYMBOL(destructTest, destructReaderFunc);
         af_Reader *reader = makeReader(read_func, destruct_func, sizeof(int));
         *(int *) getReaderData(reader) = 0;
         initReader(reader);