- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
if 语句和 while 语句不断从 p_error(p) 抛出语法错误,并且 PLY 告诉我运行时存在冲突。这些问题来自 if-else 和 while 语句,因为在添加它们之前就很好。任何帮助将不胜感激。
如果可能,请不要对实现进行太多更改,即使这是不好的做法。我只是想要帮助理解它,我不想进行彻底的修改(那将是抄袭)。
import ply.lex as lex
import ply.yacc as yacc
# === Lexical tokens component ===
# List of possible token namesthat can be produced by the lexer
# NAME: variable name, L/RPAREN: Left/Right Parenthesis
tokens = (
'NAME', 'NUMBER',
'PLUS', 'MINUS', 'TIMES', 'DIVIDE', 'MODULO', 'EQUALS',
'LPAREN', 'RPAREN',
'IF', 'ELSE', 'WHILE',
'EQUAL', 'NOTEQ', 'LARGE', 'SMALL', 'LRGEQ', 'SMLEQ',
)
# Regular expression rules for tokens format: t_<TOKEN>
# Simple tokens: regex for literals +,-,*,/,%,=,(,) and variable names (alphanumeric)
t_PLUS = r'\+'
t_MINUS = r'-'
t_TIMES = r'\*'
t_DIVIDE = r'/'
t_MODULO = r'%'
t_EQUALS = r'='
t_LPAREN = r'\('
t_RPAREN = r'\)'
t_NAME = r'[a-zA-Z_][a-zA-Z0-9_]*'
t_IF = r'if'
t_ELSE = r'else'
t_WHILE = r'while'
t_EQUAL = r'\=\='
t_NOTEQ = r'\!\='
t_LARGE = r'\>'
t_SMALL = r'\<'
t_LRGEQ = r'\>\='
t_SMLEQ = r'\<\='
# complex tokens
# number token
def t_NUMBER(t):
r'\d+' # digit special character regex
t.value = int(t.value) # convert str -> int
return t
# Ignored characters
t_ignore = " \t" # spaces & tabs regex
# newline character
def t_newline(t):
r'\n+' # newline special character regex
t.lexer.lineno += t.value.count("\n") # increase current line number accordingly
# error handling for invalid character
def t_error(t):
print("Illegal character '%s'" % t.value[0]) # print error message with causing character
t.lexer.skip(1) # skip invalid character
# Build the lexer
lex.lex()
# === Yacc parsing/grammar component ===
# Precedence & associative rules for the arithmetic operators
# 1. Unary, right-associative minus.
# 2. Binary, left-associative multiplication, division, and modulus
# 3. Binary, left-associative addition and subtraction
# Parenthesis precedence defined through the grammar
precedence = (
('left', 'PLUS', 'MINUS'),
('left', 'TIMES', 'DIVIDE', 'MODULO'),
('right', 'UMINUS'),
)
# dictionary of names (for storing variables)
names = {}
# --- Grammar:
# <statement> -> NAME = <expression> | <expression>
# <expression> -> <expression> + <expression>
# | <expression> - <expression>
# | <expression> * <expression>
# | <expression> / <expression>
# | <expression> % <expression>
# | - <expression>
# | ( <expression> )
# | NUMBER
# | NAME
# ---
# defined below using function definitions with format string/comment
# followed by logic of changing state of engine
# if statement
def p_statement_if(p):
'''statement : IF LPAREN comparison RPAREN statement
| IF LPAREN comparison RPAREN statement ELSE statement'''
if p[3]:
p[0] = p[5]
else:
if p[7] is not None:
p[0] = p[7]
def p_statement_while(p):
'statement : WHILE LPAREN comparison RPAREN statement'
while(p[3]):
p[5];
# assignment statement: <statement> -> NAME = <expression>
def p_statement_assign(p):
'statement : NAME EQUALS expression'
names[p[1]] = p[3] # PLY engine syntax, p stores parser engine state
# expression statement: <statement> -> <expression>
def p_statement_expr(p):
'statement : expression'
print(p[1])
# comparison
def p_comparison_binop(p):
'''comparison : expression EQUAL expression
| expression NOTEQ expression
| expression LARGE expression
| expression SMALL expression
| expression LRGEQ expression
| expression SMLEQ expression'''
if p[2] == '==':
p[0] = p[1] == p[3]
elif p[2] == '!=':
p[0] = p[1] != p[3]
elif p[2] == '>':
p[0] = p[1] > p[3]
elif p[2] == '<':
p[0] = p[1] < p[3]
elif p[2] == '>=':
p[0] = p[1] >= p[3]
elif p[2] == '<=':
p[0] = p[1] <= p[3]
# binary operator expression: <expression> -> <expression> + <expression>
# | <expression> - <expression>
# | <expression> * <expression>
# | <expression> / <expression>
# | <expression> % <expression>
def p_expression_binop(p):
'''expression : expression PLUS expression
| expression MINUS expression
| expression TIMES expression
| expression DIVIDE expression
| expression MODULO expression'''
if p[2] == '+':
p[0] = p[1] + p[3]
elif p[2] == '-':
p[0] = p[1] - p[3]
elif p[2] == '*':
p[0] = p[1] * p[3]
elif p[2] == '/':
p[0] = p[1] / p[3]
elif p[2] == '%':
p[0] = p[1] % p[3]
# unary minus operator expression: <expression> -> - <expression>
def p_expression_uminus(p):
'expression : MINUS expression %prec UMINUS'
p[0] = -p[2]
# parenthesis group expression: <expression> -> ( <expression> )
def p_expression_group(p):
'expression : LPAREN expression RPAREN'
p[0] = p[2]
# number literal expression: <expression> -> NUMBER
def p_expression_number(p):
'expression : NUMBER'
p[0] = p[1]
# variable name literal expression: <expression> -> NAME
def p_expression_name(p):
'expression : NAME'
# attempt to lookup variable in current dictionary, throw error if not found
try:
p[0] = names[p[1]]
except LookupError:
print("Undefined name '%s'" % p[1])
p[0] = 0
# handle parsing errors
def p_error(p):
print("Syntax error at '%s'" % p.value)
# build parser
yacc.yacc()
# start interpreter and accept input using commandline/console
while True:
try:
s = input('calc > ') # get user input. use raw_input() on Python 2
except EOFError:
break
yacc.parse(s) # parse user input string
最佳答案
您的基本问题是您的词法分析器无法识别关键字 if
和 while
(也不是 else
),因为 t_NAME
模式将在这些情况下触发。 section 4.3 of the Ply documentation 中描述了该问题和可能的解决方案。 。问题是:
Tokens defined by strings are added next by sorting them in order of decreasing regular expression length (longer expressions are added first).
并且 t_NAME
的表达式比简单关键字模式长。
仅将 t_NAME
放入词法分析器函数中无法解决此问题,因为函数定义的标记会在字符串定义的标记之前进行检查。
但是你可以将t_NAME
做成一个函数,然后在函数中在字典中查找匹配的字符串,看看它是否是保留字。 (请参阅链接部分末尾的示例,在以“处理保留字...”开头的段落中)。当您这样做时,您根本不定义 t_IF
、t_WHILE
和 t_ELSE
。
移位-归约冲突是“悬挂的其他”问题。如果您搜索该短语,您会找到各种解决方案。
最简单的解决方案是什么都不做,忽略警告,因为 Ply 默认会做正确的事情。
第二个最简单的解决方案是将 ('if', 'IF'), ('left', 'ELSE')
添加到优先级列表,并向 添加优先级标记>如果
生产:
'''statement : IF LPAREN comparison RPAREN statement %prec IF
| IF LPAREN comparison RPAREN statement ELSE statement'''
为 ELSE
提供比 IF
更高的优先级值,可确保当解析器需要在第二个产生式中的移位 ELSE
或减少之间进行选择时对于第一个产生式,它选择移位(因为 ELSE
具有更高的优先级)。事实上,这是默认行为,因此优先级声明根本不会影响解析行为;但是,它会抑制移位减少冲突警告,因为冲突已解决。
有关其他解决方案,请参阅 this question and answer .
<小时/>最后,请查看对您问题的评论。您对 if
和 while
语句的操作根本不起作用。
关于Python PLY 中 if-else 和 while 语句的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47746590/
我需要将文本放在 中在一个 Div 中,在另一个 Div 中,在另一个 Div 中。所以这是它的样子: #document Change PIN
奇怪的事情发生了。 我有一个基本的 html 代码。 html,头部, body 。(因为我收到了一些反对票,这里是完整的代码) 这是我的CSS: html { backgroun
我正在尝试将 Assets 中的一组图像加载到 UICollectionview 中存在的 ImageView 中,但每当我运行应用程序时它都会显示错误。而且也没有显示图像。 我在ViewDidLoa
我需要根据带参数的 perl 脚本的输出更改一些环境变量。在 tcsh 中,我可以使用别名命令来评估 perl 脚本的输出。 tcsh: alias setsdk 'eval `/localhome/
我使用 Windows 身份验证创建了一个新的 Blazor(服务器端)应用程序,并使用 IIS Express 运行它。它将显示一条消息“Hello Domain\User!”来自右上方的以下 Ra
这是我的方法 void login(Event event);我想知道 Kotlin 中应该如何 最佳答案 在 Kotlin 中通配符运算符是 * 。它指示编译器它是未知的,但一旦知道,就不会有其他类
看下面的代码 for story in book if story.title.length < 140 - var story
我正在尝试用 C 语言学习字符串处理。我写了一个程序,它存储了一些音乐轨道,并帮助用户检查他/她想到的歌曲是否存在于存储的轨道中。这是通过要求用户输入一串字符来完成的。然后程序使用 strstr()
我正在学习 sscanf 并遇到如下格式字符串: sscanf("%[^:]:%[^*=]%*[*=]%n",a,b,&c); 我理解 %[^:] 部分意味着扫描直到遇到 ':' 并将其分配给 a。:
def char_check(x,y): if (str(x) in y or x.find(y) > -1) or (str(y) in x or y.find(x) > -1):
我有一种情况,我想将文本文件中的现有行包含到一个新 block 中。 line 1 line 2 line in block line 3 line 4 应该变成 line 1 line 2 line
我有一个新项目,我正在尝试设置 Django 调试工具栏。首先,我尝试了快速设置,它只涉及将 'debug_toolbar' 添加到我的已安装应用程序列表中。有了这个,当我转到我的根 URL 时,调试
在 Matlab 中,如果我有一个函数 f,例如签名是 f(a,b,c),我可以创建一个只有一个变量 b 的函数,它将使用固定的 a=a1 和 c=c1 调用 f: g = @(b) f(a1, b,
我不明白为什么 ForEach 中的元素之间有多余的垂直间距在 VStack 里面在 ScrollView 里面使用 GeometryReader 时渲染自定义水平分隔线。 Scrol
我想知道,是否有关于何时使用 session 和 cookie 的指南或最佳实践? 什么应该和什么不应该存储在其中?谢谢! 最佳答案 这些文档很好地了解了 session cookie 的安全问题以及
我在 scipy/numpy 中有一个 Nx3 矩阵,我想用它制作一个 3 维条形图,其中 X 轴和 Y 轴由矩阵的第一列和第二列的值、高度确定每个条形的 是矩阵中的第三列,条形的数量由 N 确定。
假设我用两种不同的方式初始化信号量 sem_init(&randomsem,0,1) sem_init(&randomsem,0,0) 现在, sem_wait(&randomsem) 在这两种情况下
我怀疑该值如何存储在“WORD”中,因为 PStr 包含实际输出。? 既然Pstr中存储的是小写到大写的字母,那么在printf中如何将其给出为“WORD”。有人可以吗?解释一下? #include
我有一个 3x3 数组: var my_array = [[0,1,2], [3,4,5], [6,7,8]]; 并想获得它的第一个 2
我意识到您可以使用如下方式轻松检查焦点: var hasFocus = true; $(window).blur(function(){ hasFocus = false; }); $(win
我是一名优秀的程序员,十分优秀!