簡體   English   中英

是什么讓Java比C更容易解析?

[英]What makes Java easier to parse than C?

我熟悉C和C ++的語法是上下文相關的事實,特別是你需要在C中使用“lexer hack”。另一方面,我的印象是你只能解析Java盡管兩種語言之間存在相當大的相似性,但仍有2個前瞻性令牌。

你需要改變什么才能使它更易於解析?

我問,因為我所見過的關於C的上下文敏感性的所有例子在技術上都是允許的,但非常奇怪。 例如,

foo (a);

可以用參數a調用void函數foo 或者,它可以聲明a foo類型的對象,但你可以輕松地擺脫這些parantheses。 在某種程度上,這種奇怪之處的發生是因為C語法的“直接聲明者”生成規則實現了聲明函數和變量的雙重目的。

另一方面, Java語法具有用於變量聲明和函數聲明的單獨生成規則。 如果你寫

foo a;

然后你知道它是一個變量聲明, foo可以毫不含糊地解析為一個類型名。 如果類foo尚未在當前作用域中的某處定義,則這可能不是有效代碼,但這是可以在稍后的編譯器傳遞中執行的語義分析的工作。

我已經看到它說由於typedef很難解析C,但你也可以在Java中聲明自己的類型。 除了direct_declarator之外,哪個C語法規則有錯?

解析C ++變得越來越難。 解析Java變得同樣困難。

看到這個SO回答討論為什么C(和C ++)“難以”解析 簡短的總結是C和C ++ 語法本質上是模棱兩可的; 他們會給你多個解析,你必須使用上下文來解決歧義。 然后人們會假設你在解析時必須解決歧義; 不是這樣,見下文。 如果你在解析時堅持解決歧義,你的解析器會變得更復雜,而且構建起來要困難得多; 但這種復雜性是一種自我傷害。

IIRC,Java 1.4的“明顯的”LALR(1)語法並不含糊,因此解析起來很“容易”。 我不太確定現代Java至少沒有長距離的局部模糊; 總是存在決定“... >>”關閉兩個模板還是“右移操作符”的問題。 我懷疑現代Java不再用LALR(1)解析了

但是,對於這兩種語言,可以通過使用強解析器(或弱解析器和上下文收集黑客,因為C和C ++前端主要執行此操作)來解決問題。 C和C ++具有預處理器的額外復雜性; 這些在實踐中比它們看起來更復雜。 一種說法是C和C ++解析器非常難以完成,必須手工編寫。 事實並非如此; 你可以使用GLR解析器生成器很好地構建Java和C ++解析器。

但解析並不是問題所在。

解析后,您將需要使用AST / parse樹執行某些操作。 實際上,您需要知道每個標識符的定義是什么以及它的使用位置(“名稱和類型分辨率”,粗略地構建符號表)。 事實證明,這比通過繼承,接口,重載和模板更加復雜,並且由於所有這些語義都是用非正式的自然語言編寫,這些語言分布在數十到數百頁之間,這使得它更加困難。語言標准。 C ++在這里真的很糟糕。 從這個角度來看,Java 7和8變得非常糟糕。 (而且符號表並不是你所需要的;請參閱我的生物文章,閱讀更長篇文章“解析后的生活”)。

大多數人都在使用純解析部分(通常永遠不會完成;檢查SO本身是否有很多關於如何為實際語言構建工作解析器的問題),所以他們在解析后看不到生命。 然后我們得到關於難以解析的內容的民間定理,並且沒有關於該階段之后發生的事情的信號。

修復C ++語法不會讓你到處都是。

關於更改C ++語法:你會發現你需要修補很多地方來處理任何C ++語法中的各種局部和真實歧義。 如果你堅持, 以下列表可能是一個很好的起點 我認為,如果你不是C ++標准委員會,這樣做沒有意義; 如果你這樣做,並使用它構建了一個編譯器,沒有人會理智地使用它。 為了方便構建解析器的人們,現有的C ++應用程序投入太多了。 此外,他們的痛苦已經結束,現有的解析器工作正常。

您可能想要編寫自己的解析器。 好沒關系; 只是不要指望社區的其他人讓你改變他們必須使用的語言,以使你更容易。 他們都希望他們更容易,這就是使用記錄和實施的語言。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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