LoginLogin

PXIILIB [SB4]

Root / Submissions / [.]

utrmagureCreated:
Download:4RK33W34V
Version:0.3.0Size:

PXII.LIB

A library for parsing using parser combinators, with DEFs for hierarchical objects to create parsers and receive results. ( also JSON support as an example of parser combinators! ) Japanese wiki page: http://wiki.hosiken.jp/petc4/?Toukou%2FPXLIB

Instructions:

Define a parser with PXDEFPC. Parser names start with @.
PXDEFPC @_SPACE,REGEXP("[\x20]*")
PXDEFPC @EXPR,ACTP(LISTP(@TERM,CHARP("+-")),"0:ONCALCB")
PXDEFPC @TERM,ACTP(LISTP(@FACT,CHARP("*/%")),"0:ONCALCB")
PXDEFPC @FACT,ACTP(SEQP(REGEXP("[-]*"),ORP(@REAL,SEQP("(",@EXPR,")"))),"0:ONFACT")
PXDEFPC @REAL,REGEXP("([0-9]+(\.[0-9]*)?|[0-9]*\.[0-9]+)")
The reserved name @_SPACE indicates a skip parser. Pass the source, start position, and parser to PXPARSE to parse. The results are returned as an object.
DIM RES=PXPARSE("3*(6-2)",0,@EXPR)
Use OBJGET to get the value by key.
DIM SUCCESS=OBJGET(RES,"SUCCESS")
DIM POS=OBJGET(RES,"POS")
IF SUCCESS THEN
 DIM VALUE=OBJGET(RES,"VALUE")
 ' VALUE should be 12 in this case.
 ' The key "VALUE" is generated by the custom actions, ONCALCB and ONFACT.
ENDIF

Notes:

例: į°Ąå˜ãĒ計įŽ—抟 Example: Simple calculator
OPTION STRICT
ACLS

LOAD "PXIILIB-0.3.0/PXII.LIB",1
EXEC 1

INITPC
LOOP
 LINPUT "?";EXPR
 PRINT "=";EVAL(EXPR)
ENDLOOP

DEF INITPC
 PXDEFPC @_SPACE,REGEXP("[\x20]*")
 PXDEFPC @EXPR,ACTP(LISTP(@TERM,CHARP("+-")),"0:ONCALCB")
 PXDEFPC @TERM,ACTP(LISTP(@FACT,CHARP("*/%")),"0:ONCALCB")
 PXDEFPC @FACT,ACTP(SEQP(REGEXP("[-]*"),ORP(@REAL,SEQP("(",@EXPR,")"))),"0:ONFACT")
 PXDEFPC @REAL,REGEXP("([0-9]+(\.[0-9]*)?|[0-9]*\.[0-9]+)")
END

DEF EVAL(EXPR)
 DIM RES=PXPARSE(EXPR,0,@EXPR)
 IF OBJGET(RES,"SUCCESS") THEN
  RETURN OBJGET(RES,"VALUE")
 ELSE
  RETURN POW(2,1024)*0 'nan
 ENDIF
END

DEF ONFACT RES
 DIM SIGN=1-(LEN(OBJGET(RES,"SEQ0.BUFF")) MOD 2)*2
 DIM BUFF=OBJGET(RES,"SEQ1.BUFF")
 IF LEFT$(BUFF,1)=="(" THEN
  OBJSET RES,"VALUE",SIGN*OBJGET(RES,"SEQ1.SEQ1.VALUE")
 ELSE
  OBJSET RES,"VALUE",SIGN*VAL(BUFF)
 ENDIF
END

DEF ONCALCB RES
 DIM I,O,A,B
 A=OBJGET(RES,"LISTSUB0.VALUE")
 FOR I=1 TO OBJGET(RES,"LIST#")-1
  O=OBJGET(RES,"LISTDEL"+STR$(I-1)+".BUFF")
  B=OBJGET(RES,"LISTSUB"+STR$(I)+".VALUE")
  A=CALCB(O,A,B)
 NEXT
 OBJSET RES,"VALUE",A
END

DEF CALCB(O,A,B)
 CASE O
  WHEN "+":RETURN A+B
  WHEN "-":RETURN A-B
  WHEN "*":RETURN A*B
  WHEN "/":RETURN A/B
  WHEN "%":RETURN A MOD B
 ENDCASE
END

No posts yet (will you be the first?)