Python PLY 解析器语法错误

发布于 2024-12-29 09:59:07 字数 1380 浏览 3 评论 0原文

总之,

我正在使用 python PLY 编写一个非常简单的解析器。它大部分完成了这项工作,但对于许多输入行,我从yacc收到语法错误。以下是词法分析器和解析器代码,稍作修改以方便测试:

tokens = ('VAR', 'NUMBER', 'CLOSE', 'JUNK')

# Tokens

t_VAR     = r'%[mM]\['
t_CLOSE   = r'\]'
t_JUNK    = r'.'

# Ignored characters
t_ignore = " \t\r"

def t_NUMBER(t):
    r'\d+'
    try:
        t.value = int(t.value)
    except ValueError:
        print("Integer value too large %d", t.value)
        t.value = 0
    return t

def t_newline(t):
    r'\n+'
    t.lexer.lineno += t.value.count("\n")

def t_error(t):
    print("Illegal character '%s'" % t.value[0])
    t.lexer.skip(1)

# Build the lexer
import ply.lex as lex
lex.lex()

# Parsing rules

def p_statement(p):
    '''statement : field'''
    try:
        print p[1]
    except IndexError:
        pass

def p_trash(p):
    '''statement : JUNK'''
    pass

def p_field(p):
    '''field : VAR NUMBER CLOSE'''
    #print p[1], p[2], p[3]
    p[0] = p[2]

def p_error(p):
    print("Syntax error at '%s'" % repr(p)) #p.value)

import ply.yacc as yacc
yacc.yacc()

对于示例:yacc.parse('.set %m[702] $substr($currentlength,2,$currentpg)')它给出了输出:

Syntax error at 'LexToken(JUNK,'s',1,1)'
Syntax error at 'LexToken(JUNK,'$',1,13)'

它应该只输出 702

All,

I'm writing a very simplistic parser with python PLY. It mostly does the job, but for many of the lines of input, I get a Syntax error from yacc. Here is the lexer and parser code, slightly modified for easier testing:

tokens = ('VAR', 'NUMBER', 'CLOSE', 'JUNK')

# Tokens

t_VAR     = r'%[mM]\['
t_CLOSE   = r'\]'
t_JUNK    = r'.'

# Ignored characters
t_ignore = " \t\r"

def t_NUMBER(t):
    r'\d+'
    try:
        t.value = int(t.value)
    except ValueError:
        print("Integer value too large %d", t.value)
        t.value = 0
    return t

def t_newline(t):
    r'\n+'
    t.lexer.lineno += t.value.count("\n")

def t_error(t):
    print("Illegal character '%s'" % t.value[0])
    t.lexer.skip(1)

# Build the lexer
import ply.lex as lex
lex.lex()

# Parsing rules

def p_statement(p):
    '''statement : field'''
    try:
        print p[1]
    except IndexError:
        pass

def p_trash(p):
    '''statement : JUNK'''
    pass

def p_field(p):
    '''field : VAR NUMBER CLOSE'''
    #print p[1], p[2], p[3]
    p[0] = p[2]

def p_error(p):
    print("Syntax error at '%s'" % repr(p)) #p.value)

import ply.yacc as yacc
yacc.yacc()

For a sample: yacc.parse('.set %m[702] $substr($currentlength,2,$currentpg)') which gives as output:

Syntax error at 'LexToken(JUNK,'s',1,1)'
Syntax error at 'LexToken(JUNK,'

It should output 702 only.

,1,13)'

It should output 702 only.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

单身狗的梦 2025-01-05 09:59:07

您的顶级规则需要一个声明。 p_trash 匹配第一个“.”并返回一个语句,并且没有顶级规则允许它继续。您可以执行类似的操作:

def p_junk(p):
    '''statement | JUNK statement'''

您也可以执行类似的操作(并创建语句列表):

def p_statements(p):
    '''statements | statement statements
                  | empty'''

Your top level rule requires a single statement. p_trash matches the first '.' and returns a statement and there is no top level rule to allow it to continue. You could do something like:

def p_junk(p):
    '''statement | JUNK statement'''

You could also do something like this (and create a list of statements):

def p_statements(p):
    '''statements | statement statements
                  | empty'''
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文