You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用sly解析以分号分隔的多条语句?

解决Sly解析分号/换行分隔多条语句的语法错误问题

这个报错的核心原因是你的解析器缺少匹配多条语句的顶层规则,而且当前的statement规则只处理了单条带分号的语句,没有考虑连续语句的情况。下面一步步帮你修正:

1. 先调整Lexer:处理空白和换行

首先确保你的词法分析器正确处理空白字符,同时可选支持换行作为分隔符:

from sly import Lexer, Parser

class MyLexer(Lexer):
    tokens = {OUTPUT, NUMBER, SEMI}
    # 忽略空格和制表符
    ignore = ' \t'
    
    # 方案1:如果只想用分号分隔,直接忽略换行
    ignore_newline = r'\n+'
    
    # 方案2:如果要支持换行作为分隔符,就把NEWLINE加入令牌(注释掉上面的ignore_newline)
    # tokens.add('NEWLINE')
    # NEWLINE = r'\n+'

    # 定义令牌
    SEMI = r';'
    OUTPUT = r'output'
    NUMBER = r'\d+'

2. 重构Parser:添加顶层语句列表规则

你需要定义一个顶层规则(比如program)来匹配一个或多个语句,同时让单条语句支持分号/换行结尾,甚至最后一条语句可以省略分隔符:

class MyParser(Parser):
    tokens = MyLexer.tokens
    # 指定入口规则(可选,默认找名为start的规则)
    start = 'program'

    # 顶层规则:整个程序就是一组语句
    @_('statement_list')
    def program(self, p):
        return p.statement_list

    # 语句列表:递归匹配多条语句
    @_('statement')
    def statement_list(self, p):
        return [p.statement]

    @_('statement_list statement')
    def statement_list(self, p):
        p.statement_list.append(p.statement)
        return p.statement_list

    # 单条语句规则:支持分号结尾、换行结尾(如果启用NEWLINE令牌)、或者无结尾(最后一条语句)
    @_('OUTPUT expr SEMI', 'OUTPUT expr')
    # 如果支持换行分隔,改成下面这行:
    # @_('OUTPUT expr SEMI', 'OUTPUT expr NEWLINE', 'OUTPUT expr')
    def statement(self, p):
        return ('output_stmt', int(p.expr))

    # 简单的表达式规则(这里只处理数字,你可以扩展)
    @_('NUMBER')
    def expr(self, p):
        return p.NUMBER

3. 测试验证

现在你可以测试解析多语句的情况了:

if __name__ == '__main__':
    lexer = MyLexer()
    parser = MyParser()

    # 测试分号分隔的语句
    test1 = parser.parse(lexer.tokenize('output 1;output 2;'))
    print(test1)  # 输出:[('output_stmt', 1), ('output_stmt', 2)]

    # 如果启用了NEWLINE令牌,测试换行分隔
    test2 = parser.parse(lexer.tokenize('output 3\noutput 4'))
    print(test2)  # 输出:[('output_stmt', 3), ('output_stmt', 4)]

    # 混合分号和换行
    test3 = parser.parse(lexer.tokenize('output 5;\noutput 6'))
    print(test3)  # 输出:[('output_stmt', 5), ('output_stmt', 6)]

为什么之前会报错?

你之前的解析器只有单条statement规则,当解析output 1;output 2;时,第一个output 1;会被匹配,但剩下的output 2;没有任何规则可以承接——因为没有定义“多条语句”的规则,所以Sly会抛出语法错误。

内容的提问来源于stack exchange,提问作者user17176247

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.04 18:30:58