Python CST 和AST 類似之處的詳細介介紹
你在計算機相關操作中是否遇到過語法分析所獲得的中間結(jié)果例如CST,你想知道CST的實際相關應用嗎?下面的文章是針對 Python CST 的實際相關應用與相關代碼的詳細介紹,忘你會從中得到自己想要的東西。
Python CST 和AST 類似,都是語法分析所獲得的中間結(jié)果。他們的不同之處在于,CST直接對應語法分析的匹配的過程,是直接生成的,含有大量冗余信息。而AST省略了中間的冗余信息,直接對應實際的語義,也就是分析的結(jié)果。用例子說明要清楚一些:
假設有這樣一個表達式a,
Python CST是這樣的:(->表示從父結(jié)點到子結(jié)點)
- file_input -> stmt -> simple_stmt -> small_stmt ->
expr_stmt -> testlist -> test ->or_test ->and_test
->not_test -> comparison -> expr -> xor_expr ->
and_expr -> shift_expr -> arith_expr -> term ->- factor -> power -> atom -> (NAME, “a”)
而AST則是:
- (stmt_ty, expr_kind) -> (expr_ty, name_kind) ->(“a”)
可以看到CST表述了整個分析a的過程,從file_input一直推導到***的NAME,每一步推導都成了樹的結(jié)點,而大部分信息都可以說是無用的。AST的結(jié)構要簡單和直接的多,直接表明a是一個表達式語句(假定a是一個單獨的語句),內(nèi)容是一個標示符,值為”a”。Python的語法分析生成的是 Python CST而非AST,之后Python會調(diào)用PyAst_FromNode將CST轉(zhuǎn)換為AST。
CST的結(jié)點稱為Node,其結(jié)構定義在node.h中:
- typedef struct _node {
- short n_type;
- char *n_str;
- int n_lineno;
- int n_col_offset;
- int n_nchildren;
- struct _node *n_child;
- } node;
- Field
- Description
- n_type
結(jié)點類型,終結(jié)符定義在token.h中,而非終結(jié)符定義在graminit.h中
n_str
結(jié)點所對應的字符串的內(nèi)容
n_lineno
對應的行號
n_col_offset
列號
n_nchildren
子結(jié)點的個數(shù)
n_child
子結(jié)點數(shù)組,動態(tài)分配內(nèi)存
Python提供了下面的函數(shù)/宏來操作CST,同樣定義在node.h中:
- PyAPI_FUNC(node *) PyNode_New(int type);
- PyAPI_FUNC(int) PyNode_AddChild(node *n, int type,
- char *str, int lineno, int col_offset);
- PyAPI_FUNC(void) PyNode_Free(node *n);
- /* Node access functions */
- #define NCH(n) ((n)->n_nchildren)
- #define CHILD(n, i) (&(n)->n_child[i])
- #define RCHILD(n, i) (CHILD(n, NCH(n) + i))
- #define TYPE(n) ((n)->n_type)
- #define STR(n) ((n)->n_str)
- /* Assert that the type of a node is what we expect */
- #define REQ(n, type) assert(TYPE(n) == (type))
- PyAPI_FUNC(void) PyNode_ListTree(node *);
以上就是對 Python CST 和AST 類似,都是語法分析所獲得的中間結(jié)果。他們的不同之處在于,CST直接對應語法分析的匹配的過程,是直接生成的,含有大量冗余信息。而AST省略了中間的冗余信息,直接對應實際的語義,也就是分析的結(jié)果。用例子說明相關的內(nèi)容的介紹,忘你會有所收獲。
【編輯推薦】