[英]What is the best way to parse python script file in C/C++ code
我將python嵌入C / C ++程序中。
我想做的是從C / C ++程序解析python腳本文件,將文件拆分為“塊”,以便每個“塊” 在python代碼中都是有效命令 。 我需要將每個塊放入std::string
。 例如:
#PythonScript.py
import math
print "Hello Python"
i = 0;
while (i < 10):
print "i = " , i;
i = i + 1;
print "GoodBye Python"
此腳本中有5個不同的“塊”:
"import math;"
"print "Hello Python;"
"i = 0;"
第四個是
while (i < 10):\\n\\tprint "i = " , i;\\n\\ti = i + 1;
我對python的了解非常基礎,並且我對python代碼語法不熟悉。 最好的方法是什么,是否有任何支持此功能的Python C / C ++ API函數?
為什么我需要它->用於GUI。 我的程序是用C語言編寫的,它使用python進行一些計算。 我從C代碼運行,使用python C API,python腳本,而我需要的是一種在程序中捕獲python輸出的方法。 我抓住了它,並且一切正常,問題是當腳本涉及用戶輸入時。 發生的是我在腳本完成后捕獲了python的輸出,因此,當腳本中有輸入命令時,我會黑屏....我需要在輸入命令前獲取所有打印內容。
我嘗試的第一個解決方案是將腳本解析為有效命令,然后依次運行每個命令,..為此,我需要解析腳本並忽略什么是命令,什么不是。問題是:做到這一點的最佳方法是什么?是否有萬事俱備的東西?
我認為您正在嘗試做額外的工作,因為(至少) 在其他應用程序工具中嵌入了Python,並且您只能通過Python / C API執行腳本。 我想我不想從頭開始編寫Python解釋器,是嗎?
如果要進行語法分析,則應研究Python語法(並可能使用Bison作為解析器生成器)
Python語法規格:
你為什么需要這個? 如果要嵌入Python,則無需自己解析Python代碼-甚至無需遠程解析。
但是要回答這個問題:您可以使用Python的ast
模塊(該模塊_ast
內部使用_ast
內置模塊-我不知道是否以及如何從C中使用它)。 ast.parse("""... your code ...""")
提供一個Module
對象,該對象具有body
屬性,該屬性是該模塊組成的AST節點的列表。 在此示例中,使用Python 3(手頭沒有Python 2)是(僅命名類)[Import,Expr,Assign,While,Expr]。 並不是您想要的,而是盡可能地接近您。
好吧,外加:還有比這更簡單的方式。 要證明沒有什么東西可以從stdin中讀取是非常困難的,它需要大量的靜態分析(是的,如果您選擇該路徑,那么使用CPython的AST仍然比構建自己的解析器容易一百倍)。 這是一般情況-因此,您可以通過大量工作使它幾乎適合您的特定用例。 但是,從一開始就阻止它會容易得多-我不太了解C API,但是必須有某種方法可以調整__builtins__
並刪除input
, raw_input
, sys.stdin
等。
@genesiss提供了您需要的所有信息。
我10年前學習過Python,所以我的知識並不比您的知識更好。 但我確實記得,空格和換行符是Python中實際的語法元素。
查看Python官方語法 ,最接近“塊”的語法元素就是statement
。
statement ::=
stmt_list NEWLINE | compound_stmt
因此,您只需查看換行符即可成功分離Python語句。
另請注意詞匯結構的第4個:
除字符串文字外,換行符(在下面表示為NEWLINE)很重要,除非
它們后面緊跟一個反斜杠(“ \\”)字符,在這種情況下,反斜杠和換行符(實際上)都被一個空格代替,將它們分開的兩行連接在一起。
它們被包含在匹配的左括號和右括號中:“(”和“)”,“ [”和“]”或“ {”和“}”。 在這種情況下,換行符也被視為空格。
因此,按字符讀取輸入字符,查找“ \\”,“ \\ n”和定界符。
下面的示例代碼(僅概念草圖):
std::string input;
std::string::const_iterator it = input.begin();
std::string::const_iterator itEnd = input.end();
int delim = 0;
bool escape = false;
std::string block;
while (it != itEnd)
{
char c = *it;
switch (c) {
case '\\':
if (!delim) escape = true;
break;
case '\n':
if (!delim && !escape)
write_block(); // handle contents of the block variable
escape = false;
break;
case '(': case '[': case '{':
++delim; escape = false;
break;
case ')': case ']': case '}':
--delim; escape = false;
break;
}
block.append(c, 1);
++it;
}
EDITED
缺少字符串文字處理,但是我相信您肯定可以像這樣進行完整的詞法分析。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.