当前位置: 首页 > 知识库问答 >
问题:

分流码验证表达式

龚国源
2023-03-14

我们使用分流码算法来计算表达式。我们可以通过简单地应用算法来验证表达式。如果存在缺失操作数、缺失匹配括号和其他内容,则会失败。然而,分流场算法比人类可读的内插有更大的受支持语法。例如,

1 + 2
+ 1 2
1 2 +

所有可接受的方式都提供“12”作为调车场算法的输入。”“12”和“12”不是有效的中缀,但标准调车场算法可以处理它们。该算法实际上并不关心顺序,而是按优先顺序应用运算符,以获取“最近”的操作数。

我们希望将输入限制为有效的人类可读中缀。我正在寻找一种方法,要么修改调车场算法,使其在使用无效中缀时失败,要么在使用调车场之前提供中缀验证。

有人知道有什么公开的技术可以做到这一点吗?我们必须同时支持基本运算符、自定义运算符、方括号和函数(具有多个参数)。我在网上没有看到任何比基本操作员更有效的东西。

谢谢

共有2个答案

司浩壤
2023-03-14

对调车场算法进行了很好的讨论http://www.engr.mun.ca/~theo/Misc/exp\u解析。htm这里介绍的算法使用了操作符堆栈的关键思想,但是有一些语法来知道接下来应该期望什么。它有两个主要函数,一个是表达式,另一个是前缀运算符、变量、数字、括号和函数。前缀运算符总是比二进制运算符绑定得更紧,所以您希望先处理其中任何一个。

如果我们说P代表某个前缀序列,而B是一个二进制运算符,那么任何表达式的形式都是

P B P B P

也就是说,您要么期待前缀序列,要么期待二进制运算符。正式的语法是

E -> P (B P)*

而P将是

P -> -P | variable | constant | etc.

这将转换为psudocode作为

E() {
    P()
    while next token is a binary op:
         read next op
         push onto stack and do the shunting yard logic
         P()
    if any tokens remain report error
    pop remaining operators off the stack
}

P() {
    if next token is constant or variable:
         add to output
    else if next token is unary minus: 
         push uminus onto operator stack
         P()
}

您可以将其展开以处理其他一元运算符、函数、方括号和后缀运算符。

於功
2023-03-14

我的问题的解决方案是用Rici推荐的状态机增强维基百科上发布的算法。我在这里发布伪代码,因为它可能对其他人有用。

Support two states, ExpectOperand and ExpectOperator.

Set State to ExpectOperand
While there are tokens to read:
    If token is a constant (number)
        Error if state is not ExpectOperand.
        Push token to output queue.
        Set state to ExpectOperator.
    If token is a variable.
        Error if state is not ExpectOperand.
        Push token to output queue.
        Set state to ExpectOperator.
    If token is an argument separator (a comma).
        Error if state is not ExpectOperator.
        Until the top of the operator stack is a left parenthesis  (don't pop the left parenthesis).
            Push the top token of the stack to the output queue.
            If no left parenthesis is encountered then error.  Either the separator was misplaced or the parentheses were mismatched.
        Set state to ExpectOperand.
    If token is a unary operator.
        Error if the state is not ExpectOperand.
        Push the token to the operator stack.
        Set the state to ExpectOperand.
    If the token is a binary operator.
        Error if the state is not ExpectOperator.
        While there is an operator token at the top of the operator stack and either the current token is left-associative and of lower then or equal precedence to the operator on the stack, or the current token is right associative and of lower precedence than the operator on the stack.
            Pop the operator from the operator stack and push it onto the output queue.
        Push the current operator onto the operator stack.
        Set the state to ExpectOperand. 
    If the token is a Function.
        Error if the state is not ExpectOperand.  
        Push the token onto the operator stack.
        Set the state to ExpectOperand.
    If the token is a open parentheses.
        Error if the state is not ExpectOperand.
        Push the token onto the operator stack.
        Set the state to ExpectOperand.
    If the token is a close parentheses.
         Error if the state is not ExpectOperator.
         Until the token at the top of the operator stack is a left parenthesis.
             Pop the token off of the operator stack and push it onto the output queue.
         Pop the left parenthesis off of the operator stack and discard.
         If the token at the top of the operator stack is a function then pop it and push it onto the output queue.
         Set the state to ExpectOperator.
At this point you have processed all the input tokens.
While there are tokens on the operator stack.
    Pop the next token from the operator stack and push it onto the output queue.
    If a parenthesis is encountered then error.  There are mismatched parenthesis.

通过查看前面的标记,可以很容易地区分一元运算符和二元运算符(我专门谈论负前缀和减法运算符)。如果没有前一个标记,前一个标记是开括号,或前一个标记是运算符,则您遇到了一元前缀运算符,否则您遇到了二进制运算符。

 类似资料:
  • 本文向大家介绍最新密码验证正则表达式,包括了最新密码验证正则表达式的使用技巧和注意事项,需要的朋友参考一下 正则表达式验证密码功能在项目中经常被使用到,但是很多朋友还是不大会使用密码正则表达式进行验证,本文小编为大家整理了php密码验证正则表达式、python密码强度正则,当然还有大家常用到的js正则表达式,希望大家喜欢。 刚开始复习一下,什么是正则表达式? 在编写处理字符串的程序或网页时,经常有

  • 我需要检查密码是否至少包含: 一个号码 一个小写字符 一个大写字符 一个特殊符号(.,@etc) 我在C#中有以下内容: 但这并不有效: 我错过了什么? 更新 我正在将其与系统.组件模型.数据注释一起使用来验证模型属性:

  • 问题内容: 谁能帮助我创建用于密码验证的正则表达式。 条件为“密码必须包含8个字符和至少一个数字,一个字母和一个唯一字符,例如 问题答案:

  • 在注册会员时,经常需要输入电话号码,电话号码是指手机号码或者固定电话。如果输入的内容不合法,则会向用户输出提示。本实例模拟实现电话号码的验证功能,接收用户在控制台输入的电话号码,然后进行判断,并将结果输出。 在这里使用《 Java正则表达式》一节中讲到的正则表达式支持的字符来实现,步骤如下。 (1) 创建名为 Test21.java 的 Java 文件,在 main() 方法中开始编写代码。 (2

  • 我正在编写一个正则表达式来验证密码。条件是: > 密码必须至少包含两个特殊字符 密码必须至少有八个字符长 我可以使用以下正则表达式确保至少有8个字符、至少一个字母表、至少一个数字和至少一个特殊字符: 我无法获得的唯一条件是必须至少有两个特殊字符(上面的Reg exp是至少一个特殊字符)。有人知道这件事吗? 提前谢谢。

  • 密码指示器可指导用户开发强密码。我希望在测量仪上实现以下密码要求。我已使用RegEx在下面添加了突出显示的代码,但是代码未检测到所需的密码准则。检测以下要求的正确代码是什么? 8个字符 大小写字母 特殊字符 不得包含连续4个字母 不得包含4个连续数字 示例: Test@1=不足 2323Ejsdh!=不足 Tlv!897%=强 302^PLs#=强