簡體   English   中英

在C / C ++代碼中解析python腳本文件的最佳方法是什么

[英]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本身進行解析工作。 如果您使用的是2.6之前的Python,則可以使用compiler模塊。 對於2.6及更高版本,請使用內置的compile功能和ast模塊。 在3.x中, 必須使用它們,因為已刪除了compiler模塊。

我認為您正在嘗試做額外的工作,因為(至少) 在其他應用程序工具中嵌入了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__並刪除inputraw_inputsys.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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM