mirror of
https://github.com/nim-lang/Nim.git
synced 2026-08-29 18:11:44 +00:00
Pegs AST read access (#8050)
* Make PEG AST nodes readable from outside the module. * Added a test module for the pegs stdlib module. * Edited changelog. * Renamed ``sons`` iterator to ``items``, added ``pairs``, inlined both. * Updated entry and moved it to the right category.
This commit is contained in:
78
tests/stdlib/tpegs.nim
Normal file
78
tests/stdlib/tpegs.nim
Normal file
@@ -0,0 +1,78 @@
|
||||
discard """
|
||||
output: '''
|
||||
pkNonTerminal: Sum @(2, 3)
|
||||
pkSequence: (Product (('+' / '-') Product)*)
|
||||
pkNonTerminal: Product @(3, 7)
|
||||
pkSequence: (Value (('*' / '/') Value)*)
|
||||
pkNonTerminal: Value @(4, 5)
|
||||
pkOrderedChoice: (([0-9] [0-9]*) / ('(' Expr ')'))
|
||||
pkSequence: ([0-9] [0-9]*)
|
||||
pkCharChoice: [0-9]
|
||||
pkGreedyRepSet: [0-9]*
|
||||
pkSequence: ('(' Expr ')')
|
||||
pkChar: '('
|
||||
pkNonTerminal: Expr @(1, 4)
|
||||
pkNonTerminal: Sum @(2, 3)
|
||||
pkChar: ')'
|
||||
pkGreedyRep: (('*' / '/') Value)*
|
||||
pkSequence: (('*' / '/') Value)
|
||||
pkOrderedChoice: ('*' / '/')
|
||||
pkChar: '*'
|
||||
pkChar: '/'
|
||||
pkNonTerminal: Value @(4, 5)
|
||||
pkGreedyRep: (('+' / '-') Product)*
|
||||
pkSequence: (('+' / '-') Product)
|
||||
pkOrderedChoice: ('+' / '-')
|
||||
pkChar: '+'
|
||||
pkChar: '-'
|
||||
pkNonTerminal: Product @(3, 7)
|
||||
'''
|
||||
"""
|
||||
|
||||
import strutils, streams
|
||||
import pegs
|
||||
|
||||
const
|
||||
indent = " "
|
||||
|
||||
let
|
||||
pegSrc = """
|
||||
Expr <- Sum
|
||||
Sum <- Product (('+' / '-') Product)*
|
||||
Product <- Value (('*' / '/') Value)*
|
||||
Value <- [0-9]+ / '(' Expr ')'
|
||||
"""
|
||||
pegAst: Peg = pegSrc.peg
|
||||
|
||||
var
|
||||
outp = newStringStream()
|
||||
processed: seq[string] = @[]
|
||||
|
||||
proc prt(outp: Stream, kind: PegKind, s: string; level: int = 0) =
|
||||
outp.writeLine indent.repeat(level) & "$1: $2" % [$kind, s]
|
||||
|
||||
proc recLoop(p: Peg, level: int = 0) =
|
||||
case p.kind
|
||||
of pkEmpty..pkWhitespace:
|
||||
discard
|
||||
of pkTerminal, pkTerminalIgnoreCase, pkTerminalIgnoreStyle:
|
||||
outp.prt(p.kind, $p, level)
|
||||
of pkChar, pkGreedyRepChar:
|
||||
outp.prt(p.kind, $p, level)
|
||||
of pkCharChoice, pkGreedyRepSet:
|
||||
outp.prt(p.kind, $p, level)
|
||||
of pkNonTerminal:
|
||||
outp.prt(p.kind,
|
||||
"$1 @($3, $4)" % [p.nt.name, $p.nt.rule.kind, $p.nt.line, $p.nt.col], level)
|
||||
if not(p.nt.name in processed):
|
||||
processed.add p.nt.name
|
||||
p.nt.rule.recLoop level+1
|
||||
of pkBackRef..pkBackRefIgnoreStyle:
|
||||
outp.prt(p.kind, $p, level)
|
||||
else:
|
||||
outp.prt(p.kind, $p, level)
|
||||
for s in items(p):
|
||||
s.recLoop level+1
|
||||
|
||||
pegAst.recLoop
|
||||
echo outp.data
|
||||
Reference in New Issue
Block a user