我可以問一個關于我這幾天遇到的問題的問題嗎?如果你們愿意幫助我解決這個問題,我將非常感激:)
所以,我有一個我想決議的簡單字串,使用'@'關鍵字(只有在'@'在字串內部的字串之外時才決議它)。這背后的原因是我正在嘗試學習如何根據某些關鍵字決議一些字串以進行決議/拆分,因為我正在嘗試實作自己的“簡單編程語言”......
這是我使用正則運算式制作的示例:('@'關鍵字后面的空格并不重要)
# Ignore the 'println(' thing, it's basically a builtin print statement that I made, so
# you can only focus on the string itself :)
# (?!\B"[^"]*)@(?![^"]*"\B)
# As I looking up how to use this thing with regex, I found this one that basically
# split the strings into elements by '@' keyword, but not splitting it if '@' is found
# inside a string. Here's what I mean:
# '"[email protected]"' --- found '@' inside a string, so don't parse it
# '"[email protected]" @ x' --- found '@' outside a string, so after being parsed would be like this:
# ['"[email protected]", x']
print_args = re.split(r'(?!\B"[^"]*)@(?![^"]*"\B)', codes[x].split('println(')[-1].removesuffix(')\n' or ')'))
vars: list[str] = []
result_for_testing: list[str] = []
for arg in range(0, len(print_args)):
# I don't know if this works because it's split the string for each space, but
# if there are some spaces inside a string, it would be considered as the spaces
# that should've been split, but it should not be going to be split because
# because that space is inside a string that is inside a string, not outside a
# string that is inside a string.
# Example 1: '"Hello, World!" @ x @ y' => ['"Hello, World!"', x, y]
# Example 2: '"Hello, World! " @ x @ y' => ['"Hello, World! "', x, y]
# At this point, the parsing doesn't have to worry about unnecessary spaces inside a string, just like the example 2 is...
compare: list[str] = print_args[arg].split()
# This one is basically checking if '"'is not in a string that has been parsed (in this
# case is a word that doesn't have '"'). Else, append the whole thing for the rest of
# the comparison elements
# Here's the string: '"Value of a is: " @ a @ "String"' [for example 1]
# Example 1: ['"Value of a is: "', 'a', '"String"'] (This one is correct)
# Here's the string: '" Value of a is: " @ a @ " String"'
# Example 2: ['" Value of a is: " @ a @ " String"'] (This one is incorrect)
vars.append(compare[0]) if '"' not in compare[0] else vars.append(" ".join(compare[0:]))
for v in range(0, len(vars)):
# This thing is just doing it job, appending the same elements in 'vars'
# to the 'result_for_testing'
result_for_testing.append(vars[v])
print(result_for_testing)
在這些型別的操作之后,我得到的輸出是為了決議基本的東西而沒有不必要的空格是這樣的:
string_to_be_parsed: str = '"Value of a is: " @ a @ "String"'
Output > ['"Value of a is: "', 'a', '"String"'] # As what I'm expected to be...
但是當這樣的事情(帶有不必要的空格)時,它會以某種方式被破壞:
string_to_be_parsed: str = '" Value of a is: " @ a @ " String "'
Output > ['" Value of a is: " @ a @ " String "']
# Incorrect result and I'm hoping the result will be like this:
Expected Output > [" Value of a is: ", a, " String "]
# If there are spaces inside a string, it just has to be ignored, but I don't know how to do it
好的,各位,我遇到的問題就是這樣,結論是:
- 如何決議字串并通過'@'關鍵字在字串中拆分每個字串,但如果在字串中的字串中找到'@',它不會被拆分?
Example: '"@ in a string inside a string" @ is_out_from_a_string'
The result should be: ['"@ in a string inside a string"', is_out_from_a_string]
- 在決議字串時,如何忽略字串中的所有空格?
Example: '" unnecessary spaces here too" @ x @ y @ z " this one too"'
The result should be: ['" unnecessary spaces here too"', x, y, z, '" this one too"']
再次感謝您的辛勤作業,幫助我找到解決問題的方法,如果我做錯了什么或誤解,請告訴我在哪里,以及我應該如何解決它:)
謝謝 :)
uj5u.com熱心網友回復:
在談論編程語言時, string.split() 和嵌套回圈是不夠的。編程語言通常將其分為兩個步驟:分詞器或詞法分析器,以及決議器。標記器接受輸入字串(您的語言中的代碼)并回傳代表關鍵字、識別符號等的標記串列。在您的代碼中,這是結果中的每個元素。
無論哪種方式,您都可能想要稍微重構您的代碼。對于分詞器,這里有一些 python-ish 偽代碼:
yourcode = input
tokens = []
cursor = 0
while cursor < len(yourcode):
yourcode = yourcode[cursor:-1] # remove previously scanned tokens
match token regex from list of regexes
if match == token:
add add token of matched type to tokens
cursor = len(matched string)
elif match == whitespace:
cursor = len(matched whitespace)
else throw error invalid token
這使用游標在您的輸入字串中前進并提取標記,作為您問題的直接答案。對于正則運算式串列,只需使用對串列,其中每對包含一個正則運算式和一個描述令牌型別的字串。
但是,對于第一個編程語言專案,構建手動標記器和決議器可能不是可行的方法,因為它很快就會變得非常復雜,盡管一旦您熟悉了基礎知識,這是一個很好的學習體驗。我會考慮使用決議器生成器。我使用了一個名為SLY的 python 以及 PLY(SLY 的前身),效果很好。決議器生成器采用grammar特定格式對您的語言的描述,并輸出一個可以決議您的語言的程式,這樣您就可以擔心語言本身的功能,而不是決議文本/代碼輸入的方??式。
在開始實施之前,也可能值得做更多的研究。具體來說,我建議閱讀Abstract Syntax Trees和決議演算法,特別recursive descent是如果您手動構建決議器,您將要撰寫的內容,以及LALR(1)SLY 生成的(從左到右前瞻)。
AST 是決議器的輸出(決議器生成器為您執行的操作),用于解釋或編譯您的語言。它們是構建編程語言的基礎,所以我將從那里開始。該視頻解釋了語法樹,并且還有許多關于決議的特定于 python 的視頻。本系列還介紹了使用 SLY 在 python 中創建簡單的語言。
編輯:關于在字串之前對 @ 符號的特定決議,我建議對 @ 符號使用一種標記型別,對字串文字使用另一種標記型別。在您的決議器中,您可以在決議器遇到 @ 符號時檢查下一個標記是否是字串文字。這將通過拆分您的正則運算式來降低復雜性,并且如果您實作將來還使用 @ 或字串文字的功能,還允許您重用令牌。
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/461369.html
