如果字符位于引号之间,则不匹配(AKA具有编程字符串模式)
Do not match if a char is between quotation marks(AKA has a programming string pattern)
我被指派为Basic编程语言编写一个编译器。在basic中,代码用新行或:
标记分隔。例:以下三个代码是有效的。
模式# 1
10 PRINT "Hello World 1" : PRINT "Hello World 2"
模型# 2 10 PRINT "Hello World 1"
20 PRINT "Hello World 2"
你可以在这里测试。
在编译器中解析代码之前,我需要做的第一件事是拆分代码。
我已经将代码分成几行,但我遇到了寻找一个正则表达式来分割以下代码示例:
下面的代码示例应该分成2个PRINT
代码。
10 PRINT "Hello World 1" : PRINT "Hello World 2"
But DO NOT match this:
下面的代码示例是一个独立的命令。
10 PRINT "Hello World 1" ": PRINT Hello World 2"
任何正则表达式模式来匹配上面的代码样本中的第一个,其中:
在"
对之外并且不匹配第二个?
任何事情都会有帮助。:)
我认为对您来说最好的选择是使用诸如循环之类的设备来标记源代码,而不是尝试使用regexp来标记它。
在伪代码string lexeme;
token t;
for char in string
if char fits current token
lexeme = lexeme + char;
else
t.lexeme = lexeme;
t.type = type;
lexeme = null;
end if
// other treatments here
end for
您可以在源代码中看到该设备的实际实现,更具体地说是在第86行。
避免这种问题的方法是在匹配冒号之前匹配引号内的内容,例如:
"(?>[^\"]++|\{2}|\.)*"|:
您可以添加捕获组,以了解哪些部分的替换已被匹配。
但是,执行这类任务的最佳工具可能是lex/yacc感谢@Mauren,我成功地做了我想做的事。
这是我的代码(也许以后会帮助别人):
注意,源文件的内容包含在char* buffer
和vector<string> source_code
中。
/* lines' tokens container */
std::string token;
/* Tokenize the file's content into seperate lines */
/* fetch and tokenizing line version of readed data and maintain it into the container vector*/
for(int top = 0, bottom = 0; top < strlen(buffer) ; top++)
{
/* inline tokenizing with line breakings */
if(buffer[top] != 'n' || top == bottom)
{ /* collect current line's tokens */ token += char(buffer[top]); /* continue seeking */continue; }
/* if we reach here we have collected the current line's tokens */
/* normalize current tokens */
boost::algorithm::trim(token);
/* concurrent statements check point */
if(token.find(':') != std::string::npos)
{
/* a quotation mark encounter flag */
bool quotation_meet = false;
/* process entire line from beginning */
for(int index = 0; true ; index++)
{
/* loop's exit cond. */
if(!(index < token.length())) { break; }
/* fetch currently processing char */
char _char = token[index];
/* if encountered a quotation mark */
/* we are moving into a string */
/* note that in basic for printing quotation mark, should use `CHR$(34)`
* so there is no `"` to worry about! :) */
if(_char == '"')
{
/* change quotation meeting flag */
quotation_meet = !quotation_meet;
/* proceed with other chars. */
continue;
}
/* if we have meet the `:` char and also we are not in a pair quotation*/
if(_char == ':' && !quotation_meet)
{
/* this is the first sub-token of current token */
std::string subtoken(token.substr(0, index - 1));
/* normalize the sub-token */
boost::algorithm::trim(subtoken);
/* add sub-token as new line */
source_codes.push_back(subtoken);
/* replace the rest of sub-token as new token */
/**
* Note: We keep the `:` mark intentionally, since every code line in BASIC
* should start with a number; by keeping `:` while processing lines starting with `:` means
* they are meant to execute semi-concurrent with previous numbered statement.
* So we use following `substr` pattern instead of `token.substr(index + 1, token.length() - 1);`
*/
token = token.substr(index, token.length() - 1);
/* normalize the sub-token */
boost::algorithm::trim(token);
/* reset the index for new token */
index = 0;
/* continue with other chars */
continue;
}
}
/* if we have any remained token and not empty one? */
if(token.length())
/* a the tokens into collection */
goto __ADD_TOKEN;
}
__ADD_TOKEN:
/* if the token is not empty? */
if(token.length())
/* add fetched of token to our source code */
source_codes.push_back(token);
__NEXT_TOKEN:
/* move pointer to next tokens' position */
bottom = top + 1;
/* clear the token buffer */
token.clear();
/* a fail safe for loop */
continue;
}
/* We NOW have our source code departed into lines and saved in a vector */
相关文章:
- 有一个打印语句的函数是一种糟糕的编程实践吗
- 我是C++编程的新手,这些代码之间有什么区别,我应该使用哪一个
- 模板元编程:如何将参数包组合成新的参数包
- Qt Q串行端口未编程设备未关闭
- 模板元编程 - 尝试实现维度分析
- 我是编程新手
- C++编程从外部文本文件定义数组大小
- 了解算法的性能差异(如果以不同的编程语言实现)
- 使用 Gtkmm 以编程方式选择 Gtk::TextView 中的文本
- 如何将可变参数模板转换为多个单个模板?(C++竞争编程调试模板)
- 使用命名空间正确编程
- C++编程:运算符重载中的引用如何工作?
- Arduino 模块化编程与全局和设置
- C++ 运算符修改/元编程策略,用于不那么冗长的语法
- 在没有管理员权限的情况下,在 c++ 中以编程方式将程序添加到启动
- 如何以编程方式将音频从任何录制设备路由到任何播放设备
- 试图修复一个错误,该错误不会让我开始编程其余部分
- C++模板编程设计问题 - 根据输入文件返回不同的类型
- Frank Luna 在他的书"使用 DirectX12 进行 3D 游戏编程"的介绍中盒子示例的问题
- 如果字符位于引号之间,则不匹配(AKA具有编程字符串模式)