gpt4 book ai didi

string - Ada 如何逐个字符获取输入

转载 作者:行者123 更新时间:2023-12-03 03:02:29 25 4
gpt4 key购买 nike

我是 Ada 新手,我正在尝试将 Recursive Decent Parser 上的编译器教程中的代码转换为 Ada。移植 Jack W Crenshaw 的教程“让我们构建一个编译器”一直是我学习多种语言最喜欢的方式。使用单字符标记,我已经完成了第三章的所有工作。转向多字符 token 一直很麻烦。

我有类似这样的 sudo 代码:

procedure GetName is
token: Ada.Strings.Unbounded;
begin
while IsAlNum(Look) loop
Token := Token & Look;
GetChar;
end loop
end GetName;

现在我知道 Ada 的目的是让字符串保持静态。但我需要能够将从输入中获取的每个新字符连接到 Token 中的字符集合。 Look 是全局前瞻值(最后输入的字符)。

谢谢你的帮助。另外,网上有什么好的 Ada 教程或食谱网站吗?我读过 Lovelace 和 Ada for C 程序员的书。 Ada RM 有点正式,只显示规范,不使用...

再次感谢!

最佳答案

在这个问题的结尾,看起来您是在寻求 Ada 字符串处理方面的帮助。

是的,Ada 字符串确实最好作为静态字符串处理,而不是可调整大小的缓冲区。解决这个问题有三种典型的方法。

第一个方法是创建一个非常大的String缓冲区,并使用一个单独的Natural变量来保存字符串的逻辑长度。这有点痛苦,而且有点容易出错,但至少比 C 的在缓冲区末尾不断扫描空值的方法要快。

第二个是仅平底船并使用 Ada.Strings.Unbounded.Unbounded_String。这是大多数人所做的,因为如果您习惯以程序方式思考事情,这是最简单的。

第三个(如果可能的话我更喜欢)是按功能处理字符串。这里您需要的主要见解是,Ada String 确实是静态的,但您可以控制它们的生命周期,并且如果您进行功能编程,则可以随时动态地生成静态字符串。

例如,我可以通过执行以下操作来创建一个任意长度的新 Token 字符串(理论上具有无限的超前):

function Matches_Token (Scanned : String) return boolean;  --// Returns true if the given string is a token
function Could_Match_Longer (Scanned : String) return boolean; --// Returns true if the given string could be part of a larger token.
function Get_Next_Char return Character; --// Returns the next character from the stream
procedure Unget; --// Puts the last character back onto the stream
procedure Advance (Amount : Natural); --// Advance the stream pointer the given amount
function Longest_Matching_Token (Scanned : String) return String is
New_Token : constant String := Scanned & Get_Next_Char;
begin
--// Find the longest token a further scan can match
if Could_Match_Longer(New_Token) then
declare
LMT : constant String := Longest_Matching_Token (New_Token);
begin
if LMT /= "" then
unget;
return LMT;
end if;
end;
end if;

--// See if this string at least matches.
if Matches_Token(New_Token) then
unget;
return New_Token;
else
unget;
return "";
end if;
end Build_Token;

function Get_Next_Token return String is
Next_Token : constant String := Build_Token("");
begin
Advance (Next_Token'length);
return Next_Token;
end Get_Next_Token;

这并不总是最有效的字符串处理方法(堆栈使用过多),但它通常是最简单的。

在实践中,扫描和解析实际上是一种特殊情况的应用程序,通常建议避免丑陋的事情,例如缓冲区(方法 1)和 goto。

关于string - Ada 如何逐个字符获取输入,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10973382/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com