以为我已经完成并准备提交这个小项目,直到我得到这个意想不到的曲线球。
目标是使用令牌词法分析器创建解析器。
实质上
<underline><red> R <green> G </green> <blue> B </blue> and back to red </red></underline>
将输出为:&#34; RGB并返回红色&#34;各自的颜色和属性。
在Windows上一切正常但是当我将它移到Linux系统时,它会输出颜色代码而不会发生任何事情。
#include <iostream>
#include <sstream>
#include <stack>
#include <map>
#include <cstdlib>
#include <vector>
#include "cmd.h"
#include "Lexer.h" // you should make use of the provided Lexer
#include "term_control.h"
#include "error_handling.h"
using namespace std;
map<string, term_colors_t> colorMap;
map<string, term_attrib_t> attribMap;
string display(const string& expression)
{
if(validate(expression) == "VALID") {
Lexer lex;
Token tok;
vector<term_colors_t> colorVect;
vector<term_attrib_t> attribVect;
lex.set_input(expression);
while(lex.has_more_token()){
tok = lex.next_token();
string sTok = tok.value;
if(tok.type == TAG && tok.value.at(0) != '/'){
cout<<term_cc(colorMap[tok.value], DEFAULT_COLOR, attribMap[tok.value]);
colorVect.push_back(colorMap[tok.value]);
attribVect.push_back(attribMap[tok.value]);
}
if(tok.type == TAG && tok.value.at(0) == '/'){
colorVect.pop_back();
cout<<term_cc(colorVect.back(), DEFAULT_COLOR, attribVect.back());
}
if(tok.type != TAG){
cout<<tok.value;
}
}
}
else if(validate(expression) != "VALID") return validate(expression);
return "";
}
_
cout<term_cc(Color, DEFAULT_COLOR, Attribute)
是隐藏问题的特定方法我一直在寻找并且似乎找不到合适的方法。
cout<<term_fg(color)
该方法在Linux系统上正确显示颜色,但我没有该方法的属性。
我读过的所有东西都只涉及颜色而不是颜色和属性,他们也使用了回声命令和特定终端的硬编码颜色。这些都需要对我的所有代码进行严格更改,导致它无法在Windows上运行,只能在Linux上运行,所以我试图避免这种情况。
提前感谢您对这个问题的任何建议,我很感激,希望我能在12点之前得到这个!
答案 0 :(得分:1)
我不清楚colorMap
和attribMap
在哪里被初始化以及在什么值上,我只是在这里本能,但似乎关键colorMap
的颜色和attribMap
的键是属性。在这种情况下,underline
不是colorMap
中的密钥,而red
不是attribMap
中的密钥。
在您的计划中,您执行以下操作:
if(tok.type == TAG && tok.value.at(0) != '/'){
cout<<term_cc(colorMap[tok.value], DEFAULT_COLOR, attribMap[tok.value]);
假设TAG
和colorMap
中都存在attribMap
{}}。但是,如果标记是"red"
之类的颜色,则(可能)仅在colorMap
中,如果它是"underline"
之类的属性,则它(可能)仅在attribMap
中}。
现在,执行colorMap["underline"]
会发生什么?在这里,C ++标准库的便利性可能有点不利,因为它默默地隐藏了一个错误。答案是将"underline"
到term_colors_t
的默认值的映射添加到地图中,以便查找始终返回一些内容。 term_colors_t
是一个枚举,因此其默认值为0
(不 '0'
)。
现在,term_cc
- 如果它与@MikePetch挖出的term_cc
相同 - 不检查其参数的有效性;它只是假设它们是有效的ANSI数字('0'
到'9'
,或者换句话说是48到57之间的数字,包括在内。)因为它没有检查它们,所以它只是输出包括它们在输出中,因为您(可能)使用属性参数0调用term_cc
- 即NUL
字符 - 它输出{{1作为假设的控制台代码的一部分。
我检查了NUL
,xterm
和Linux控制台,所有这些都忽略了konsole
字符。 (我相信这是预期的行为;像VT-100这样的DEC终端忽略了NUL
,虽然在某些情况下你需要插入它们,因为如果前一个控制花费太长时间,终端也会忽略任何字符。)我不知道您正在使用什么终端仿真器,并且它很可能具有不同的行为,例如终止控制代码序列。 NUL
首先输出属性,即使它是第三个参数,因此term_cc
属性可能会导致终端模拟器只打印NUL
之类的内容而不是设置前景色为红色。
其他一些错误:
你永远不会弹出;31;49m
;只有1个}}。所以我不知道如何正确恢复这些属性。
您不能将attribVect
初始化为colorVect
。因此,在弹出第一个标记后,您将从colorVect
中弹出(仅)元素,将其留空,然后调用DEFAULT_COLOR
,如果colorVect
为colorVect.back()
,则为colorVect
空。
这些只是我在快速浏览代码时注意到的事情。可能还有其他问题。