Parsing di chiavi sintattiche

  • Creatore
    Topic
  • #45367
    robitex
    Amministratore del forum
      Up
      0
      Down
      ::


      Buongiorno.
      Ammettiamo di dover gestire la seguente sintassi con la chiave extends:
      `
      oppure:
      extends `

      Mi servirebbe un comando che elabori la stringa di testo dell’utente e mi restituisca il valore del nome nel primo caso oppure i valori dei due nomi nel secondo.
      La soluzione che ho pensato (e che chiarirà meglio il problema) è quella di utilizzare gli argomenti delimitati, ecco il codice:
      `\documentclass{minimal}

      \makeatletter
      \def\extends{extends}
      \def\pnn#1 #2 ){%
      \def\key{#1}
      \ifx\key\extends
      padre=#2.
      \else
      Error 'extends'
      \fi
      }
      %
      \def\pn(#1 #2){%
      \def\tmp{#2}
      \ifx\tmp\@empty
      nome=#1.
      \else
      nome=#1, \pnn#2)
      \fi
      }
      %
      \def\parsename#1{%
      \pn(#1 )
      }
      \makeatother

      \begin{document}

      \parsename{pippo}

      \parsename{pippo extends sempronio}
      \end{document}`

      Questo codice fa esattamente quello che desidero: ma smette di funzionare non appena l’utente prova ad inserire caratteri spazio prima od anche dopo l’argomento di\parsename

      Chiedo quindi se esiste un altro modo per implementare l’idea sintattica o se è possibile farlo aggiustando il codice che fa uso della tecnica ad argomenti delimitati.
      Grazie a tutti.
      Roberto.

    Visualizzazione 6 filoni di risposte
    • Autore
      Risposte
      • #45368
        Up
        0
        Down
        ::

        Buongiorno.
        Ammettiamo di dover gestire la seguente sintassi con la chiave extends:
        `
        oppure:
        extends `

        Mi servirebbe un comando che elabori la stringa di testo dell’utente e mi restituisca il valore del nome nel primo caso oppure i valori dei due nomi nel secondo.
        La soluzione che ho pensato (e che chiarirà meglio il problema) è quella di utilizzare gli argomenti delimitati, ecco il codice:
        `\documentclass{minimal}

        \makeatletter
        \def\extends{extends}
        \def\pnn#1 #2 ){%
        \def\key{#1}
        \ifx\key\extends
        padre=#2.
        \else
        Error 'extends'
        \fi
        }
        %
        \def\pn(#1 #2){%
        \def\tmp{#2}
        \ifx\tmp\@empty
        nome=#1.
        \else
        nome=#1, \pnn#2)
        \fi
        }
        %
        \def\parsename#1{%
        \pn(#1 )
        }
        \makeatother

        \begin{document}

        \parsename{pippo}

        \parsename{pippo extends sempronio}
        \end{document}`

        Questo codice fa esattamente quello che desidero: ma smette di funzionare non appena l’utente prova ad inserire caratteri spazio prima od anche dopo l’argomento di\parsename

        Chiedo quindi se esiste un altro modo per implementare l’idea sintattica o se è possibile farlo aggiustando il codice che fa uso della tecnica ad argomenti delimitati.
        Grazie a tutti.
        Roberto.

        Puoi ottenere di ignorare spazi iniziali con
        `\makeatletter
        \def\parsename#1{\@parsename#1\@nil}
        \def\@parsename{\futurelet\@let@token\@@parsename}
        \def\@@parsename{%
        \ifx\@let@token\@sptoken
        \expandafter\@parsename
        \else
        \expandafter\@@@parsename
        \fi}
        \def\@@@parsename#1\@nil{%
        \pn(#1 )%
        }
        \makeatother`
        Per gli spazi finali credo sia un bel problemino. Ma perché una sintassi così complicata? Non è meglio una classica “chiave=valore”?

        Ciao
        Enrico

      • #45369
        robitex
        Amministratore del forum
          Up
          0
          Down
          ::


          Sto elaborando una sintassi particolare (sempre per la classe che sto sviluppando e temo finirò tra molto tempo mancando ancora circa 300 linee di codice).
          Si tratta di instanziare in memoria un nuovo “oggetto”. Se l’utente fornisce un nome, quello sarà l’identificativo per l’oggetto e se fornisce anche l’indicazione con “extends” allora produrrà un oggetto che “eredita” da quello indicato.

          Scrivere `name=myobject, extends=baseobject`è meno elegante ed espressivo che scrivere `myobject extends baseobject` anche se appunto immediato da implementare.

          Per quanto riguarda gli spazi finali, poiché la classe carica il pacchetto etextools potrei impiegare il comando \deblank. Farò qualche esperimento.

          Grazie ed a presto.

        • #45370
          Up
          0
          Down
          ::

          Sto elaborando una sintassi particolare (sempre per la classe che sto sviluppando e temo finirò tra molto tempo mancando ancora circa 300 linee di codice).
          Si tratta di instanziare in memoria un nuovo “oggetto”. Se l’utente fornisce un nome, quello sarà l’identificativo per l’oggetto e se fornisce anche l’indicazione con “extends” allora produrrà un oggetto che “eredita” da quello indicato.

          Scrivere `name=myobject, extends=baseobject`è meno elegante ed espressivo che scrivere `myobject extends baseobject` anche se appunto immediato da implementare.

          Per quanto riguarda gli spazi finali, poiché la classe carica il pacchetto etextools potrei impiegare il comando \deblank. Farò qualche esperimento.

          Grazie ed a presto.

          Siccome hai una chiave, il trucco è di delimitare con la chiave stessa.
          `\documentclass{minimal}
          \usepackage{etextools}
          \makeatletter
          \def\parsename#1{\pn@i#1 extends \@nil}
          \def\pn@i#1 extends #2\@nil{%
          \def\temp{#2}%
          \edef\nome{\deblank{#1}}%
          nome=\nome.
          \ifx\temp\empty % non c'è “extends”
          \else
          \expandafter\pn@ii\temp
          \fi}
          \def\pn@ii#1 extends {%
          \edef\padre{\deblank{#1}}%
          padre=\padre}
          \makeatother

          \begin{document}

          `\parsename{pippo}'

          `\parsename{pippo extends sempronio}'

          `\parsename{pippo extends sss }'

          `\parsename{ pippo extends sss }'
          \end{document}`
          Naturalmente le parole chiave devono essere senza traccia di caratteri attivi, quindi solo ASCII a 7 bit.

          Ciao
          Enrico

        • #45371
          robitex
          Amministratore del forum
            Up
            0
            Down
            ::


            Splendida intuizione Enrico.
            Aggiungere la chiave extends come delimitatore è una genialità!
            8) 8) 8)
            Naturalmente il problema non è ancora del tutto risolto perché i nomi ricavati dal parsing devono poi diventare argomenti per il comando \csname e si deve fare attenzione all’espansione ed ai caratteri spazio. Forse in questo fine settimana potrò provare qualche test finale.
            Grazie.

          • #45372
            Up
            0
            Down
            ::

            Splendida intuizione Enrico.
            Aggiungere la chiave extends come delimitatore è una genialità!
            8) 8) 8)
            Naturalmente il problema non è ancora del tutto risolto perché i nomi ricavati dal parsing devono poi diventare argomenti per il comando \csname e si deve fare attenzione all’espansione ed ai caratteri spazio. Forse in questo fine settimana potrò provare qualche test finale.
            Grazie.

            Non capisco il problema: hai a disposizione i nomi nelle macro \nome e \padre, dove ci sono le stringhe date senza spazi iniziali e finali. Se hai problemi di caratteri accentati, usa
            `\csname Prefisso\detokenize{\padre}Suffisso\endcsname`
            Ciao
            Enrico

          • #45373
            robitex
            Amministratore del forum
              Up
              0
              Down
              ::

              Splendida intuizione Enrico.
              Aggiungere la chiave extends come delimitatore è una genialità!
              8) 8) 8)
              Naturalmente il problema non è ancora del tutto risolto perché i nomi ricavati dal parsing devono poi diventare argomenti per il comando \csname e si deve fare attenzione all’espansione ed ai caratteri spazio. Forse in questo fine settimana potrò provare qualche test finale.
              Grazie.

              Non capisco il problema: hai a disposizione i nomi nelle macro \nome e \padre, dove ci sono le stringhe date senza spazi iniziali e finali. Se hai problemi di caratteri accentati, usa
              `\csname Prefisso\detokenize{\padre}Suffisso\endcsname`
              Ciao
              Enrico

              Ma il comando \detokenize{\padre} non pruduce i caratteri \padre appunto detokenizzati?
              Ciao

            • #45374
              Up
              0
              Down
              ::

              [quote]Splendida intuizione Enrico.
              Aggiungere la chiave extends come delimitatore è una genialità!
              8) 8) 8)
              Naturalmente il problema non è ancora del tutto risolto perché i nomi ricavati dal parsing devono poi diventare argomenti per il comando \csname e si deve fare attenzione all’espansione ed ai caratteri spazio. Forse in questo fine settimana potrò provare qualche test finale.
              Grazie.

              Non capisco il problema: hai a disposizione i nomi nelle macro \nome e \padre, dove ci sono le stringhe date senza spazi iniziali e finali. Se hai problemi di caratteri accentati, usa
              `\csname Prefisso\detokenize{\padre}Suffisso\endcsname`
              Ciao
              Enrico

              Ma il comando \detokenize{\padre} non pruduce i caratteri \padre appunto detokenizzati?
              Ciao[/quote]
              Sì; tutti di categoria 12 tranne gli spazi che sono come sempre di categoria 10; aggiunge uno spazio dopo i nomi di comandi. Continuo a non capire il problema.

              Ciao
              Enrico

          Visualizzazione 6 filoni di risposte
          • Devi essere connesso per rispondere a questo topic.

          Go to top