词法分析器:如何识别令牌的结尾
Lexical analyser : how to identify the end of a token
我需要一个识别令牌结尾的函数,以便我可以在其中保存一个数组并将其发送到我的自动机进行识别(运算符、关键字、标识符)
当我只输入 1 个标记时,自动机工作得很好,但是当有很多标记包括空格时它不起作用,我需要这个函数来删除空格并在每个标记的末尾停止并发送数组中的每个标记到我的自动机函数,我被卡住了..
我正在使用 C
例如:ABC + D
:ABC 代币 1
: + 令牌 2
:D令牌3
ex2: ABC++D12*/z (ABC,+,+,D12,*,/,z) 7 个标记
ex3: AD ++ - C (AD,+,+,-,C) 5 个代币
编辑:我没有使用任何工具,只使用带有确定性有限自动机的 c
假设注释在较早的传递中被删除。
现在您可以点击空格、字母、数字或标点符号。
空格要么不是标记,要么是解析器忽略的虚拟/空标记。
字母必须是标识符的一部分。这由一个字母(或下划线,那里的小曲线球)后跟零个或多个字母或数字组成。下划线以外的空格或标点符号终止该标记。
数字必须是数字的一部分。规则有点复杂,0 前面表示八进制(已过时),0x 前面表示十六进制,1-9 表示十进制。后缀是允许的,科学记数法也是如此。但是任意 [标点符号或空格终止数字。
一元 -、++、<=、+= 和其他复合词几乎没有繁琐的规则。但是这些令牌没有附加值。 ++ 总是 ++.
字符串是下一个大问题,因为引号可以被转义。
但仅此而已。为 C 源代码手动构建词法分析器并不难。
(请参阅 MiniBasic 以了解如何为一种简单的语言编写一个简单但功能齐全的递归下降解析器。
https://sourceforge.net/projects/minibasic/files/?source=navbar)
void lirelexeme(char chaine[500]){
int i,j=0,k;
char tc,tc2;
char lexeme[500];memset(lexeme,0,500);
for(i=0;i<length;i++){
tc=chaine[i]; // terme courant
tc2=chaine[i+1]; // terme suivant
if(tc!=' ' && tc!='[=10=]' && tc!='\n'&& tc!='\t'){
if((tc==':' && tc2=='=') || (tc=='>' && tc2=='=') || (tc=='<' && tc2=='=') || (tc=='<' && tc2=='>')){ // ex: a:= / >= / <=
lexeme[0]=tc;
lexeme[1]=tc2;
lex(lexeme);
memset(lexeme,0,500);
j=0; // préparer pour recevoir le nouveau lexeme
i++; // on évite de prendre tc2
}
这里是拆分标记的函数,使用 puts() 而不是 lex() 来查看结果
注意:lex() 是我创建的词法分析器函数,它会将标记作为参数并为您提供 return 它的类型(常量、标识符、关键字、算术运算符、逻辑运算符...)
我需要一个识别令牌结尾的函数,以便我可以在其中保存一个数组并将其发送到我的自动机进行识别(运算符、关键字、标识符)
当我只输入 1 个标记时,自动机工作得很好,但是当有很多标记包括空格时它不起作用,我需要这个函数来删除空格并在每个标记的末尾停止并发送数组中的每个标记到我的自动机函数,我被卡住了..
我正在使用 C
例如:ABC + D
:ABC 代币 1
: + 令牌 2
:D令牌3
ex2: ABC++D12*/z (ABC,+,+,D12,*,/,z) 7 个标记 ex3: AD ++ - C (AD,+,+,-,C) 5 个代币
编辑:我没有使用任何工具,只使用带有确定性有限自动机的 c
假设注释在较早的传递中被删除。
现在您可以点击空格、字母、数字或标点符号。
空格要么不是标记,要么是解析器忽略的虚拟/空标记。
字母必须是标识符的一部分。这由一个字母(或下划线,那里的小曲线球)后跟零个或多个字母或数字组成。下划线以外的空格或标点符号终止该标记。
数字必须是数字的一部分。规则有点复杂,0 前面表示八进制(已过时),0x 前面表示十六进制,1-9 表示十进制。后缀是允许的,科学记数法也是如此。但是任意 [标点符号或空格终止数字。
一元 -、++、<=、+= 和其他复合词几乎没有繁琐的规则。但是这些令牌没有附加值。 ++ 总是 ++.
字符串是下一个大问题,因为引号可以被转义。
但仅此而已。为 C 源代码手动构建词法分析器并不难。
(请参阅 MiniBasic 以了解如何为一种简单的语言编写一个简单但功能齐全的递归下降解析器。 https://sourceforge.net/projects/minibasic/files/?source=navbar)
void lirelexeme(char chaine[500]){
int i,j=0,k;
char tc,tc2;
char lexeme[500];memset(lexeme,0,500);
for(i=0;i<length;i++){
tc=chaine[i]; // terme courant
tc2=chaine[i+1]; // terme suivant
if(tc!=' ' && tc!='[=10=]' && tc!='\n'&& tc!='\t'){
if((tc==':' && tc2=='=') || (tc=='>' && tc2=='=') || (tc=='<' && tc2=='=') || (tc=='<' && tc2=='>')){ // ex: a:= / >= / <=
lexeme[0]=tc;
lexeme[1]=tc2;
lex(lexeme);
memset(lexeme,0,500);
j=0; // préparer pour recevoir le nouveau lexeme
i++; // on évite de prendre tc2
}
这里是拆分标记的函数,使用 puts() 而不是 lex() 来查看结果
注意:lex() 是我创建的词法分析器函数,它会将标记作为参数并为您提供 return 它的类型(常量、标识符、关键字、算术运算符、逻辑运算符...)