Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/regex/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 使用regex Macher加速和简化多个if/else_Javascript_Regex_Parsing - Fatal编程技术网

Javascript 使用regex Macher加速和简化多个if/else

Javascript 使用regex Macher加速和简化多个if/else,javascript,regex,parsing,Javascript,Regex,Parsing,我有,在解析器中,我有一个用于解析值的函数。在S表达式中: 函数parse_argument{ var regex=arg.matchre\u re; if正则表达式{ 返回新的正则表达式[1],正则表达式[2]; }如果arg.match/^[\s\s]*$/{ 返回parse_stringarg; }否则,如果arg.matchchar\u re{ 返回parse_characterarg; }否则,如果arg.matchrational\u re{ 返回parse_rationalarg;

我有,在解析器中,我有一个用于解析值的函数。在S表达式中:

函数parse_argument{ var regex=arg.matchre\u re; if正则表达式{ 返回新的正则表达式[1],正则表达式[2]; }如果arg.match/^[\s\s]*$/{ 返回parse_stringarg; }否则,如果arg.matchchar\u re{ 返回parse_characterarg; }否则,如果arg.matchrational\u re{ 返回parse_rationalarg; }否则,如果arg.matchcomplex\u re{ 返回parse_complexarg; }否则,如果arg.matchint\u re{ 返回parse_integerarg; }否则,如果arg.matchfloat\u re{ 返回parse_floatarg; }如果arg=='nil'{ 返回零; }else如果['+nan.0','-nan.0'].includeSag{ 返回LNumberNaN; }如果['true','t','true'],则为else。包括标记{ 返回true; }如果['false','f','false'],则为else。包括标记{ 返回false; }如果参数匹配/^[iexobd]/{ 抛出新错误“无效的数值常量”; }否则{ //具有多个代码点的字符 var m=arg.match/\.+/; 如果m&&ucs2decodem[1]。长度===1{ 返回parse_characterarg; } 返回parse_symbolarg; } } 这个函数在解析时经常被调用,所以去掉if..else可能会加快代码的速度,但我不确定它是否可以简化或加快


你知道有什么方法可以让这个功能运行得更快吗?正如您所看到的,符号位于末尾,而解析符号是最常见的对象。

我通常更喜欢使用一个大正则表达式,将所有标记或符号放在一起,以便正则表达式引擎自己进行分支。这应该更快,并且有助于简化后续的parse_xxx工作,因为您已经有了所需的子匹配项。玩具示例:

让LEXEMS=String.raw` ? [0-9]+ ? \. [0-9]+ ? | ? \w+ | ? [+ * / -] | \+ | ? \s `; 让lexer=new RegExpLEXEMS.replace/\s+/g,“g” // 程序=abc+123.456-123 对于program.matchAlllexer的let m{ 设g=m群; 如果g.num console.log'num',g.num',frac=',g.frac 如果g.ident 控制台.日志'ident',g.ident //等
} 我通常更喜欢使用一个大的正则表达式,将所有的令牌一起进行OR运算,这样正则表达式引擎就可以自己进行分支。这应该更快,并且有助于简化后续的parse_xxx工作,因为您已经有了所需的子匹配项。玩具示例:

让LEXEMS=String.raw` ? [0-9]+ ? \. [0-9]+ ? | ? \w+ | ? [+ * / -] | \+ | ? \s `; 让lexer=new RegExpLEXEMS.replace/\s+/g,“g” // 程序=abc+123.456-123 对于program.matchAlllexer的let m{ 设g=m群; 如果g.num console.log'num',g.num',frac=',g.frac 如果g.ident 控制台.日志'ident',g.ident //等
} @georg的回答很好,ff OP想要的就是为各种各样的词素调出词素文本。这将所有单独的正则表达式组合到一个正则表达式中,从而有效地处理条件

但是,如果OP想要生成特殊代码来说明识别了哪个词素类型标记,请查看其识别器的nil/true/false;我怀疑是其他令牌,但OP并没有提供足够的代码,那个么OP需要的是一个传统的lexer生成器,它可以对令牌进行分类

不同之处在于@georg的union regext有一个接受状态非常复杂的regex匹配它的一个union子项和lexer生成器,每个子项有一个接受状态。具有单独的接受状态允许相应的单独操作,例如生成特定于词素的标记代码,并可选地进行值转换,例如读取浮点数文本并生成浮点数。由于这种能力,几乎每个编译器/解释器都使用lexer生成器作为标准解决方案

OP可以通过Google查找任何Javascript lexer生成器,但这里有一个: 我没有这方面的具体经验


注意:如果OP这样做,他应该将所有词素放入词法生成器,尤其是LISP,而不是仅用于值。然后,get_token例程上的每个调用都可以返回下一个标记。

@georg的回答很好,ff OP想要的就是为各种词素调出词素文本。这将所有单独的正则表达式组合到一个正则表达式中,从而有效地处理条件

但是,如果OP想要生成特殊代码来说明识别了哪个词素类型标记,请查看其识别器的nil/true/false;我怀疑是其他令牌,但OP并没有提供足够的代码,那个么OP需要的是一个传统的lexer生成器,它可以对令牌进行分类

区别在于@georg的 union regext有一个接受状态非常复杂的regex匹配它的一个union子项和lexer生成器,每个子项有一个接受状态。具有单独的接受状态允许相应的单独操作,例如生成特定于词素的标记代码,并可选地进行值转换,例如读取浮点数文本并生成浮点数。由于这种能力,几乎每个编译器/解释器都使用lexer生成器作为标准解决方案

OP可以通过Google查找任何Javascript lexer生成器,但这里有一个: 我没有这方面的具体经验


注意:如果OP这样做,他应该将所有词素放入词法生成器,尤其是LISP,而不是仅用于值。然后,get_令牌例程上的每个调用都可以返回下一个令牌。

如果您坚持这样做,您应该根据遇到的概率对序列进行排序。例如,在我的经验中,左括号和右括号、原子名和小十进制数是LISP中最常见的标记;它们应该是你清单上最早的东西。如果你想让它更快,请看我的答案。。。如果您希望您的方案在浏览器中快速运行,则可以考虑将本机代码编译方案移植到Web程序集。甚至似乎已经有了一个:@Toto我已经先添加到codereview中,但几乎没有人看过这篇文章。所以我在这里问了。如果你坚持这样做,你应该根据相遇的概率对序列进行排序。例如,在我的经验中,左括号和右括号、原子名和小十进制数是LISP中最常见的标记;它们应该是你清单上最早的东西。如果你想让它更快,请看我的答案。。。如果您希望您的方案在浏览器中快速运行,则可以考虑将本机代码编译方案移植到Web程序集。甚至似乎已经有了一个:@Toto我已经先添加到codereview中,但几乎没有人看过这篇文章。我在这里问过,如果正则表达式有效匹配,这比OP的显式更好。它会受到同样的else-if连锁效应的影响,因为它不会直接告诉你它匹配了哪个标记;您的示例对每一个都进行了测试。这是正确的,但与regexp匹配不同,这些布尔检查非常轻量级。这比OP的explicit if else更好,因为regex的匹配效率更高。它会受到同样的else-if连锁效应的影响,因为它不会直接告诉你它匹配了哪个标记;正如您的示例对每一个进行测试一样。这是事实,但与regexp匹配不同,这些布尔检查非常轻量级。我同意,一般来说,手写或生成的lexer或lexer解析器比regex+解析器更灵活、更强大。在这种特殊情况下,OP甚至可以考虑在LISP本身中实现读,从而使它成为自包含的。感谢答案,我已经在代码中使用了Listar,它是简单的状态机,但现在它只测试需要区分的特殊情况,如注释、块注释、块符号或正则表达式,我处理所有不特殊的符号,这些符号由parse_参数处理,这是Lexer的最后一步。很难将复杂的正则表达式重写为Lexer规则。这就是为什么当我用Lexer替换单个大的正则表达式标记器时,我留下了parse_参数函数。我同意,一般来说,手工编写或生成的Lexer或Lexer解析器比正则表达式+解析器更灵活、更强大。在这种特殊情况下,OP甚至可以考虑在LISP本身中实现读,从而使它成为自包含的。感谢答案,我已经在代码中使用了Listar,它是简单的状态机,但现在它只测试需要区分的特殊情况,如注释、块注释、块符号或正则表达式,我处理所有不特殊的符号,这些符号由parse_参数处理,这是Lexer的最后一步。很难将复杂的正则表达式重写为Lexer规则。这就是为什么当我用Lexer替换单个大正则表达式标记器时,我留下了parse_参数函数。