質問
システムプログラミングクラスのSICアセンブラーのコーディングをほぼ終了しましたが、トークン化部分に困惑しています。
たとえば、ソースコードのこの行を取ります:
フォーマット(フリーフォーマット)は次のとおりです。{label} opcode {operand {、x}} {comment}
カールは、フィールドがオプションであることを示しています。
また、各フィールドは、少なくとも1つのスペースまたはタブで分離する必要があります。
ENDFIL LDA EOF COMMENT GOES HERE
上記のコードの整理は少し簡単ですが、次のスニペットは私に困難を与えています。
RSUB COMMENT GOES HERE
私のコードは、コメントの最初の単語でオペランドであるかのように読み取られます。
これが私のコードです:
//tokenize line
if(currentLine[0] != ' ' && currentLine[0] != '\t')
{
stringstream stream(currentLine);
stream >> LABEL;
stream >> OPCODE;
stream >> OPERAND;
stream.str("");
if(LABEL.length() > 6 || isdigit(LABEL[0]) || !alphaNum(LABEL))
{
errors[1] = 1;
}
else if(LABEL.length() == currentLine.length())
{
justLabel = true;
errors[6] = 1;
return;
}
}
else
{
stringstream stream(currentLine);
stream >> OPCODE;
stream >> OPERAND;
stream.str("");
}
私の教授は、アセンブラーをソースコードの2つのバージョンでテストすることを要求しています。1つはエラーがあり、もう1つはありません。
RSUBオペコードはオペランドに依存していないため、RSUBオペコードの後のすべてがコメントと見なされる可能性があることを理解していますが、誤ったソースコードにオペランドフィールドに値が含まれている場合、またはオペランドに依存しているオペコードが欠落している場合オペランド値、これを補償するにはどうすればよいですか?これらにエラーとしてフラグを立て、誤ったオペランド値(またはその欠如)を印刷する必要があります。
私の質問は、コードのコメント部分がオペランドと見なされないようにするにはどうすればよいですか?
解決
私が見たアセンブリ言語(他のプログラミング言語のように)では、コメントをマークする区切り文字があります。たとえば、コメントの前のセミコロン:
ENDFIL LDA EOF ;COMMENT GOES HERE
RSUB ;ANOTHER COMMENT GOES HERE
しかし、あなたの構文では、例えば、オペコードとコメントの間に2つの(1つだけではなく)白面イベントがあるという事実によって、ライン上にそれに先行するホワイトスペースの量によるコメントであるかどうかを知ることができますか?
{LABEL}<whitespace>OPCODE<whitespace>{OPERAND{,X}}<whitespace>{COMMENT}
他のヒント
特定の行のテキストがオペランドかコメントであるかをどのように見分けることができますか?それはコンテキストに基づいていますか?たとえば、オペコードが「rsub」の場合、オペランドが必要ないことがわかりますか?次に、OpCodeの読み取りに基づいて、オペランドで魔法を実行する必要があります。
if (OPCODE == "RSUB") OPERAND.clear();