如何从字符串中提取令牌?

时间:2020-10-06 03:39:22

标签: c# parsing

我正在尝试制作一个“编译器”,我需要让像这样的比较运算符:

  • '<='
  • '> ='
  • '!='

来自输入字符串。

我试图标记输入字符串以获取运算符,但我却得到了两个输出,例如:

'<'和'='或'>'和'='

static List<String> divideSymbols(string token){
            /** quitamos punto y coma y tokenizamos separando por operadores*/
            List<String> myTokens = new List<string>();
            // separar operadores
            char [] tokens = token.ToCharArray();
            String accum="";
            String accum1 = "";

            for(int i=0;i<tokens.Length; i++){
                try{
                    if((tokens[i]!='>' && tokens[i]!='<' && tokens[i]!='=' && tokens[i]!='+' && tokens[i]!='-' && tokens[i]!='(' && tokens[i]!=')' && tokens[i]!='{' && tokens[i]!='}' && tokens[i]!=(char)34 && tokens[i]!=(char)39 && tokens[i]!='/' && tokens[i]!='*' && tokens[i]!='%' && tokens[i]!='&' && tokens[i]!='|'  && tokens[i]!='!' && tokens[i]!=','  && tokens[i]!='[' && tokens[i]!=']' /*&& tokens[i+1] !='='*/) ){
                        /*if((tokens[i] == '>' || tokens[i] == '<' || tokens[i]== '!') && tokens[i+1]== '=' ){
                            Console.WriteLine("TEST");
                        }*/

                    if(tokens[i] == '<' && tokens[i+1] == '='){

                        
                    }
                    if(tokens[i]!=';' ){ // quitar ; (punto y coma)
                        removeDuplicates(accum);
                        
                        accum+=tokens[i];
                        
                    }

                }else{
                   
                    if(accum!=""){
                        myTokens.Add(accum);
                        myTokens.Add(tokens[i].ToString());

                    }else{
                        removeDuplicates(accum);
                        

                        myTokens.Add(tokens[i].ToString());
                    }
                    accum="";
                }
                
                    if((tokens[i]== '>' ||tokens[i]== '<' || tokens[i]== '!' || tokens[i]== '=') && tokens[i+1] == '='){
                        accum1 = tokens[i].ToString()+tokens[i+1].ToString();
                        myTokens.Add(accum1);
                        i++;
                        //myTokens.Remove('<');
                    }

                }catch(IndexOutOfRangeException){

                }   
            }
            myTokens.Add(accum);
            myTokens.Add(accum1);
            
            return myTokens;
        }

当我得到输出时,我得到了两个令牌,如果第二个是=符号,则需要删除第一个。

预期输出为:

1,<if_stmt>,if
1,<open_parents>,(
1,<number>,4
1,<morethan_op>,>
1,<eqmorethan_op>,>=
1,<number>,5
1,<close_parents>,)
1,<open_braces>,{
1,<eqmorethan_op>,>=
2,<print>,print
2,<open_parents>,(
2,<string_op>,"
2,<variable>,yes
2,<string_op>,"
2,<close_parents>,)
3,<close_braces>,}
4,<class>,class
4,<variable>,Foo
4,<open_braces>,{
5,<type>,int
5,<variable>,key
6,<close_braces>,}
8,<variable>,Foo
8,<variable>,a

,但无需重复>和> =。

1 个答案:

答案 0 :(得分:1)

如果我正确理解了您的问题-我们需要做的就是从输入字符串中提取比较运算符。

所以这里的想法是遍历字符串,只专注于

  • '<='
  • '> ='
  • '!='

当您尝试模拟编译器时,我们知道的是,每行必须以半列(punto y coma)结尾;

请牢记,我们要做的是传递字符串,删除所有空格,分析并返回找到的比较运算符。

    static string RemoveWhitespace( string input)
    {
        int j = 0, inputlen = input.Length;
        char[] newarr = new char[inputlen];

        for (int i = 0; i < inputlen; ++i)
        {
            char tmp = input[i];

            if (!char.IsWhiteSpace(tmp))
            {
                newarr[j] = tmp;
                ++j;
            }
        }
        return new String(newarr, 0, j);
    }

    static List<String> DivideSymbols(string tokenisedString)
    {
        string token= RemoveWhitespace(tokenisedString);

        List<String> myTokens = new List<string>();
        List<char> tokensToSkip = new List<char> { '+', '-', '(', ')', '{', '}', '/', '*', '%', '&', '|', '!', ',', '[', ']', '\'', '"' };

        char different = '!';
        char lessThan = '<';
        char greaterThan = '>';
        char equal = '=';
        char endOfLine = ';';

        for (int i = 0; i < token.Length - 1; i++)
        {
            if (token[i] == endOfLine)
            {
                break;
            }

            if (token[i] == different && token[i + 1] == equal)
            {
                myTokens.Add(token[i].ToString() + token[i + 1].ToString());
            }

            if (token[i] == lessThan && token[i + 1] == equal)
            {
                myTokens.Add(token[i].ToString() + token[i + 1].ToString());
            }

            if (token[i] == greaterThan && token[i + 1] == equal)
            {
                myTokens.Add(token[i].ToString() + token[i + 1].ToString());
            }
        }

        return myTokens;
    }
    static void Main(string[] args)
    {
        DivideSymbols("if(x == 1 && x >= 10 || v != 3 'perhaps something like' AND SQL <::=  c<=d) { x++};");
    }

现在,您已经有了逻辑,并且可以在if逻辑内对它们做任何您想做的事情。

enter image description here